All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.flywaydb.maven.AbstractFlywayMojo Maven / Gradle / Ivy

There is a newer version: 10.21.0
Show newest version
/*
 * Copyright (C) Red Gate Software Ltd 2010-2024
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.flywaydb.maven;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.building.SettingsProblem;
import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
import org.apache.maven.settings.crypto.SettingsDecrypter;
import org.apache.maven.settings.crypto.SettingsDecryptionResult;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.api.Location;
import org.flywaydb.core.api.logging.Log;
import org.flywaydb.core.api.logging.LogFactory;
import org.flywaydb.core.internal.configuration.ConfigUtils;
import org.flywaydb.core.internal.logging.EvolvingLog;
import org.flywaydb.core.internal.logging.buffered.BufferedLog;
import org.flywaydb.core.internal.util.ExceptionUtils;
import org.flywaydb.core.internal.util.StringUtils;

import java.io.File;
import java.util.*;

import static org.flywaydb.core.internal.configuration.ConfigUtils.FLYWAY_PLUGINS_PREFIX;
import static org.flywaydb.core.internal.configuration.ConfigUtils.putArrayIfSet;
import static org.flywaydb.core.internal.configuration.ConfigUtils.putIfSet;

/**
 * Common base class for all mojos with all common attributes.
 */
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
abstract class AbstractFlywayMojo extends AbstractMojo {
    private static final String CONFIG_WORKING_DIRECTORY = "flyway.workingDirectory";
    private static final String CONFIG_SERVER_ID = "flyway.serverId";
    private static final String CONFIG_VERSION = "flyway.version";
    private static final String CONFIG_SKIP = "flyway.skip";
    private static final String CONFIG_CURRENT = "flyway.current";

    Log log;

