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 8dac5c2  [MBUILDCACHE-115] - fix execution scope seeding outside of 
forced mode (#217)
8dac5c2 is described below

commit 8dac5c28af1e26f038083c57e4f68c299d76e7a2
Author: Sebastian Tiemann <se...@mailbox.org>
AuthorDate: Wed Jun 4 12:52:45 2025 +0200

    [MBUILDCACHE-115] - fix execution scope seeding outside of forced mode 
(#217)
    
    * [MBUILDCACHE-115] - fix execution scope seeding outside of forced mode
    - added the provided reproduction project as IT
    - Remove protobuf-plugin config parts from IT that are not maven4 
compatible.
---
 .../BuildCacheMojosExecutionStrategy.java          | 146 ++++++++++-----------
 .../apache/maven/buildcache/its/Issue115Test.java  |  57 ++++++++
 .../projects/mbuildcache-115/.mvn/extensions.xml   |  25 ++++
 src/test/projects/mbuildcache-115/pom.xml          |  82 ++++++++++++
 .../mbuildcache-115/src/main/protobuf/test.proto   |   8 ++
 5 files changed, 244 insertions(+), 74 deletions(-)

diff --git 
a/src/main/java/org/apache/maven/buildcache/BuildCacheMojosExecutionStrategy.java
 
b/src/main/java/org/apache/maven/buildcache/BuildCacheMojosExecutionStrategy.java
index 424ca28..a63eccd 100644
--- 
a/src/main/java/org/apache/maven/buildcache/BuildCacheMojosExecutionStrategy.java
+++ 
b/src/main/java/org/apache/maven/buildcache/BuildCacheMojosExecutionStrategy.java
@@ -220,90 +220,88 @@ private CacheRestorationStatus restoreProject(
             MojoExecutionRunner mojoExecutionRunner,
             CacheConfig cacheConfig)
             throws LifecycleExecutionException, MojoExecutionException {
-        mojoExecutionScope.enter();
-        try {
-            final Build build = cacheResult.getBuildInfo();
-            final MavenProject project = cacheResult.getContext().getProject();
-            final MavenSession session = cacheResult.getContext().getSession();
-            mojoExecutionScope.seed(MavenProject.class, project);
-            mojoExecutionScope.seed(MavenSession.class, session);
-            final List<MojoExecution> cachedSegment =
-                    lifecyclePhasesHelper.getCachedSegment(project, 
mojoExecutions, build);
-
-            // Verify cache consistency for cached mojos
-            LOGGER.debug("Verify consistency on cached mojos");
-            Set<MojoExecution> forcedExecutionMojos = new HashSet<>();
-            for (MojoExecution cacheCandidate : cachedSegment) {
-                if (cacheController.isForcedExecution(project, 
cacheCandidate)) {
-                    forcedExecutionMojos.add(cacheCandidate);
-                } else {
-                    if (!verifyCacheConsistency(
-                            cacheCandidate, build, project, session, 
mojoExecutionRunner, cacheConfig)) {
-                        LOGGER.info("A cached mojo is not consistent, 
continuing with non cached build");
-                        return CacheRestorationStatus.FAILURE;
-                    }
+
+        final Build build = cacheResult.getBuildInfo();
+        final MavenProject project = cacheResult.getContext().getProject();
+        final MavenSession session = cacheResult.getContext().getSession();
+        final List<MojoExecution> cachedSegment =
+                lifecyclePhasesHelper.getCachedSegment(project, 
mojoExecutions, build);
+
+        // Verify cache consistency for cached mojos
+        LOGGER.debug("Verify consistency on cached mojos");
+        Set<MojoExecution> forcedExecutionMojos = new HashSet<>();
+        for (MojoExecution cacheCandidate : cachedSegment) {
+            if (cacheController.isForcedExecution(project, cacheCandidate)) {
+                forcedExecutionMojos.add(cacheCandidate);
+            } else {
+                if (!verifyCacheConsistency(
+                        cacheCandidate, build, project, session, 
mojoExecutionRunner, cacheConfig)) {
+                    LOGGER.info("A cached mojo is not consistent, continuing 
with non cached build");
+                    return CacheRestorationStatus.FAILURE;
                 }
             }
+        }
 
-            // Restore project artifacts
-            ArtifactRestorationReport restorationReport = 
cacheController.restoreProjectArtifacts(cacheResult);
-            if (!restorationReport.isSuccess()) {
-                LOGGER.info("Cannot restore project artifacts, continuing with 
non cached build");
-                return restorationReport.isRestoredFilesInProjectDirectory()
-                        ? CacheRestorationStatus.FAILURE_NEEDS_CLEAN
-                        : CacheRestorationStatus.FAILURE;
-            }
+        // Restore project artifacts
+        ArtifactRestorationReport restorationReport = 
cacheController.restoreProjectArtifacts(cacheResult);
+        if (!restorationReport.isSuccess()) {
+            LOGGER.info("Cannot restore project artifacts, continuing with non 
cached build");
+            return restorationReport.isRestoredFilesInProjectDirectory()
+                    ? CacheRestorationStatus.FAILURE_NEEDS_CLEAN
+                    : CacheRestorationStatus.FAILURE;
+        }
 
-            // Execute mandatory mojos (forced by configuration)
-            LOGGER.debug("Execute mandatory mojos in the cache segment");
-            for (MojoExecution cacheCandidate : cachedSegment) {
-                if (forcedExecutionMojos.contains(cacheCandidate)) {
-                    LOGGER.info(
-                            "Mojo execution is forced by project property: {}",
-                            
cacheCandidate.getMojoDescriptor().getFullGoalName());
+        // Execute mandatory mojos (forced by configuration)
+        LOGGER.debug("Execute mandatory mojos in the cache segment");
+        for (MojoExecution cacheCandidate : cachedSegment) {
+            if (forcedExecutionMojos.contains(cacheCandidate)) {
+                LOGGER.info(
+                        "Mojo execution is forced by project property: {}",
+                        cacheCandidate.getMojoDescriptor().getFullGoalName());
+                // need maven 4 as minumum
+                // mojoExecutionScope.seed(
+                //        org.apache.maven.api.plugin.Log.class,
+                //        new DefaultLog(LoggerFactory.getLogger(
+                //                
cacheCandidate.getMojoDescriptor().getFullGoalName())));
+                // mojoExecutionScope.seed(Project.class, ((DefaultSession)
+                // session.getSession()).getProject(project));
+                // mojoExecutionScope.seed(
+                //        org.apache.maven.api.MojoExecution.class, new 
DefaultMojoExecution(cacheCandidate));
+                mojoExecutionRunner.run(cacheCandidate);
+            } else {
+                LOGGER.info(
+                        "Skipping plugin execution (cached): {}",
+                        cacheCandidate.getMojoDescriptor().getFullGoalName());
+                // Need to populate cached candidate executions for the build 
cache save result
+                Mojo mojo = null;
+                mojoExecutionScope.enter();
+                try {
+                    mojoExecutionScope.seed(MavenProject.class, project);
                     mojoExecutionScope.seed(MojoExecution.class, 
cacheCandidate);
-                    // need maven 4 as minumum
-                    // mojoExecutionScope.seed(
-                    //        org.apache.maven.api.plugin.Log.class,
-                    //        new DefaultLog(LoggerFactory.getLogger(
-                    //                
cacheCandidate.getMojoDescriptor().getFullGoalName())));
-                    // mojoExecutionScope.seed(Project.class, ((DefaultSession)
-                    // session.getSession()).getProject(project));
-                    // mojoExecutionScope.seed(
-                    //        org.apache.maven.api.MojoExecution.class, new 
DefaultMojoExecution(cacheCandidate));
-                    mojoExecutionRunner.run(cacheCandidate);
-                } else {
-                    LOGGER.info(
-                            "Skipping plugin execution (cached): {}",
-                            
cacheCandidate.getMojoDescriptor().getFullGoalName());
-                    // Need to populate cached candidate executions for the 
build cache save result
-                    Mojo mojo = null;
-                    try {
-                        mojo = 
mavenPluginManager.getConfiguredMojo(Mojo.class, session, cacheCandidate);
-                        MojoExecutionEvent mojoExecutionEvent =
-                                new MojoExecutionEvent(session, project, 
cacheCandidate, mojo);
-                        mojoListener.beforeMojoExecution(mojoExecutionEvent);
-                    } catch (PluginConfigurationException | 
PluginContainerException e) {
-                        throw new RuntimeException(e);
-                    } finally {
-                        if (mojo != null) {
-                            mavenPluginManager.releaseMojo(mojo, 
cacheCandidate);
-                        }
+
+                    mojo = mavenPluginManager.getConfiguredMojo(Mojo.class, 
session, cacheCandidate);
+                    MojoExecutionEvent mojoExecutionEvent =
+                            new MojoExecutionEvent(session, project, 
cacheCandidate, mojo);
+                    mojoListener.beforeMojoExecution(mojoExecutionEvent);
+                } catch (PluginConfigurationException | 
PluginContainerException e) {
+                    throw new RuntimeException(e);
+                } finally {
+                    mojoExecutionScope.exit();
+                    if (mojo != null) {
+                        mavenPluginManager.releaseMojo(mojo, cacheCandidate);
                     }
                 }
             }
+        }
 
-            // Execute mojos after the cache segment
-            LOGGER.debug("Execute mojos post cache segment");
-            List<MojoExecution> postCachedSegment =
-                    lifecyclePhasesHelper.getPostCachedSegment(project, 
mojoExecutions, build);
-            for (MojoExecution mojoExecution : postCachedSegment) {
-                mojoExecutionRunner.run(mojoExecution);
-            }
-            return CacheRestorationStatus.SUCCESS;
-        } finally {
-            mojoExecutionScope.exit();
+        // Execute mojos after the cache segment
+        LOGGER.debug("Execute mojos post cache segment");
+        List<MojoExecution> postCachedSegment =
+                lifecyclePhasesHelper.getPostCachedSegment(project, 
mojoExecutions, build);
+        for (MojoExecution mojoExecution : postCachedSegment) {
+            mojoExecutionRunner.run(mojoExecution);
         }
+        return CacheRestorationStatus.SUCCESS;
     }
 
     private boolean verifyCacheConsistency(
diff --git a/src/test/java/org/apache/maven/buildcache/its/Issue115Test.java 
b/src/test/java/org/apache/maven/buildcache/its/Issue115Test.java
new file mode 100644
index 0000000..1de8319
--- /dev/null
+++ b/src/test/java/org/apache/maven/buildcache/its/Issue115Test.java
@@ -0,0 +1,57 @@
+/*
+ * 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.util.List;
+
+import org.apache.maven.buildcache.its.junit.IntegrationTest;
+import org.apache.maven.it.VerificationException;
+import org.apache.maven.it.Verifier;
+import org.junit.jupiter.api.Test;
+
+@IntegrationTest("src/test/projects/mbuildcache-115")
+public class Issue115Test {
+
+    private static final String PROJECT_NAME = 
"org.apache.maven.caching.test:mbuildcache-115";
+    private static final String RESTORED_MESSAGE = "Found cached build, 
restoring " + PROJECT_NAME + " from cache";
+
+    @Test
+    void buildShouldRestoreProjectWithoutError(Verifier verifier) throws 
VerificationException {
+        verifier.setAutoclean(false);
+        verifier.setLogFileName("../log-1.txt");
+        verifier.executeGoal("package");
+        verifier.verifyErrorFreeLog();
+        // verify protobuf-plugin is present and has run
+        
verifier.verifyFilePresent("target/generated-sources/protobuf/Test.java");
+        verifyTextNotInLog(verifier, RESTORED_MESSAGE);
+
+        verifier.executeGoal("package");
+        verifier.verifyTextInLog(RESTORED_MESSAGE);
+        verifier.verifyErrorFreeLog();
+    }
+
+    private static void verifyTextNotInLog(Verifier verifier, String text) 
throws VerificationException {
+        List<String> lines = verifier.loadFile(verifier.getBasedir(), 
verifier.getLogFileName(), false);
+        for (String line : lines) {
+            if (Verifier.stripAnsi(line).contains(text)) {
+                throw new VerificationException("Text found in log: " + text);
+            }
+        }
+    }
+}
diff --git a/src/test/projects/mbuildcache-115/.mvn/extensions.xml 
b/src/test/projects/mbuildcache-115/.mvn/extensions.xml
new file mode 100644
index 0000000..8df78f8
--- /dev/null
+++ b/src/test/projects/mbuildcache-115/.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-115/pom.xml 
b/src/test/projects/mbuildcache-115/pom.xml
new file mode 100644
index 0000000..18371f4
--- /dev/null
+++ b/src/test/projects/mbuildcache-115/pom.xml
@@ -0,0 +1,82 @@
+<!--
+
+    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</groupId>
+    <artifactId>mbuildcache-115</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <properties>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>io.github.ascopes</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <version>2.7.0</version>
+
+                <configuration>
+                    <protocVersion>3.24.0</protocVersion>
+
+                    <binaryMavenPlugins>
+                        <binaryMavenPlugin>
+                            <groupId>io.grpc</groupId>
+                            <artifactId>protoc-gen-grpc-java</artifactId>
+                            <version>1.58.0</version>
+                        </binaryMavenPlugin>
+                    </binaryMavenPlugins>
+                </configuration>
+
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>versions-maven-plugin</artifactId>
+                    <version>2.16.0</version>
+                    <configuration>
+                        <generateBackupPoms>false</generateBackupPoms>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+            <version>4.30.2</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/src/test/projects/mbuildcache-115/src/main/protobuf/test.proto 
b/src/test/projects/mbuildcache-115/src/main/protobuf/test.proto
new file mode 100644
index 0000000..4327335
--- /dev/null
+++ b/src/test/projects/mbuildcache-115/src/main/protobuf/test.proto
@@ -0,0 +1,8 @@
+syntax = "proto3";
+
+message Person {
+  string firstName = 1;
+  string lastName = 2;
+  int32 age = 3;
+  float heightInMeters = 4;
+}
\ No newline at end of file

Reply via email to