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

Viewed 59

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!

1 Answers

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

Related