    /**
     * Whether to skip the execution of the Maven Plugin for this module.
     * 

Also configurable with Maven or System Property: ${flyway.skip}

*/ @Parameter(property = CONFIG_SKIP) protected boolean skip; /** * The fully qualified classname of the JDBC driver to use to connect to the database. * By default, the driver is autodetected based on the url. *

Also configurable with Maven or System Property: ${flyway.driver}

*/ @Parameter(property = ConfigUtils.DRIVER) protected String driver; /** * The JDBC url to use to connect to the database. *

Also configurable with Maven or System Property: ${flyway.url}

*/ @Parameter(property = ConfigUtils.URL) protected String url; /** * The user to use to connect to the database. (default: blank) * The credentials can be specified by user/password or {@code serverId} from settings.xml *

Also configurable with Maven or System Property: ${flyway.user}

*/ @Parameter(property = ConfigUtils.USER) protected String user; /** * The password to use to connect to the database. (default: blank) *

Also configurable with Maven or System Property: ${flyway.password}

*/ @Parameter(property = ConfigUtils.PASSWORD) private String password; /** * The maximum number of retries when attempting to connect to the database. After each failed attempt, Flyway will * wait 1 second before attempting to connect again, up to the maximum number of times specified by connectRetries. * The interval between retries doubles with each subsequent attempt. * (default: 0) *

Also configurable with Maven or System Property: ${flyway.connectRetries}

*/ @Parameter(property = ConfigUtils.CONNECT_RETRIES) private Integer connectRetries; /** * The maximum time between retries when attempting to connect to the database in seconds. This will cap the interval * between connect retry to the value provided. * (default: 120) *

Also configurable with Maven or System Property: ${flyway.connectRetriesInterval}

*/ @Parameter(property = ConfigUtils.CONNECT_RETRIES_INTERVAL) private Integer connectRetriesInterval; /** * The SQL statements to run to initialize a new database connection immediately after opening it. (default: {@code null}) *

Also configurable with Maven or System Property: ${flyway.initSql}

*/ @Parameter(property = ConfigUtils.INIT_SQL) private String initSql; /** * The default schema managed by Flyway. This schema name is case-sensitive. If not specified, but schemas * is, Flyway uses the first schema in that list. If that is also not specified, Flyway uses the default schema for the * database connection. *

Consequences:

*
    *
  • This schema will be the one containing the schema history table.
  • *
  • This schema will be the default for the database connection (provided the database supports this concept).
  • *
*

Also configurable with Maven or System Property: ${flyway.defaultSchema}

*/ @Parameter private String defaultSchema; /** * The schemas managed by Flyway. These schema names are case-sensitive. If not specified, Flyway uses * the default schema for the database connection. If defaultSchema is not specified, then the first of * this list also acts as default schema. *

Consequences:

*
    *
  • Flyway will automatically attempt to create all these schemas, unless they already exist.
  • *
  • The schemas will be cleaned in the order of this list.
  • *
  • If Flyway created them, the schemas themselves will be dropped when cleaning.
  • *
*

Also configurable with Maven or System Property: ${flyway.schemas} (comma-separated list)

*/ @Parameter private String[] schemas; /** * The name of the schema history table that will be used by Flyway. (default: flyway_schema_history) * By default, (single-schema mode) the schema history table is placed in the default schema for the connection provided by the datasource. * When the {@code flyway.schemas} property is set (multi-schema mode), the schema history table is placed in the first schema of the list, * or in the schema specified to {@code flyway.defaultSchema}. *

Also configurable with Maven or System Property: ${flyway.table}

*/ @Parameter(property = ConfigUtils.TABLE) private String table; /** * The tablespace where to create the schema history table that will be used by Flyway. * If not specified, Flyway uses the default tablespace for the database connection. * This setting is only relevant for databases that support the notion of tablespaces. Its value is simply * ignored for all others. *

Also configurable with Maven or System Property: ${flyway.tablespace}

*/ @Parameter(property = ConfigUtils.TABLESPACE) private String tablespace; /** * The version to tag an existing schema with when executing baseline. (default: 1) *

Also configurable with Maven or System Property: ${flyway.baselineVersion}

*/ @Parameter(property = ConfigUtils.BASELINE_VERSION) private String baselineVersion; /** * The description to tag an existing schema with when executing baseline. (default: << Flyway Baseline >>) *

Also configurable with Maven or System Property: ${flyway.baselineDescription}

*/ @Parameter(property = ConfigUtils.BASELINE_DESCRIPTION) private String baselineDescription; /** * Locations to scan recursively for migrations. * The location type is determined by its prefix. * Unprefixed locations or locations starting with {@code classpath:} point to a package on the classpath and may * contain both SQL and Java-based migrations. * Locations starting with {@code filesystem:} point to a directory on the filesystem, may only * contain SQL migrations and are only scanned recursively down non-hidden directories. * (default: filesystem:src/main/resources/db/migration) *

Also configurable with Maven or System Property: ${flyway.locations} (Comma-separated list)

*/ @Parameter private String[] locations; /** * The fully qualified class names of the custom MigrationResolvers to be used in addition or as replacement * (if skipDefaultResolvers is true) to the built-in ones for resolving Migrations to apply. (default: none) *

Also configurable with Maven or System Property: ${flyway.resolvers} (Comma-separated list)

*/ @Parameter private String[] resolvers; /** * When set to true, default resolvers are skipped, i.e. only custom resolvers as defined by 'resolvers' * are used. (default: false) *

Also configurable with Maven or System Property: ${flyway.skipDefaultResolvers}

*/ @Parameter(property = ConfigUtils.SKIP_DEFAULT_RESOLVERS) private Boolean skipDefaultResolvers; /** * The encoding of SQL migrations. (default: UTF-8) *

Also configurable with Maven or System Property: ${flyway.encoding}

*/ @Parameter(property = ConfigUtils.ENCODING) private String encoding; /** * Whether Flyway should try to automatically detect SQL migration file encoding * Flyway Teams only *

Also configurable with Maven or System Property: ${flyway.detectEncoding}

*/ @Parameter private Boolean detectEncoding; /** * The maximum number of retries when trying to obtain a lock. (default: 50) *

Also configurable with Maven or System Property: ${flyway.lockRetryCount}

*/ @Parameter(property = ConfigUtils.LOCK_RETRY_COUNT) private Integer lockRetryCount; /** * The file name prefix for versioned SQL migrations (default: V) *

Versioned SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix, * which using the defaults translates to V1_1__My_description.sql

*

Also configurable with Maven or System Property: ${flyway.sqlMigrationPrefix}

*/ @Parameter(property = ConfigUtils.SQL_MIGRATION_PREFIX) private String sqlMigrationPrefix; /** * The file name prefix for undo SQL migrations. (default: U) * Undo SQL migrations are responsible for undoing the effects of the versioned migration with the same version. *

They have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix, * which using the defaults translates to U1.1__My_description.sql

* Flyway Teams only *

Also configurable with Maven or System Property: ${flyway.undoSqlMigrationPrefix}

*/ @Parameter(property = ConfigUtils.UNDO_SQL_MIGRATION_PREFIX) private String undoSqlMigrationPrefix; /** * The file name prefix for repeatable SQL migrations (default: R) *

Repeatable SQL migrations have the following file name structure: prefixSeparatorDESCRIPTIONsuffix, * which using the defaults translates to R__My_description.sql

*

Also configurable with Maven or System Property:${flyway.repeatableSqlMigrationPrefix}

*/ @Parameter(property = ConfigUtils.REPEATABLE_SQL_MIGRATION_PREFIX) private String repeatableSqlMigrationPrefix; /** * The file name separator for SQL migrations (default: __) *

SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix, * which using the defaults translates to V1_1__My_description.sql

*

Also configurable with Maven or System Property: ${flyway.sqlMigrationSeparator}

*/ @Parameter(property = ConfigUtils.SQL_MIGRATION_SEPARATOR) private String sqlMigrationSeparator; /** * The file name suffixes for SQL migrations. (default: .sql) *

SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix, * which using the defaults translates to V1_1__My_description.sql

*

Multiple suffixes (like .sql,.pkg,.pkb) can be specified for easier compatibility with other tools such as * editors with specific file associations.

*

Also configurable with Maven or System Property: ${flyway.sqlMigrationSuffixes}

*/ @Parameter private String[] sqlMigrationSuffixes; /** * Whether to automatically call clean or not when a validation error occurs. (default: {@code false}) *

This is exclusively intended as a convenience for development. even though we strongly recommend not to * change migration scripts once they have been checked into SCM and run, this provides a way of dealing with this * case in a smooth manner. The database will be wiped clean automatically, ensuring that the next migration will * bring you back to the state checked into SCM.

*

Warning! Do not enable in production!

*

Also configurable with Maven or System Property: ${flyway.cleanOnValidationError}

*/ @Parameter(property = ConfigUtils.CLEAN_ON_VALIDATION_ERROR) private Boolean cleanOnValidationError; /** * Whether to disable clean. (default: {@code false}) * This is especially useful for production environments where running clean can be a career limiting move. *

Also configurable with Maven or System Property: ${flyway.cleanDisabled}

*/ @Parameter(property = ConfigUtils.CLEAN_DISABLED) private Boolean cleanDisabled; /** * The target version up to which Flyway should consider migrations. * Migrations with a higher version number will be ignored. * Special values: *
    *
  • {@code current}: Designates the current version of the schema
  • *
  • {@code latest}: The latest version of the schema, as defined by the migration with the highest version
  • *
  • {@code next}: The next version of the schema, as defined by the first pending migration
  • *
  • * <version>? (end with a '?'): Instructs Flyway not to fail if the target version doesn't exist. * In this case, Flyway will go up to but not beyond the specified target * (default: fail if the target version doesn't exist) Flyway Teams only *
  • *
* Defaults to {@code latest}. *

Also configurable with Maven or System Property: ${flyway.target}

*/ @Parameter(property = ConfigUtils.TARGET) private String target; /** * Gets the migrations that Flyway should consider when migrating or undoing. Leave empty to consider all available migrations. * Migrations not in this list will be ignored. * Values should be the version for versioned migrations (e.g. 1, 2.4, 6.5.3) or the description for repeatable migrations (e.g. Insert_Data, Create_Table) * Flyway Teams only */ @Parameter private String[] cherryPick; /** * The loggers Flyway should use. Valid options are: * *
    *
  • auto: Auto detect the logger (default behavior)
  • *
  • console: Use stdout/stderr (only available when using the CLI)
  • *
  • slf4j: Use the slf4j logger
  • *
  • log4j2: Use the log4j2 logger
  • *
  • apache-commons: Use the Apache Commons logger
  • *
* * Alternatively you can provide the fully qualified class name for any other logger to use that. */ @Parameter private String[] loggers; /** * Allows migrations to be run "out of order" (default: {@code false}). *

If you already have versions 1 and 3 applied, and now a version 2 is found, * it will be applied too instead of being ignored.

*

Also configurable with Maven or System Property: ${flyway.outOfOrder}

*/ @Parameter(property = ConfigUtils.OUT_OF_ORDER) private Boolean outOfOrder; /** * Whether Flyway should skip actually executing the contents of the migrations and only update the schema history table. * This should be used when you have applied a migration manually (via executing the sql yourself, or via an IDE), and * just want the schema history table to reflect this. * Use in conjunction with {@code cherryPick} to skip specific migrations instead of all pending ones. * Flyway Teams only */ @Parameter(property = ConfigUtils.SKIP_EXECUTING_MIGRATIONS) private Boolean skipExecutingMigrations; /** * Whether Flyway should output a table with the results of queries when executing migrations (default: true). * Flyway Teams only *

Also configurable with Maven or System Property: ${flyway.outputQueryResults}

*/ @Parameter(property = ConfigUtils.OUTPUT_QUERY_RESULTS) private Boolean outputQueryResults; /** * Ignore migrations that match this comma-separated list of patterns when validating migrations. * Each pattern is of the form : * See https://documentation.red-gate.com/fd/ignore-migration-patterns-184127507.html for full details * Example: repeatable:missing,versioned:pending,*:failed * (default: *:future) * Flyway Teams only */ @Parameter private String[] ignoreMigrationPatterns; /** * Whether to validate migrations and callbacks whose scripts do not obey the correct naming convention. A failure * can be useful to check that errors such as case sensitivity in migration prefixes have been corrected. *

Also configurable with Maven or System Property: ${flyway.validateMigrationNaming}

*/ @Parameter(property = ConfigUtils.VALIDATE_MIGRATION_NAMING) private Boolean validateMigrationNaming; /** * Whether placeholders should be replaced. (default: true) *

Also configurable with Maven or System Property: ${flyway.placeholderReplacement}

*/ @Parameter(property = ConfigUtils.PLACEHOLDER_REPLACEMENT) private Boolean placeholderReplacement; /** * A map of <placeholder, replacementValue> to apply to SQL migration scripts. *

Also configurable with Maven or System Properties like ${flyway.placeholders.myplaceholder} or ${flyway.placeholders.otherone}

*/ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") @Parameter private Map placeholders; /** * A map of <propertyName, propertyValue> to pass to the JDBC driver object *

Also configurable with Maven or System Properties like ${flyway.jdbcProperties.myProperty} or ${flyway.jdbcProperties.otherProperty}

*/ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") @Parameter private Map jdbcProperties; /** * The prefix of every placeholder. (default: ${ ) *

Also configurable with Maven or System Property: ${flyway.placeholderPrefix}

*/ @Parameter(property = ConfigUtils.PLACEHOLDER_PREFIX) private String placeholderPrefix; /** * The suffix of every placeholder. (default: } ) *

Also configurable with Maven or System Property: ${flyway.placeholderSuffix}

*/ @Parameter(property = ConfigUtils.PLACEHOLDER_SUFFIX) private String placeholderSuffix; /** * The separator of default placeholders. (default: : ) *

Also configurable with Maven or System Property: ${flyway.placeholderSeparator}

*/ @Parameter(property = ConfigUtils.PLACEHOLDER_SEPARATOR) private String placeholderSeparator; /** * The prefix of every script placeholder. (default: FP__ ) */ @Parameter(property = ConfigUtils.SCRIPT_PLACEHOLDER_PREFIX) private String scriptPlaceholderPrefix; /** * The suffix of every script placeholder. (default: __ ) */ @Parameter(property = ConfigUtils.SCRIPT_PLACEHOLDER_SUFFIX) private String scriptPlaceholderSuffix; /** * An array of FlywayCallback implementations. (default: empty ) *

Also configurable with Maven or System Property: ${flyway.callbacks}

*/ @Parameter private String[] callbacks; /** * When set to true, default callbacks are skipped, i.e. only custom callbacks as defined by 'resolvers' * are used. (default: false) *

Also configurable with Maven or System Property: ${flyway.skipDefaultCallbacks}

*/ @Parameter(property = ConfigUtils.SKIP_DEFAULT_CALLBACKS) private Boolean skipDefaultCallbacks; /** * Whether to automatically call baseline when migrate is executed against a non-empty schema with no schema history table. * This schema will then be baselined with the {@code initialVersion} before executing the migrations. * Only migrations above {@code initialVersion} will then be applied. * This is useful for initial Flyway production deployments on projects with an existing DB. * Be careful when enabling this as it removes the safety net that ensures Flyway does not migrate the wrong * database in case of a configuration mistake! (default: {@code false}) *

Also configurable with Maven or System Property: ${flyway.baselineOnMigrate}

*/ @Parameter(property = ConfigUtils.BASELINE_ON_MIGRATE) private Boolean baselineOnMigrate; /** * Whether to automatically call validate or not when running migrate. (default: {@code true}) *

Also configurable with Maven or System Property: ${flyway.validateOnMigrate}

*/ @Parameter(property = ConfigUtils.VALIDATE_ON_MIGRATE) private Boolean validateOnMigrate; /** * Whether to allow mixing transactional and non-transactional statements within the same migration. Enabling this * automatically causes the entire affected migration to be run without a transaction. * * Note that this is only applicable for PostgreSQL, Aurora PostgreSQL, SQL Server and SQLite which all have * statements that do not run at all within a transaction. * * This is not to be confused with implicit transaction, as they occur in MySQL or Oracle, where even though a * DDL statement was run within a transaction, the database will issue an implicit commit before and after * its execution. * {@code true} if mixed migrations should be allowed. {@code false} if an error should be thrown instead. (default: {@code false}) *

Also configurable with Maven or System Property: ${flyway.mixed}

*/ @Parameter(property = ConfigUtils.MIXED) private Boolean mixed; /** * Whether to group all pending migrations together in the same transaction when applying them (only recommended for databases with support for DDL transactions). * {@code true} if migrations should be grouped. {@code false} if they should be applied individually instead. (default: {@code false}) *

Also configurable with Maven or System Property: ${flyway.group}

*/ @Parameter(property = ConfigUtils.GROUP) private Boolean group; /** * The username that will be recorded in the schema history table as having applied the migration. * {@code null} for the current database user of the connection. (default: {@code null}). *

Also configurable with Maven or System Property: ${flyway.installedBy}

*/ @Parameter(property = ConfigUtils.INSTALLED_BY) private String installedBy; /** * Rules for the built-in error handler that let you override specific SQL states and errors codes in order to force * specific errors or warnings to be treated as debug messages, info messages, warnings or errors. *

Each error override has the following format: {@code STATE:12345:W}. * It is a 5 character SQL state (or * to match all SQL states), a colon, * the SQL error code (or * to match all SQL error codes), a colon and finally * the desired behavior that should override the initial one.

*

The following behaviors are accepted:

*
    *
  • {@code D} to force a debug message
  • *
  • {@code D-} to force a debug message, but do not show the original sql state and error code
  • *
  • {@code I} to force an info message
  • *
  • {@code I-} to force an info message, but do not show the original sql state and error code
  • *
  • {@code W} to force a warning
  • *
  • {@code W-} to force a warning, but do not show the original sql state and error code
  • *
  • {@code E} to force an error
  • *
  • {@code E-} to force an error, but do not show the original sql state and error code
  • *
*

Example 1: to force Oracle stored procedure compilation issues to produce * errors instead of warnings, the following errorOverride can be used: {@code 99999:17110:E}

*

Example 2: to force SQL Server PRINT messages to be displayed as info messages (without SQL state and error * code details) instead of warnings, the following errorOverride can be used: {@code S0001:0:I-}

*

Example 3: to force all errors with SQL error code 123 to be treated as warnings instead, * the following errorOverride can be used: {@code *:123:W} * * Flyway Teams only *

Also configurable with Maven or System Property: ${flyway.errorOverrides}

*/ @Parameter private String[] errorOverrides; /** * The file where to output the SQL statements of a migration dry run. If the file specified is in a non-existent * directory, Flyway will create all directories and parent directories as needed. * Paths starting with s3: point to a bucket in AWS S3, which must exist. They are in the format s3:(/optionalfolder/subfolder)/filename.sql * Paths starting with gcs: point to a bucket in Google Cloud Storage, which must exist. They are in the format gcs:(/optionalfolder/subfolder)/filename.sql * {@code null} to execute the SQL statements directly against the database. (default: {@code null}) * * Flyway Teams only *

Also configurable with Maven or System Property: ${flyway.dryRunOutput}

*/ @Parameter(property = ConfigUtils.DRYRUN_OUTPUT) private String dryRunOutput; /** * Whether to stream SQL migrations when executing them. Streaming doesn't load the entire migration in memory at * once. Instead each statement is loaded individually. This is particularly useful for very large SQL migrations * composed of multiple MB or even GB of reference data, as this dramatically reduces Flyway's memory consumption. * (default: {@code false} * * Flyway Teams only *

Also configurable with Maven or System Property: ${flyway.stream}

*/ @Parameter(property = ConfigUtils.STREAM) private Boolean stream; /** * Whether to batch SQL statements when executing them. Batching can save up to 99 percent of network roundtrips by * sending up to 100 statements at once over the network to the database, instead of sending each statement * individually. This is particularly useful for very large SQL migrations composed of multiple MB or even GB of * reference data, as this can dramatically reduce the network overhead. This is supported for INSERT, UPDATE, * DELETE, MERGE and UPSERT statements. All other statements are automatically executed without batching. * (default: {@code false}) * * Flyway Teams only *

Also configurable with Maven or System Property: ${flyway.batch}

*/ @Parameter(property = ConfigUtils.BATCH) private Boolean batch; /** * When connecting to a Kerberos service to authenticate, the path to the Kerberos config file. * Flyway Teams only */ @Parameter(property = ConfigUtils.KERBEROS_CONFIG_FILE) private String kerberosConfigFile; /** * The encoding of the external config files specified with the {@code flyway.configFiles} property. (default: UTF-8). *

Also configurable with Maven or System Property: ${flyway.configFileEncoding}

*/ @Parameter(property = ConfigUtils.CONFIG_FILE_ENCODING) private String configFileEncoding; /** * Config files from which to load the Flyway configuration. The names of the individual properties match the ones * you would use as Maven or System properties. The encoding of the files is defined by the * flyway.configFileEncoding property, which is UTF-8 by default. Relative paths are relative to the POM or * workingDirectory if set. *

Also configurable with Maven or System Property: ${flyway.configFiles}

*/ @Parameter(property = ConfigUtils.CONFIG_FILES) private String[] configFiles; /** * Whether Flyway should attempt to create the schemas specified in the schemas property. *

Also configurable with Maven or System Property: ${flyway.createSchemas}

*/ @Parameter(property = ConfigUtils.CREATE_SCHEMAS) private Boolean createSchemas; /** * The working directory to consider when dealing with relative paths for both config files and locations. * (default: basedir, the directory where the POM resides) *

Also configurable with Maven or System Property: ${flyway.workingDirectory}

*/ @Parameter(property = CONFIG_WORKING_DIRECTORY) private String workingDirectory; /** * Whether to fail if a location specified in the flyway.locations option doesn't exist * * @return @{code true} to fail (default: {@code false}) */ @Parameter(property = ConfigUtils.FAIL_ON_MISSING_LOCATIONS) public Boolean failOnMissingLocations; /** * The id of the server tag in settings.xml (default: flyway-db) * The credentials can be specified by user/password or {@code serverId} from settings.xml *

Also configurable with Maven or System Property: ${flyway.serverId}

*/ @Parameter(property = CONFIG_SERVER_ID) private String serverId = "flyway-db"; /** * The link to the settings.xml */ @Parameter(defaultValue = "${settings}", readonly = true) protected Settings settings; /** * The configuration for plugins * You will need to configure this with the key and value specific to your plugin */ @Parameter private Map pluginConfiguration; /** * Reference to the current project that includes the Flyway Maven plugin. */ @Parameter(defaultValue = "${project}", readonly = true, required = true) protected MavenProject mavenProject; @Component private SettingsDecrypter settingsDecrypter; /** * Load username and password from settings. * * @throws FlywayException when the credentials could not be loaded. */ private void loadCredentialsFromSettings() throws FlywayException { final Server server = settings.getServer(serverId); if (user == null) { if (server != null) { user = server.getUsername(); SettingsDecryptionResult result = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(server)); for (SettingsProblem problem : result.getProblems()) { if (problem.getSeverity() == SettingsProblem.Severity.ERROR || problem.getSeverity() == SettingsProblem.Severity.FATAL) { throw new FlywayException("Unable to decrypt password: " + problem, problem.getException()); } } password = result.getServer().getPassword(); } } else if (server != null) { throw new FlywayException("You specified credentials both in the Flyway config and settings.xml. Use either one or the other"); } } /** * Retrieves the value of this boolean property, based on the matching System property on the Maven property. * * @param systemPropertyName The name of the System property. * @param mavenPropertyValue The value of the Maven property. */ protected boolean getBooleanProperty(String systemPropertyName, boolean mavenPropertyValue) { String systemPropertyValue = System.getProperty(systemPropertyName); if (systemPropertyValue != null) { return Boolean.parseBoolean(systemPropertyValue); } return mavenPropertyValue; } public final void execute() throws MojoExecutionException { LogFactory.setFallbackLogCreator(new MavenLogCreator(this)); log = LogFactory.getLog(getClass()); try { if (getBooleanProperty(CONFIG_SKIP, skip)) { log.info("Skipping Flyway execution"); return; } Set classpathElements = new HashSet<>(); classpathElements.addAll(mavenProject.getCompileClasspathElements()); classpathElements.addAll(mavenProject.getRuntimeClasspathElements()); ClassRealm classLoader = (ClassRealm) Thread.currentThread().getContextClassLoader(); for (String classpathElement : classpathElements) { classLoader.addURL(new File(classpathElement).toURI().toURL()); } File workDir = StringUtils.hasText(workingDirectory) ? toFile(mavenProject.getBasedir(), workingDirectory) : mavenProject.getBasedir(); if (locations != null) { for (int i = 0; i < locations.length; i++) { if (locations[i].startsWith(Location.FILESYSTEM_PREFIX)) { String newLocation = locations[i].substring(Location.FILESYSTEM_PREFIX.length()); File file = toFile(workDir, newLocation); locations[i] = Location.FILESYSTEM_PREFIX + file.getAbsolutePath(); } } } else { locations = new String[] { Location.FILESYSTEM_PREFIX + workDir.getAbsolutePath() + "/src/main/resources/db/migration" }; } Map envVars = ConfigUtils.environmentVariablesToPropertyMap(); Map conf = new HashMap<>(loadConfigurationFromDefaultConfigFiles(envVars)); loadCredentialsFromSettings(); putIfSet(conf, ConfigUtils.DRIVER, driver); putIfSet(conf, ConfigUtils.URL, url); putIfSet(conf, ConfigUtils.USER, user); putIfSet(conf, ConfigUtils.PASSWORD, password); putIfSet(conf, ConfigUtils.CONNECT_RETRIES, connectRetries); putIfSet(conf, ConfigUtils.CONNECT_RETRIES_INTERVAL, connectRetriesInterval); putIfSet(conf, ConfigUtils.INIT_SQL, initSql); putIfSet(conf, ConfigUtils.DEFAULT_SCHEMA, defaultSchema); putArrayIfSet(conf, ConfigUtils.SCHEMAS, schemas); putIfSet(conf, ConfigUtils.TABLE, table); putIfSet(conf, ConfigUtils.TABLESPACE, tablespace); putIfSet(conf, ConfigUtils.BASELINE_VERSION, baselineVersion); putIfSet(conf, ConfigUtils.BASELINE_DESCRIPTION, baselineDescription); putArrayIfSet(conf, ConfigUtils.LOCATIONS, locations); putArrayIfSet(conf, ConfigUtils.RESOLVERS, resolvers); putIfSet(conf, ConfigUtils.SKIP_DEFAULT_RESOLVERS, skipDefaultResolvers); putArrayIfSet(conf, ConfigUtils.CALLBACKS, callbacks); putIfSet(conf, ConfigUtils.SKIP_DEFAULT_CALLBACKS, skipDefaultCallbacks); putIfSet(conf, ConfigUtils.ENCODING, encoding); putIfSet(conf, ConfigUtils.DETECT_ENCODING, detectEncoding); putIfSet(conf, ConfigUtils.LOCK_RETRY_COUNT, lockRetryCount); putIfSet(conf, ConfigUtils.SQL_MIGRATION_PREFIX, sqlMigrationPrefix); putIfSet(conf, ConfigUtils.UNDO_SQL_MIGRATION_PREFIX, undoSqlMigrationPrefix); putIfSet(conf, ConfigUtils.REPEATABLE_SQL_MIGRATION_PREFIX, repeatableSqlMigrationPrefix); putIfSet(conf, ConfigUtils.SQL_MIGRATION_SEPARATOR, sqlMigrationSeparator); putArrayIfSet(conf, ConfigUtils.SQL_MIGRATION_SUFFIXES, sqlMigrationSuffixes); putIfSet(conf, ConfigUtils.MIXED, mixed); putIfSet(conf, ConfigUtils.GROUP, group); putIfSet(conf, ConfigUtils.INSTALLED_BY, installedBy); putIfSet(conf, ConfigUtils.CLEAN_ON_VALIDATION_ERROR, cleanOnValidationError); putIfSet(conf, ConfigUtils.CLEAN_DISABLED, cleanDisabled); putIfSet(conf, ConfigUtils.OUT_OF_ORDER, outOfOrder); putIfSet(conf, ConfigUtils.SKIP_EXECUTING_MIGRATIONS, skipExecutingMigrations); putIfSet(conf, ConfigUtils.OUTPUT_QUERY_RESULTS, outputQueryResults); putIfSet(conf, ConfigUtils.TARGET, target); putArrayIfSet(conf, ConfigUtils.LOGGERS, loggers); putArrayIfSet(conf, ConfigUtils.IGNORE_MIGRATION_PATTERNS, ignoreMigrationPatterns); putIfSet(conf, ConfigUtils.VALIDATE_MIGRATION_NAMING, validateMigrationNaming); putIfSet(conf, ConfigUtils.PLACEHOLDER_REPLACEMENT, placeholderReplacement); putIfSet(conf, ConfigUtils.PLACEHOLDER_PREFIX, placeholderPrefix); putIfSet(conf, ConfigUtils.PLACEHOLDER_SUFFIX, placeholderSuffix); putIfSet(conf, ConfigUtils.PLACEHOLDER_SEPARATOR, placeholderSeparator); putIfSet(conf, ConfigUtils.SCRIPT_PLACEHOLDER_PREFIX, scriptPlaceholderPrefix); putIfSet(conf, ConfigUtils.SCRIPT_PLACEHOLDER_SUFFIX, scriptPlaceholderSuffix); putIfSet(conf, ConfigUtils.BASELINE_ON_MIGRATE, baselineOnMigrate); putIfSet(conf, ConfigUtils.VALIDATE_ON_MIGRATE, validateOnMigrate); putIfSet(conf, ConfigUtils.DRIVER, driver); putIfSet(conf, ConfigUtils.CREATE_SCHEMAS, createSchemas); putIfSet(conf, ConfigUtils.FAIL_ON_MISSING_LOCATIONS, failOnMissingLocations); putArrayIfSet(conf, ConfigUtils.ERROR_OVERRIDES, errorOverrides); putIfSet(conf, ConfigUtils.DRYRUN_OUTPUT, dryRunOutput); putIfSet(conf, ConfigUtils.STREAM, stream); putIfSet(conf, ConfigUtils.BATCH, batch); putIfSet(conf, ConfigUtils.KERBEROS_CONFIG_FILE, kerberosConfigFile); if (placeholders != null) { for (String placeholder : placeholders.keySet()) { String value = placeholders.get(placeholder); conf.put(ConfigUtils.PLACEHOLDERS_PROPERTY_PREFIX + placeholder, value == null ? "" : value); } } if (jdbcProperties != null) { for (String property : jdbcProperties.keySet()) { String value = jdbcProperties.get(property); conf.put(ConfigUtils.JDBC_PROPERTIES_PREFIX + property, value == null ? "" : value); } } conf.putAll(getPluginConfiguration(pluginConfiguration)); conf.putAll(ConfigUtils.propertiesToMap(mavenProject.getProperties())); conf.putAll(loadConfigurationFromConfigFiles(workDir, envVars)); conf.putAll(envVars); conf.putAll(ConfigUtils.propertiesToMap(System.getProperties())); removeMavenPluginSpecificPropertiesToAvoidWarnings(conf); if (conf.getOrDefault(ConfigUtils.LOGGERS, "auto").equalsIgnoreCase("auto")) { conf.put(ConfigUtils.LOGGERS, "maven"); } Flyway flyway = Flyway.configure(classLoader).configuration(conf).load(); doExecute(flyway); } catch (Exception e) { throw new MojoExecutionException(e.toString(), ExceptionUtils.getRootCause(e)); } finally { Log currentLog = ((EvolvingLog) log).getLog(); if (currentLog instanceof BufferedLog) { ((BufferedLog) currentLog).flush(new MavenLog(this.getLog())); } } } public Map getPluginConfiguration(Map pluginConfiguration) { Map conf = new HashMap<>(); if (pluginConfiguration == null) { return conf; } String camelCaseRegex = "(? determineConfigFiles(File workDir, Map envVars) { List configFiles = new ArrayList<>(); if (envVars.containsKey(ConfigUtils.CONFIG_FILES)) { for (String file : StringUtils.tokenizeToStringArray(envVars.get(ConfigUtils.CONFIG_FILES), ",")) { configFiles.add(toFile(workDir, file)); } return configFiles; } if (System.getProperties().containsKey(ConfigUtils.CONFIG_FILES)) { for (String file : StringUtils.tokenizeToStringArray(System.getProperties().getProperty(ConfigUtils.CONFIG_FILES), ",")) { configFiles.add(toFile(workDir, file)); } return configFiles; } if (mavenProject.getProperties().containsKey(ConfigUtils.CONFIG_FILES)) { for (String file : StringUtils.tokenizeToStringArray(mavenProject.getProperties().getProperty(ConfigUtils.CONFIG_FILES), ",")) { configFiles.add(toFile(workDir, file)); } } else if (this.configFiles != null) { for (String configFile : this.configFiles) { configFiles.add(toFile(workDir, configFile)); } } return configFiles; } /** * Converts this file name into a file, adjusting relative paths if necessary to make them relative to the pom. * * @param workDir The working directory to use. * @param fileName The name of the file, relative or absolute. * @return The resulting file. */ private File toFile(File workDir, String fileName) { File file = new File(fileName); if (file.isAbsolute()) { return file; } return new File(workDir, fileName); } /** * Determines the encoding to use for loading the configuration files. * * @param envVars The environment variables converted to Flyway properties. * @return The encoding. (default: UTF-8) */ private String determineConfigurationFileEncoding(Map envVars) { if (envVars.containsKey(ConfigUtils.CONFIG_FILE_ENCODING)) { return envVars.get(ConfigUtils.CONFIG_FILE_ENCODING); } if (System.getProperties().containsKey(ConfigUtils.CONFIG_FILE_ENCODING)) { return System.getProperties().getProperty(ConfigUtils.CONFIG_FILE_ENCODING); } if (configFileEncoding != null) { return configFileEncoding; } return "UTF-8"; } /** * Filters these properties to remove the Flyway Maven Plugin-specific ones to avoid warnings. * * @param conf The properties to filter. */ private static void removeMavenPluginSpecificPropertiesToAvoidWarnings(Map conf) { conf.remove(ConfigUtils.CONFIG_FILES); conf.remove(ConfigUtils.CONFIG_FILE_ENCODING); conf.remove(CONFIG_CURRENT); conf.remove(CONFIG_SKIP); conf.remove(CONFIG_VERSION); conf.remove(CONFIG_SERVER_ID); conf.remove(CONFIG_WORKING_DIRECTORY); } /** * Load properties from the config files (if specified). * * @param workDir The working directory to use. * @param envVars The environment variables converted to Flyway properties. * @return The properties. */ private Map loadConfigurationFromConfigFiles(File workDir, Map envVars) { String encoding = determineConfigurationFileEncoding(envVars); Map conf = new HashMap<>(); for (File configFile : determineConfigFiles(workDir, envVars)) { conf.putAll(ConfigUtils.loadConfigurationFile(configFile, encoding, true)); } return conf; } /** * Load properties from the default config files (if available). * * @param envVars The environment variables converted to Flyway properties. * @return The properties. */ private Map loadConfigurationFromDefaultConfigFiles(Map envVars) { String encoding = determineConfigurationFileEncoding(envVars); Map configMap = new HashMap<>(); configMap.putAll(ConfigUtils.loadConfigurationFile(new File(System.getProperty("user.home") + "/" + ConfigUtils.CONFIG_FILE_NAME), encoding, false)); configMap.putAll(ConfigUtils.loadConfigurationFile(new File(ConfigUtils.CONFIG_FILE_NAME), encoding, false)); return configMap; } /** * Retrieves this property from either the system or the maven properties. * * @param name The name of the property to retrieve. * @return The property value. {@code null} if not found. */ protected String getProperty(String name) { String systemProperty = System.getProperty(name); if (systemProperty != null) { return systemProperty; } return mavenProject.getProperties().getProperty(name); } /** * Executes this mojo. * * @param flyway The flyway instance to operate on. * @throws Exception Any exception. */ protected abstract void doExecute(Flyway flyway) throws Exception; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy