Search code examples
mavenliquibase

Liquibase - how to customize an expressionVars property for an execution


I have a pom.xml with a liquibase plugin v. 4.7.1 with two expressionVars, prop1 and prop2 that should replace the placeholders in a changelog (that is included in another changelog, if this matters). I have several executions defined to create different sql script files. All works fine if I only define the expressionVars globally for the plugin and set the property values there. However, I need to have a different value for prop1 in one of the executions while the others use the global value. So I have an expressionVars with only that property value for prop1 and I expect prop2 would keep the globally defined value. What happens instead for this execution is I get the new value of prop1 in the output sql file but the prop2 placeholder is not replaced anymore.

The pom:

<plugin>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-maven-plugin</artifactId>
    <version>4.7.1</version>
    <configuration>
        <outputFileEncoding>UTF-8</outputFileEncoding>
        <expressionVars>
            <property>
                <name>prop1</name>
                <value>some-common-value-1</value>
            </property>
            <property>
                <name>prop2</name>
                <value>some-common-value-2</value>
            </property>
        </expressionVars>
    </configuration>
    <executions>
        ...
        <execution>
            <id>one</id>
            <phase>generate-resources</phase>
            <goals>
                <goal>updateSQL</goal>
            </goals>
            <configuration>
                <changeLogFile>some-changelog.xml</changeLogFile>
                <url>...</url>
                <migrationSqlOutputFile>file.sql</migrationSqlOutputFile>
                <expressionVars>
                    <property>
                        <name>prop1</name>
                        <value>some-specific-value-1</value>
                    </property>
                </expressionVars>
            </configuration>
        </execution>
        ....

Expected prop1 to be replaced by some-specific-value-1 and prop2 to be replaced by some-common-value-2. But the ${prop2} placeholder is not being replaced.

I executed mvn help:effective-pom and the output pom contains:

<configuration>
                <changeLogFile>some-changelog.xml</changeLogFile>
                <url>...</url>
                <migrationSqlOutputFile>file.sql</migrationSqlOutputFile>
                <expressionVars>
                    <property>
                        <name>prop1</name>
                        <value>some-specific-value-1</value>
                    </property>
                    <property>
                        <name>prop2</name>
                        <value>some-common-value-2</value>
                    </property>
                </expressionVars>
            </configuration>
        </execution>

That looks how I was expecting so I don't understand why is the ${prop2} placeholder not replaced?


Solution

  • First of all, it is worth to read Maven How-To: Merging Plugin Configuration in Complex Projects article, describing options provided by maven for merging configuration.

    At second, after reading the article, mentioned above, it becomes clear that it is not clear how to merge "property-based" configurations like yours:

    <expressionVars>
        <property>
            <name>prop1</name>
            <value>some-common-value-1</value>
        </property>
        <property>
            <name>prop2</name>
            <value>some-common-value-2</value>
        </property>
    </expressionVars>  
    

    just because all elements have the same name (property/name/value), fortunately, it seems that liquibase developers anticipated that challenge (or something similar) and have provided the ability to use "map-based" configurations: expressionVariables, so, in your case the following should work:

    <configuration>
        <expressionVariables>
            <prop1>some-common-value-1</prop1>
            <prop2>some-common-value-2</prop2>
        </expressionVariables>
        <skip>true</skip>
    </configuration>
    <executions>
        <execution>
            <id>one</id>
            <configuration>
                <expressionVariables combine.self="append">
                    <prop1 combine.self="override">some-special-value-1</prop1>
                </expressionVariables>
        </execution>
    </executions>