Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to negate a property in pom.xml?

Tags:

maven

I'd like to negate a boolean property as defined in pom.xml.

Meaning, given a property ${doSomething} I need to pass <skip> to a plugin where the value of <skip> should be the negation of ${doSomething}.

If ${doSomething} is false, then I want to skip. If it is true, then I don't want to skip. Any ideas?

Clarification: I am not talking about using the negation of a property for profile activation. I just want to pass the negation of a boolean into a plugin.

like image 387
Gili Avatar asked Dec 02 '16 17:12

Gili


People also ask

What is property in POM xml?

Properties can be defined in a POM or in a Profile. The properties set in a POM or in a Maven Profile can be referenced just like any other property available throughout Maven. User-defined properties can be referenced in a POM, or they can be used to filter resources via the Maven Resource plugin.

How do I get property from POM xml?

In maven pom. xml , a property is accessed by using ${property_name} . You can define your custom properties in Maven.

How do you define a variable in POM xml?

To refer to environment variables from the pom. xml, we can use the ${env. VARIABLE_NAME} syntax. We should remember to pass the Java version information via environment variables.


2 Answers

Apart from profile activation, Maven doesn't have a boolean logic implemented. So if want to negate a property to pass it to a plugin, you'll need to do it yourself. It is a bit clumsy, but you could use the build-helper-maven-plugin:bsh-property goal, which enables to write a BeanShell script and export variables defined in it as Maven properties:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>build-helper-maven-plugin</artifactId>
  <version>1.12</version>
  <executions>
    <execution>
      <id>negate-prop</id>
      <phase>initialize</phase>
      <goals>
        <goal>bsh-property</goal>
      </goals>
      <configuration>
        <source>dontDoSomething = !${doSomething};</source>
        <properties>
          <property>dontDoSomething</property>
        </properties>
      </configuration>
    </execution>
  </executions>
</plugin>

You can't override the property, but you can define a new one containing the result of the negation; in the example above, it is dontDoSomething. This is ran in the initialize phase so that the rest of the plugins can use it as a parameter, with the standard ${dontDoSomething}.

This could be enhanced to have a default value for dontDoSomething if doSomething doesn't exist.

<source>
  value = project.getProperties().getProperty("doSomething");
  dontDoSomething = value == null ? false : !Boolean.parseBoolean(value);
</source>

BeanShell is a scripting language that looks very much like Java and you can use existing Java methods. In the above, the property "doSomething" is retrieved from the project's properties (project is injected by the plugin at evaluation-time with the current Maven project); it it isn't defined, we return false, otherwise, we negate the value.


If doSomething is specifically a system property, it could also be possible to (ab)use the profile activation feature and have 2 profiles: one activated by a property being true and setting another to false, and a second profile doing the inverse:

<profiles>
  <profile>
    <id>pro-1</id>
    <activation>
      <property>
        <name>doSomething</name>
        <value>!false</value>
      </property>
    </activation>
    <properties>
      <dontDoSomething>false</dontDoSomething>
    </properties>
  </profile>
  <profile>
    <id>pro-2</id>
    <activation>
      <property>
        <name>doSomething</name>
        <value>false</value>
      </property>
    </activation>
    <properties>
      <dontDoSomething>true</dontDoSomething>
    </properties>
  </profile>
</profiles>

This won't work if doSomething is a Maven property set in the <properties> tag for example. It will need to be passed as a system property with mvn -DdoSomething=true|false. The corresponding profile will be activated according to the value of the system property, which will define the dontDoSomething property to its inverse. If the property isn't defined, pro-1 will be active, setting dontDoSomething to the default value of false. All of this is quite ugly though...

like image 55
Tunaki Avatar answered Sep 19 '22 05:09

Tunaki


I don't know the exact answer but I think you could try the following to invert the properties value (from http://maven.apache.org/guides/introduction/introduction-to-profiles.html). Declare another property where you invert the value of the first property:

<property>
    <name>dontDoSomething</name>
    <value>!${doSomething}</value>
</property>
like image 39
actc Avatar answered Sep 18 '22 05:09

actc