This is an automated email from the ASF dual-hosted git repository.

olamy pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/maven-build-cache-extension.git


The following commit(s) were added to refs/heads/master by this push:
     new c61188a  [MBUILDCACHE-87] - Checksum should consider plugin 
dependencies (#146)
c61188a is described below

commit c61188a4d0468d6ec0692f54faf68f08db3b6ebe
Author: Réda Housni Alaoui <reda-ala...@hey.com>
AuthorDate: Mon Jul 15 05:25:46 2024 +0200

    [MBUILDCACHE-87] - Checksum should consider plugin dependencies (#146)
    
    * Checksum should consider plugin dependencies
    
    * Support the case of a maven plugin declared multiple times in the pom
---
 .../org/apache/maven/buildcache/CacheDiff.java     |  35 ++++--
 .../maven/buildcache/checksum/DigestUtils.java     |   4 +
 .../buildcache/checksum/MavenProjectInput.java     |  47 +++++++-
 .../apache/maven/buildcache/xml/CacheConfig.java   |   2 +
 .../maven/buildcache/xml/CacheConfigImpl.java      |  11 ++
 src/main/mdo/build-cache-config.mdo                |  11 ++
 src/site/markdown/how-to.md                        |  13 ++
 src/site/resources/maven-build-cache-config.xml    |   2 +-
 .../apache/maven/buildcache/its/Issue87Test.java   | 133 +++++++++++++++++++++
 .../.mvn/maven-build-cache-config.xml              |  29 +++++
 src/test/projects/mbuildcache-87/external/pom.xml  |  31 +++++
 .../mbuildcache-87/top/.mvn/extensions.xml         |  25 ++++
 .../projects/mbuildcache-87/top/module1/pom.xml    |  33 +++++
 .../org/apache/maven/buildcache/test.properties    |  16 +++
 .../projects/mbuildcache-87/top/module2/pom.xml    |  72 +++++++++++
 .../java/org/apache/maven/buildcache/Test2.java    |  24 ++++
 src/test/projects/mbuildcache-87/top/pom.xml       |  47 ++++++++
 17 files changed, 524 insertions(+), 11 deletions(-)

diff --git a/src/main/java/org/apache/maven/buildcache/CacheDiff.java 
b/src/main/java/org/apache/maven/buildcache/CacheDiff.java
index 4c9c63b..a378804 100644
--- a/src/main/java/org/apache/maven/buildcache/CacheDiff.java
+++ b/src/main/java/org/apache/maven/buildcache/CacheDiff.java
@@ -68,6 +68,7 @@ public class CacheDiff {
         compareExecutions(current.getExecutions(), baseline.getExecutions());
         compareFiles(current.getProjectsInputInfo(), 
baseline.getProjectsInputInfo());
         compareDependencies(current.getProjectsInputInfo(), 
baseline.getProjectsInputInfo());
+        comparePluginDependencies(current.getProjectsInputInfo(), 
baseline.getProjectsInputInfo());
 
         final Diff buildDiffType = new Diff();
         buildDiffType.getMismatches().addAll(report);
@@ -157,20 +158,40 @@ public class CacheDiff {
     }
 
     private void compareDependencies(ProjectsInputInfo current, 
ProjectsInputInfo baseline) {
-        final Map<String, DigestItem> currentDependencies = 
current.getItems().stream()
-                .filter(item -> "dependency".equals(item.getType()))
-                .collect(Collectors.toMap(DigestItem::getValue, item -> item));
+        compareDependencies(
+                "dependencies files",
+                current.getItems().stream()
+                        .filter(item -> "dependency".equals(item.getType()))
+                        .collect(Collectors.toList()),
+                baseline.getItems().stream()
+                        .filter(item -> "dependency".equals(item.getType()))
+                        .collect(Collectors.toList()));
+    }
 
-        final Map<String, DigestItem> baselineDependencies = 
baseline.getItems().stream()
-                .filter(item -> "dependency".equals(item.getType()))
-                .collect(Collectors.toMap(DigestItem::getValue, item -> item));
+    private void comparePluginDependencies(ProjectsInputInfo current, 
ProjectsInputInfo baseline) {
+        compareDependencies(
+                "plugin dependencies files",
+                current.getItems().stream()
+                        .filter(item -> 
"pluginDependency".equals(item.getType()))
+                        .collect(Collectors.toList()),
+                baseline.getItems().stream()
+                        .filter(item -> 
"pluginDependency".equals(item.getType()))
+                        .collect(Collectors.toList()));
+    }
+
+    private void compareDependencies(String property, List<DigestItem> 
current, List<DigestItem> baseline) {
+        final Map<String, DigestItem> currentDependencies =
+                
current.stream().collect(Collectors.toMap(DigestItem::getValue, item -> item));
+
+        final Map<String, DigestItem> baselineDependencies =
+                
baseline.stream().collect(Collectors.toMap(DigestItem::getValue, item -> item));
 
         if (!Objects.equals(currentDependencies.keySet(), 
baselineDependencies.keySet())) {
             Set<String> currentVsBaseline = diff(currentDependencies.keySet(), 
baselineDependencies.keySet());
             Set<String> baselineVsCurrent = 
diff(baselineDependencies.keySet(), currentDependencies.keySet());
 
             addNewMismatch(
-                    "dependencies files",
+                    property,
                     "Remote and local builds contain different sets of 
dependencies and cannot be matched. "
                             + "Added dependencies: " + currentVsBaseline + ". 
Removed dependencies: "
                             + baselineVsCurrent,
diff --git 
a/src/main/java/org/apache/maven/buildcache/checksum/DigestUtils.java 
b/src/main/java/org/apache/maven/buildcache/checksum/DigestUtils.java
index da0f3f2..a8e48b5 100644
--- a/src/main/java/org/apache/maven/buildcache/checksum/DigestUtils.java
+++ b/src/main/java/org/apache/maven/buildcache/checksum/DigestUtils.java
@@ -126,6 +126,10 @@ public class DigestUtils {
         return item("dependency", key, checksum.update(hash));
     }
 
+    public static DigestItem pluginDependency(HashChecksum checksum, String 
key, String hash) {
+        return item("pluginDependency", key, checksum.update(hash));
+    }
+
     private static String normalize(Path basedirPath, Path file) {
         return FilenameUtils.separatorsToUnix(relativize(basedirPath, 
file).toString());
     }
diff --git 
a/src/main/java/org/apache/maven/buildcache/checksum/MavenProjectInput.java 
b/src/main/java/org/apache/maven/buildcache/checksum/MavenProjectInput.java
index 06ed5c4..7efc80b 100644
--- a/src/main/java/org/apache/maven/buildcache/checksum/MavenProjectInput.java
+++ b/src/main/java/org/apache/maven/buildcache/checksum/MavenProjectInput.java
@@ -35,6 +35,7 @@ import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -45,6 +46,7 @@ import java.util.SortedMap;
 import java.util.SortedSet;
 import java.util.TreeMap;
 import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Predicate;
 
 import org.apache.commons.lang3.StringUtils;
@@ -177,6 +179,7 @@ public class MavenProjectInput {
         final String effectivePom = 
getEffectivePom(normalizedModelProvider.normalizedModel(project));
         final SortedSet<Path> inputFiles = isPom(project) ? 
Collections.emptySortedSet() : getInputFiles();
         final SortedMap<String, String> dependenciesChecksum = 
getMutableDependencies();
+        final SortedMap<String, String> pluginDependenciesChecksum = 
getMutablePluginDependencies();
 
         final long t1 = System.currentTimeMillis();
 
@@ -184,7 +187,8 @@ public class MavenProjectInput {
         final int count = 1
                 + (config.calculateProjectVersionChecksum() ? 1 : 0)
                 + inputFiles.size()
-                + dependenciesChecksum.size();
+                + dependenciesChecksum.size()
+                + pluginDependenciesChecksum.size();
 
         final List<DigestItem> items = new ArrayList<>(count);
         final HashChecksum checksum = 
config.getHashFactory().createChecksum(count);
@@ -237,6 +241,19 @@ public class MavenProjectInput {
             LOGGER.info("Dependencies: {}", dependenciesMatched ? "MATCHED" : 
"OUT OF DATE");
         }
 
+        boolean pluginDependenciesMatched = true;
+        for (Map.Entry<String, String> entry : 
pluginDependenciesChecksum.entrySet()) {
+            DigestItem dependencyDigest = 
DigestUtils.pluginDependency(checksum, entry.getKey(), entry.getValue());
+            items.add(dependencyDigest);
+            if (compareWithBaseline) {
+                pluginDependenciesMatched &= 
checkItemMatchesBaseline(baselineHolder.get(), dependencyDigest);
+            }
+        }
+
+        if (compareWithBaseline) {
+            LOGGER.info("Plugin dependencies: {}", pluginDependenciesMatched ? 
"MATCHED" : "OUT OF DATE");
+        }
+
         final ProjectsInputInfo projectsInputInfoType = new 
ProjectsInputInfo();
         projectsInputInfoType.setChecksum(checksum.digest());
         projectsInputInfoType.getItems().addAll(items);
@@ -616,9 +633,32 @@ public class MavenProjectInput {
     }
 
     private SortedMap<String, String> getMutableDependencies() throws 
IOException {
+        return getMutableDependenciesHashes("", project.getDependencies());
+    }
+
+    private SortedMap<String, String> getMutablePluginDependencies() throws 
IOException {
+        Map<String, AtomicInteger> keyPrefixOccurrenceIndex = new HashMap<>();
+        SortedMap<String, String> fullMap = new TreeMap<>();
+        for (Plugin plugin : project.getBuildPlugins()) {
+            if (config.isPluginDependenciesExcluded(plugin)) {
+                continue;
+            }
+
+            String rawKeyPrefix = 
KeyUtils.getVersionlessArtifactKey(repoSystem.createPluginArtifact(plugin));
+            int occurrenceIndex = keyPrefixOccurrenceIndex
+                    .computeIfAbsent(rawKeyPrefix, k -> new AtomicInteger())
+                    .getAndIncrement();
+            fullMap.putAll(
+                    getMutableDependenciesHashes(rawKeyPrefix + "|" + 
occurrenceIndex + "|", plugin.getDependencies()));
+        }
+        return fullMap;
+    }
+
+    private SortedMap<String, String> getMutableDependenciesHashes(String 
keyPrefix, List<Dependency> dependencies)
+            throws IOException {
         SortedMap<String, String> result = new TreeMap<>();
 
-        for (Dependency dependency : project.getDependencies()) {
+        for (Dependency dependency : dependencies) {
 
             if (CacheUtils.isPom(dependency)) {
                 // POM dependency will be resolved by maven system to actual 
dependencies
@@ -648,7 +688,8 @@ public class MavenProjectInput {
                 projectHash = resolved.getHash();
             }
             result.put(
-                    
KeyUtils.getVersionlessArtifactKey(repoSystem.createDependencyArtifact(dependency)),
 projectHash);
+                    keyPrefix + 
KeyUtils.getVersionlessArtifactKey(repoSystem.createDependencyArtifact(dependency)),
+                    projectHash);
         }
         return result;
     }
diff --git a/src/main/java/org/apache/maven/buildcache/xml/CacheConfig.java 
b/src/main/java/org/apache/maven/buildcache/xml/CacheConfig.java
index b06d880..d86b15d 100644
--- a/src/main/java/org/apache/maven/buildcache/xml/CacheConfig.java
+++ b/src/main/java/org/apache/maven/buildcache/xml/CacheConfig.java
@@ -58,6 +58,8 @@ public interface CacheConfig {
     @Nonnull
     List<String> getEffectivePomExcludeProperties(Plugin plugin);
 
+    boolean isPluginDependenciesExcluded(Plugin plugin);
+
     @Nullable
     MultiModule getMultiModule();
 
diff --git a/src/main/java/org/apache/maven/buildcache/xml/CacheConfigImpl.java 
b/src/main/java/org/apache/maven/buildcache/xml/CacheConfigImpl.java
index 69fabb7..4b6287d 100644
--- a/src/main/java/org/apache/maven/buildcache/xml/CacheConfigImpl.java
+++ b/src/main/java/org/apache/maven/buildcache/xml/CacheConfigImpl.java
@@ -304,6 +304,17 @@ public class CacheConfigImpl implements 
org.apache.maven.buildcache.xml.CacheCon
         return Collections.emptyList();
     }
 
+    @Override
+    public boolean isPluginDependenciesExcluded(Plugin plugin) {
+        checkInitializedState();
+        final PluginConfigurationScan pluginConfig = 
findPluginScanConfig(plugin);
+
+        if (pluginConfig != null) {
+            return pluginConfig.isExcludeDependencies();
+        }
+        return false;
+    }
+
     @Nullable
     @Override
     public MultiModule getMultiModule() {
diff --git a/src/main/mdo/build-cache-config.mdo 
b/src/main/mdo/build-cache-config.mdo
index 6271a13..ecb15e6 100644
--- a/src/main/mdo/build-cache-config.mdo
+++ b/src/main/mdo/build-cache-config.mdo
@@ -494,6 +494,12 @@ under the License.
     <xs:complexType name="PluginConfigurationScanType">
         <xs:complexContent>
             <xs:extension base="c:CoordinatesBaseType">
+                <xs:attribute name="calculateProjectVersionChecksum" 
type="xs:boolean" default="false" use="optional">
+                    <xs:annotation>
+                        <xs:documentation 
source="version">0.0.0+</xs:documentation>
+                        <xs:documentation source="description">True to exclude 
plugin dependencies from the calculation rules.</xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
                 <xs:sequence>
                     <xs:element name="effectivePom" minOccurs="0">
                         <xs:annotation>
@@ -540,6 +546,11 @@ under the License.
             <name>PluginConfigurationScan</name>
             <superClass>CoordinatesBase</superClass>
             <fields>
+                <field xml.attribute="true">
+                    <name>excludeDependencies</name>
+                    <type>boolean</type>
+                    <description>True to exclude plugin dependencies from the 
calculation rules</description>
+                </field>
                 <field>
                     <name>effectivePom</name>
                     <association>
diff --git a/src/site/markdown/how-to.md b/src/site/markdown/how-to.md
index 879ccf2..e077a0a 100644
--- a/src/site/markdown/how-to.md
+++ b/src/site/markdown/how-to.md
@@ -214,3 +214,16 @@ git reset --hard
 
 Solution: set `-Dmaven.build.cache.remote.save.final=true` to nodes that 
produce final builds. Such builds will not be overridden
 and eventually will replace all interim builds
+
+### I want to disable dependencies checksum calculation of one plugin
+
+Set attribute `excludeDependencies` to `true` in `input/plugins/plugin` 
section:
+
+```xml
+    <input>
+      <plugins>
+        <plugin artifactId="maven-surefire-plugin" excludeDependencies="true">
+        </plugin>
+      </plugins>
+    </input>
+```
diff --git a/src/site/resources/maven-build-cache-config.xml 
b/src/site/resources/maven-build-cache-config.xml
index dc965a1..b31c955 100644
--- a/src/site/resources/maven-build-cache-config.xml
+++ b/src/site/resources/maven-build-cache-config.xml
@@ -56,7 +56,7 @@
             </excludes>
         </global>
         <plugins>
-            <plugin artifactId="codegen">
+            <plugin artifactId="codegen" excludeDependencies="false">
                 <effectivePom>
                     <excludeProperties>
                         <excludeProperty>111</excludeProperty>
diff --git a/src/test/java/org/apache/maven/buildcache/its/Issue87Test.java 
b/src/test/java/org/apache/maven/buildcache/its/Issue87Test.java
new file mode 100644
index 0000000..66e90db
--- /dev/null
+++ b/src/test/java/org/apache/maven/buildcache/its/Issue87Test.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.maven.buildcache.its;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.buildcache.its.junit.IntegrationTest;
+import org.apache.maven.buildcache.util.LogFileUtils;
+import org.apache.maven.buildcache.xml.XmlService;
+import org.apache.maven.buildcache.xml.build.ProjectsInputInfo;
+import org.apache.maven.it.VerificationException;
+import org.apache.maven.it.Verifier;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@IntegrationTest("src/test/projects/mbuildcache-87")
+public class Issue87Test {
+
+    private static final String MODULE1_PROJECT_ARTIFACT = 
"org.apache.maven.caching.test.mbuildcache-87:module1:jar";
+    private static final String MODULE2_PROJECT_NAME = 
"org.apache.maven.caching.test.mbuildcache-87:module2";
+    private static final String FOUND_CACHED_RESTORING_MODULE2_MESSAGE =
+            "Found cached build, restoring " + MODULE2_PROJECT_NAME + " from 
cache";
+
+    @Test
+    void simple(Verifier verifier) throws VerificationException, IOException {
+        verifier.setLogFileName("../log-0.txt");
+        verifier.executeGoals(Arrays.asList("-f", "external", "install"));
+        verifier.verifyErrorFreeLog();
+
+        verifier.setAutoclean(false);
+
+        verifier.setLogFileName("../log-1.txt");
+        verifier.executeGoals(Arrays.asList("-f", "top", "verify"));
+        verifier.verifyErrorFreeLog();
+
+        verifier.setLogFileName("../log-2.txt");
+        verifier.executeGoals(Arrays.asList("-f", "top", "verify"));
+        verifier.verifyErrorFreeLog();
+        verifier.verifyTextInLog(FOUND_CACHED_RESTORING_MODULE2_MESSAGE);
+
+        // START: Modifying maven plugin reactor dependency makes the cache 
stale
+        
verifier.writeFile("top/module1/src/main/resources/org/apache/maven/buildcache/test.properties",
 "foo=bar");
+        verifier.setLogFileName("../log-3.txt");
+        verifier.executeGoals(Arrays.asList("-f", "top", "verify"));
+        verifier.verifyErrorFreeLog();
+        verifyTextNotInLog(verifier, FOUND_CACHED_RESTORING_MODULE2_MESSAGE);
+        // END: Modifying maven plugin reactor dependency makes the cache stale
+
+        String buildInfoXmlLog =
+                LogFileUtils.findLinesContainingTextsInLogs(verifier, "Saved 
Build to local file: ").stream()
+                        .filter(line -> line.contains("module2"))
+                        .findFirst()
+                        .orElseThrow(
+                                () -> new VerificationException("Could not 
find module2 build info file location"));
+        Path buildInfoXmlLocation = 
Paths.get(buildInfoXmlLog.split(":\\s")[1]);
+
+        ProjectsInputInfo projectsInputInfo =
+                new 
XmlService().loadBuild(buildInfoXmlLocation.toFile()).getProjectsInputInfo();
+
+        assertEquals(
+                1,
+                projectsInputInfo.getItems().stream()
+                        .filter(item -> "dependency".equals(item.getType()))
+                        .filter(item -> 
MODULE1_PROJECT_ARTIFACT.equals(item.getValue()))
+                        .count(),
+                "Expected artifact acting as plugin dependency and project 
dependency to be considered twice during checksum computation");
+        assertEquals(
+                1,
+                projectsInputInfo.getItems().stream()
+                        .filter(item -> 
"pluginDependency".equals(item.getType()))
+                        .filter(item -> 
("org.apache.maven.plugins:maven-dependency-plugin:maven-plugin|0|"
+                                        + MODULE1_PROJECT_ARTIFACT)
+                                .equals(item.getValue()))
+                        .count(),
+                "Expected artifact acting as plugin dependency and project 
dependency to be considered twice during checksum computation");
+
+        assertEquals(
+                1,
+                projectsInputInfo.getItems().stream()
+                        .filter(item -> 
"pluginDependency".equals(item.getType()))
+                        .filter(item ->
+                                
"org.apache.maven.plugins:maven-dependency-plugin:maven-plugin|0|org.apache.maven.caching.test.mbuildcache-87:external:jar"
+                                        .equals(item.getValue()))
+                        .count(),
+                "Expected external snapshot plugin dependency to be included 
in the checksum computation");
+
+        assertEquals(
+                0,
+                projectsInputInfo.getItems().stream()
+                        .filter(item -> 
"pluginDependency".equals(item.getType()))
+                        .filter(item -> item.getValue()
+                                
.startsWith("org.apache.maven.plugins:maven-compiler-plugin:maven-plugin|"))
+                        .count(),
+                "Expected plugins having excludeDependencies=true to have 
their dependencies excluded");
+    }
+
+    private void verifyTextNotInLog(Verifier verifier, String text) throws 
VerificationException {
+
+        List<String> lines = verifier.loadFile(verifier.getBasedir(), 
verifier.getLogFileName(), false);
+
+        boolean result = true;
+        for (String line : lines) {
+            if (Verifier.stripAnsi(line).contains(text)) {
+                result = false;
+                break;
+            }
+        }
+        if (!result) {
+            throw new VerificationException("Text found in log: " + text);
+        }
+    }
+}
diff --git a/src/test/projects/mbuildcache-87/.mvn/maven-build-cache-config.xml 
b/src/test/projects/mbuildcache-87/.mvn/maven-build-cache-config.xml
new file mode 100644
index 0000000..8e416ee
--- /dev/null
+++ b/src/test/projects/mbuildcache-87/.mvn/maven-build-cache-config.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+
+<cache xmlns="http://maven.apache.org/BUILD-CACHE-CONFIG/1.0.0";>
+  <input>
+    <plugins>
+      <plugin groupId="org.apache.maven.plugins" 
artifactId="maven-compiler-plugin" excludeDependencies="true">
+      </plugin>
+    </plugins>
+  </input>
+</cache>
diff --git a/src/test/projects/mbuildcache-87/external/pom.xml 
b/src/test/projects/mbuildcache-87/external/pom.xml
new file mode 100644
index 0000000..3c0fac9
--- /dev/null
+++ b/src/test/projects/mbuildcache-87/external/pom.xml
@@ -0,0 +1,31 @@
+<!--
+
+    Copyright 2021 the original author or authors.
+
+    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.
+
+-->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns="http://maven.apache.org/POM/4.0.0";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.maven.caching.test.mbuildcache-87</groupId>
+    <artifactId>external</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+
+    <properties>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+    </properties>
+
+</project>
diff --git a/src/test/projects/mbuildcache-87/top/.mvn/extensions.xml 
b/src/test/projects/mbuildcache-87/top/.mvn/extensions.xml
new file mode 100644
index 0000000..8df78f8
--- /dev/null
+++ b/src/test/projects/mbuildcache-87/top/.mvn/extensions.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright 2021 the original author or authors.
+
+    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.
+
+-->
+<extensions>
+    <extension>
+        <groupId>org.apache.maven.extensions</groupId>
+        <artifactId>maven-build-cache-extension</artifactId>
+        <version>${projectVersion}</version>
+    </extension>
+</extensions>
diff --git a/src/test/projects/mbuildcache-87/top/module1/pom.xml 
b/src/test/projects/mbuildcache-87/top/module1/pom.xml
new file mode 100644
index 0000000..b072a03
--- /dev/null
+++ b/src/test/projects/mbuildcache-87/top/module1/pom.xml
@@ -0,0 +1,33 @@
+<!--
+
+    Copyright 2021 the original author or authors.
+
+    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.
+
+-->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns="http://maven.apache.org/POM/4.0.0";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>module1</artifactId>
+    <packaging>jar</packaging>
+
+    <parent>
+        <groupId>org.apache.maven.caching.test.mbuildcache-87</groupId>
+        <artifactId>top</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+
+</project>
diff --git 
a/src/test/projects/mbuildcache-87/top/module1/src/main/resources/org/apache/maven/buildcache/test.properties
 
b/src/test/projects/mbuildcache-87/top/module1/src/main/resources/org/apache/maven/buildcache/test.properties
new file mode 100644
index 0000000..71e666b
--- /dev/null
+++ 
b/src/test/projects/mbuildcache-87/top/module1/src/main/resources/org/apache/maven/buildcache/test.properties
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
diff --git a/src/test/projects/mbuildcache-87/top/module2/pom.xml 
b/src/test/projects/mbuildcache-87/top/module2/pom.xml
new file mode 100644
index 0000000..fcc64bf
--- /dev/null
+++ b/src/test/projects/mbuildcache-87/top/module2/pom.xml
@@ -0,0 +1,72 @@
+<!--
+
+    Copyright 2021 the original author or authors.
+
+    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.
+
+-->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns="http://maven.apache.org/POM/4.0.0";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>module2</artifactId>
+    <packaging>jar</packaging>
+
+    <parent>
+        <groupId>org.apache.maven.caching.test.mbuildcache-87</groupId>
+        <artifactId>top</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>module1</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <dependencies>
+                    <dependency>
+                        <groupId>${project.groupId}</groupId>
+                        <artifactId>module1</artifactId>
+                        <version>${project.version}</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>${project.groupId}</groupId>
+                        <artifactId>external</artifactId>
+                        <version>0.0.1-SNAPSHOT</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <dependencies>
+                    <dependency>
+                        <groupId>${project.groupId}</groupId>
+                        <artifactId>module1</artifactId>
+                        <version>${project.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git 
a/src/test/projects/mbuildcache-87/top/module2/src/main/java/org/apache/maven/buildcache/Test2.java
 
b/src/test/projects/mbuildcache-87/top/module2/src/main/java/org/apache/maven/buildcache/Test2.java
new file mode 100644
index 0000000..03f66a8
--- /dev/null
+++ 
b/src/test/projects/mbuildcache-87/top/module2/src/main/java/org/apache/maven/buildcache/Test2.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.maven.buildcache;
+
+class Test
+{
+
+}
\ No newline at end of file
diff --git a/src/test/projects/mbuildcache-87/top/pom.xml 
b/src/test/projects/mbuildcache-87/top/pom.xml
new file mode 100644
index 0000000..1a5587f
--- /dev/null
+++ b/src/test/projects/mbuildcache-87/top/pom.xml
@@ -0,0 +1,47 @@
+<!--
+
+    Copyright 2021 the original author or authors.
+
+    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.
+
+-->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns="http://maven.apache.org/POM/4.0.0";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.maven.caching.test.mbuildcache-87</groupId>
+    <artifactId>top</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>pom</packaging>
+
+    <properties>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+    </properties>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>org.apache.maven.extensions</groupId>
+                <artifactId>maven-build-cache-extension</artifactId>
+                <version>${projectVersion}</version>
+            </extension>
+        </extensions>
+    </build>
+
+    <modules>
+        <module>module1</module>
+        <module>module2</module>
+    </modules>
+
+</project>


Reply via email to