Search code examples
mavenmaven-3maven-plugin

Maven plugin - How to configure element for each item of a list


I'm trying to setup and enforce code coverage at the parent module but allow overrides from the child modules. Specifically jacoco-maven-plugin and exclusions for rules coming from child modules. I've been to: http://maven.apache.org/pom.html#advanced_configuration_inheritance and have tried all sorts of the combine options without success.

In the parent I've got a plugin definition like the following:

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  ...
  <configuration>
   <rules>
    <rule>
      <element>CLASS</element>
      <limits>
        <limit implementation="org.jacoco.report.check.Limit">
         <counter>LINE</counter>
         <value>COVEREDRATIO</value>
         <minimum>1.0</minimum>
        </limit>
      </limits>
    </rule>
    <rule>
      <element>BUNDLE</element>
      <limits>
        <limit implementation="org.jacoco.report.check.Limit">
         <counter>PACKAGE</counter>
         <value>COVEREDRATIO</value>
         <minimum>1.0</minimum>
        </limit>
      </limits>
    </rule> </rules> </configuration>

In the child modules I'm trying to avoid copy and pasting everywhere but I'm struggling to get the maven plugin configuration to do what I want.

In my child modules I'd like to have something like:

        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <configuration>
           <rules>
            <rule>
              <excludes>
                <exclude>*Application*</exclude>
                <exclude>*Config*</exclude>
              </excludes>
            </rule>
          </rules>
        </configuration>
      </plugin>

to produce the following effective-pom with the exclusion added to each rule element.

   <rules>
    <rule>
      <element>CLASS</element> 
      <excludes>
        <exclude>*Application*</exclude>
        <exclude>*Config*</exclude>
      </excludes>
      <limits>...</limit>
      </limits>
    </rule>
    <rule>
      <element>BUNDLE</element> 
      <excludes>
        <exclude>*Application*</exclude>
        <exclude>*Config*</exclude>
      </excludes>
      <limits>...</limits>
    </rule> </rules> </configuration>

I've tried lots of the plugin configuration inheritance attributes but haven't been able to crack it. combine.self=[merge|override|append]
combine.children=[merge|override|append]

<rules combine.self="merge">
            <rule>
              <excludes combine.children="append">
                <exclude>*Application*</exclude>
                <exclude>*Config*</exclude>
              </excludes>
            </rule>
          </rules>

but the resulting effective-pom only contains the first rule definition and that means losing the BUNDLE rule configuration

   <rules>
    <rule>
      <element>CLASS</element> 
      <excludes>
        <exclude>*Application*</exclude>
        <exclude>*Config*</exclude>
      </excludes>
      <limits>...</limit>
      </limits>
    </rule>

Is it possible to configure maven to ADD/APPEND/OVERRIDE this <excludes/> for each child rule elements?

Thanks for any insights!


Solution

  • There's probably some other magic way to solve this that I'm completely missing but here's how I got beyond my blocking issue.

    The page for advanced configuration inheritance only mentions combine.children or combine.self but reading the POM.xsd there is mention of https://codehaus-plexus.github.io/plexus-utils/apidocs/org/codehaus/plexus/util/xml/Xpp3DomUtils.html

    in the digging into the doc for this page I stumbled upon two additional options combine.id and combine.keys I'm grateful there were tests that provided a reference for how these attributes work.

    In my parent pom, I've defined the plugin configuration with these combine.id attributes.

      <groupId>org.jacoco</groupId>
      <artifactId>jacoco-maven-plugin</artifactId>
      ...
      <configuration>
    <rules combine.id="jacoco-rules" combine.children="merge">
                  <rule combine.id="class-rule"  combine.children="merge">
                    <element>CLASS</element>
                    <excludes combine.id="class-rule-excludes" combine.children="merge">
                      <exclude>META-INF/**</exclude>
                    </excludes>
                    <limits>
                      ...
                    </limits>
                  </rule>
                  <rule combine.id="bundle-rule" >
                    <element>BUNDLE</element>
                    <excludes combine.id="bundle-rule-excludes" combine.children="merge">
                      <exclude>META-INF/**</exclude>
                    </excludes>
                    <limits>...
    

    this allows me to add to existing rules in my child poms referencing this combine.id and my working solution now looks something like

            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
              <rules combine.id="jacoco-rules" combine.children="merge">
                <rule combine.id="class-rule" combine.children="merge">
                  <excludes combine.children="append">
                    <exclude>*Application*</exclude>
                    <exclude>*Config*</exclude>
                  </excludes>
                </rule>
                <rule combine.id="bundle-rule"></rule>
              </rules>
            </configuration>
          </plugin>
    

    the effective-pom now looks as I'm expecting it to with both the CLASS and BUNDLE rules present and configured but only CLASS has the excludes element.

    Effective-pom

                    <rule combine.id="class-rule" combine.children="merge">
                      <!--This is the element I was trying to add to this plugin configuration -->
                      <excludes combine.id="class-rule-excludes" combine.children="append">
                        <exclude>*Application*</exclude>
                        <exclude>*Config*</exclude>
                      </excludes>
                      <element>CLASS</element>
                      <limits>...
                      </limits>
                    </rule>
                    <rule combine.id="bundle-rule">
                      <element>BUNDLE</element>
        <!-- no child plugin changes -->
    
    

    NOTE: I'm pretty sure all the combine.children="merge" attributes are redundant AND these combine.id or combine.keys may not be available in your version of maven.

    HTH