Skip to content

Commit 90ade09

Browse files
authored
Maven clean build failure when maven.build.cache.failFast=true (#412)
* Fixes #220 * Changed log level to INFO * Fix the JavaDoc comment * Delete commented code * Spotless applied
1 parent e73f519 commit 90ade09

File tree

2 files changed

+92
-18
lines changed

2 files changed

+92
-18
lines changed

src/main/java/org/apache/maven/buildcache/BuildCacheMojosExecutionStrategy.java

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,21 @@ public BuildCacheMojosExecutionStrategy(
100100
public void execute(
101101
List<MojoExecution> mojoExecutions, MavenSession session, MojoExecutionRunner mojoExecutionRunner)
102102
throws LifecycleExecutionException {
103+
103104
try {
104105
final MavenProject project = session.getCurrentProject();
105106
final Source source = getSource(mojoExecutions);
106107

107108
// execute clean bound goals before restoring to not interfere/slowdown clean
108109
CacheState cacheState = DISABLED;
109110
CacheResult result = CacheResult.empty();
110-
boolean skipCache = cacheConfig.isSkipCache() || MavenProjectInput.isSkipCache(project);
111+
boolean skipCache =
112+
cacheConfig.isSkipCache() || MavenProjectInput.isSkipCache(project) || isGoalClean(mojoExecutions);
111113
boolean cacheIsDisabled = MavenProjectInput.isCacheDisabled(project);
112-
// Forked execution should be thought as a part of originating mojo internal implementation
113-
// If forkedExecution is detected, it means that originating mojo is not cached so forks should rerun too
114+
// Forked execution should be thought as a part of originating mojo internal
115+
// implementation
116+
// If forkedExecution is detected, it means that originating mojo is not cached
117+
// so forks should rerun too
114118
boolean forkedExecution = lifecyclePhasesHelper.isForkedProject(project);
115119
String projectName = getVersionlessProjectKey(project);
116120
List<MojoExecution> cleanPhase = null;
@@ -178,13 +182,29 @@ public void execute(
178182
}
179183

180184
/**
181-
* Cache configuration could demand to restore some files in the project directory (generated sources or even arbitrary content)
182-
* If an error occurs during or after this kind of restoration AND a clean phase was required in the build :
183-
* we execute an extra clean phase to remove any potential partially restored files
185+
* Check if the current mojo execution is for the clean goal
186+
*
187+
* @param mojoExecutions the mojo executions
188+
* @return true if the goal is clean and it is the only goal, false otherwise
189+
*/
190+
private boolean isGoalClean(List<MojoExecution> mojoExecutions) {
191+
if (mojoExecutions.stream().allMatch(mojoExecution -> "clean".equals(mojoExecution.getLifecyclePhase()))) {
192+
LOGGER.info("Build cache is disabled for 'clean' goal.");
193+
return true;
194+
}
195+
return false;
196+
}
197+
198+
/**
199+
* Cache configuration could demand to restore some files in the project
200+
* directory (generated sources or even arbitrary content)
201+
* If an error occurs during or after this kind of restoration AND a clean phase
202+
* was required in the build, we execute an extra clean phase to remove any
203+
* potential partially restored files.
184204
*
185205
* @param cacheRestorationStatus the restoration status
186-
* @param cleanPhase clean phase mojos
187-
* @param mojoExecutionRunner mojo runner
206+
* @param cleanPhase clean phase mojos
207+
* @param mojoExecutionRunner mojo runner
188208
* @throws LifecycleExecutionException
189209
*/
190210
private void executeExtraCleanPhaseIfNeeded(
@@ -258,15 +278,6 @@ private CacheRestorationStatus restoreProject(
258278
LOGGER.info(
259279
"Mojo execution is forced by project property: {}",
260280
cacheCandidate.getMojoDescriptor().getFullGoalName());
261-
// need maven 4 as minumum
262-
// mojoExecutionScope.seed(
263-
// org.apache.maven.api.plugin.Log.class,
264-
// new DefaultLog(LoggerFactory.getLogger(
265-
// cacheCandidate.getMojoDescriptor().getFullGoalName())));
266-
// mojoExecutionScope.seed(Project.class, ((DefaultSession)
267-
// session.getSession()).getProject(project));
268-
// mojoExecutionScope.seed(
269-
// org.apache.maven.api.MojoExecution.class, new DefaultMojoExecution(cacheCandidate));
270281
mojoExecutionRunner.run(cacheCandidate);
271282
} else {
272283
LOGGER.info(
@@ -413,7 +424,8 @@ boolean isParamsMatched(
413424
* - all absolute paths under project root to be relativized for portability
414425
* - redundant '..' and '.' to be removed to have consistent views on all paths
415426
* - all relative paths are considered portable and should not be touched
416-
* - absolute paths outside of project directory could not be deterministically relativized and not touched
427+
* - absolute paths outside of project directory could not be deterministically
428+
* relativized and not touched
417429
*/
418430
private static String normalizedPath(Path path, Path baseDirPath) {
419431
boolean isProjectSubdir = path.isAbsolute() && path.startsWith(baseDirPath);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.maven.buildcache.its;
20+
21+
import java.util.List;
22+
23+
import org.apache.maven.buildcache.its.junit.IntegrationTest;
24+
import org.apache.maven.it.VerificationException;
25+
import org.apache.maven.it.Verifier;
26+
import org.junit.jupiter.api.Assertions;
27+
import org.junit.jupiter.api.Test;
28+
import org.testcontainers.shaded.com.google.common.collect.Lists;
29+
30+
import static org.apache.maven.buildcache.util.LogFileUtils.findFirstLineContainingTextsInLogs;
31+
32+
@IntegrationTest("src/test/projects/build-extension")
33+
class SkipBuildExtensionTest {
34+
35+
@Test
36+
void simple(Verifier verifier) throws VerificationException {
37+
verifier.setAutoclean(false);
38+
39+
verifier.setLogFileName("../log-1.txt");
40+
verifier.executeGoal("clean");
41+
verifier.verifyErrorFreeLog();
42+
43+
verifier.verifyTextInLog("Build cache is disabled for 'clean' goal.");
44+
}
45+
46+
@Test
47+
void multipleGoals(Verifier verifier) throws VerificationException {
48+
verifier.setAutoclean(false);
49+
50+
verifier.setLogFileName("../log-2.txt");
51+
String[] goals = {"clean", "install"};
52+
List<String> goalsList = Lists.newArrayList(goals);
53+
verifier.executeGoals(goalsList);
54+
verifier.verifyErrorFreeLog();
55+
56+
verifyNoTextInLog(verifier, "Build cache is disabled for 'clean' goal.");
57+
}
58+
59+
private static void verifyNoTextInLog(Verifier verifier, String text) throws VerificationException {
60+
Assertions.assertNull(findFirstLineContainingTextsInLogs(verifier, text));
61+
}
62+
}

0 commit comments

Comments
 (0)