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

elharo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-filtering.git


The following commit(s) were added to refs/heads/master by this push:
     new ebefa11  [MSHARED-1285] use an up-to-date scanner instead the 
newscanner (#77)
ebefa11 is described below

commit ebefa118a2ee10fb011128b93a50d29d0867883e
Author: Christoph Läubrich <m...@laeubi-soft.de>
AuthorDate: Tue Dec 19 18:39:56 2023 +0100

    [MSHARED-1285] use an up-to-date scanner instead the newscanner (#77)
    
    * [MSHARED-1285] - exhibit incremental issue
    
    Current incremental build does not honor isUptodate(), so changed or
    removed target resources are not refreshed until sources are modified or
    a full build is performed.
    
    2 new testcases exhibits this issue (one for missing target resource,
    one for modified target resource). As stub BuildContext provides
    appropriate isUptodate results, build should refresh this resources.
    
    Current implementation prevents BuildContext implementors to trigger
    appropriate resource refresh by tweaking isUptodate implementation.
    
    See javadoc in BuildContext#newScanner javadoc that advices that
    incremental build may be performed with a full resource scanning and a
    isUptodate call to refresh only needed resources.
    
    * MSHARED-1285 use an up-to-date scanner instead the newscanner
    
    Currently it could happen that the scanner misses changed files (because
    they are not part of the delta) or copies files even if they have not
    changed (e.g. because the output has changes).
    
    This uses now a different approach, instead of only handling the delta
    files, we scan all inputs and compare if they are up-to-date with the
    output.
    
    ---------
    
    Co-authored-by: Laurent Almeras <laurent.alme...@kobalt.fr>
    Co-authored-by: Christoph Läubrich <christ...@laeubi-soft.de>
---
 .../filtering/DefaultMavenResourcesFiltering.java  | 47 ++++++++++++++++-----
 .../IncrementalResourceFilteringTest.java          | 49 ++++++++++++++++++++++
 2 files changed, 85 insertions(+), 11 deletions(-)

diff --git 
a/src/main/java/org/apache/maven/shared/filtering/DefaultMavenResourcesFiltering.java
 
b/src/main/java/org/apache/maven/shared/filtering/DefaultMavenResourcesFiltering.java
index f5a5cd6..3713d7c 100644
--- 
a/src/main/java/org/apache/maven/shared/filtering/DefaultMavenResourcesFiltering.java
+++ 
b/src/main/java/org/apache/maven/shared/filtering/DefaultMavenResourcesFiltering.java
@@ -37,6 +37,7 @@ import java.util.Locale;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.maven.model.Resource;
+import org.codehaus.plexus.util.DirectoryScanner;
 import org.codehaus.plexus.util.Scanner;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -189,8 +190,7 @@ public class DefaultMavenResourcesFiltering implements 
MavenResourcesFiltering {
             // as destination
             // see MNG-1345
             File outputDirectory = 
mavenResourcesExecution.getOutputDirectory();
-            boolean outputExists = outputDirectory.exists();
-            if (!outputExists && !outputDirectory.mkdirs()) {
+            if (!outputDirectory.mkdirs() && !outputDirectory.exists()) {
                 throw new MavenFilteringException("Cannot create resource 
output directory: " + outputDirectory);
             }
 
@@ -198,11 +198,36 @@ public class DefaultMavenResourcesFiltering implements 
MavenResourcesFiltering {
                 isFilteringUsed = true;
             }
 
-            boolean ignoreDelta = !outputExists
-                    || 
buildContext.hasDelta(mavenResourcesExecution.getFileFilters())
-                    || 
buildContext.hasDelta(getRelativeOutputDirectory(mavenResourcesExecution));
-            LOGGER.debug("ignoreDelta " + ignoreDelta);
-            Scanner scanner = buildContext.newScanner(resourceDirectory, 
ignoreDelta);
+            boolean filtersFileChanged = 
buildContext.hasDelta(mavenResourcesExecution.getFileFilters());
+            Path resourcePath = resourceDirectory.toPath();
+            DirectoryScanner scanner = new DirectoryScanner() {
+                @Override
+                protected boolean isSelected(String name, File file) {
+                    if (filtersFileChanged) {
+                        // if the file filters file has a change we must 
assume everything is out of
+                        // date
+                        return true;
+                    }
+                    if (file.isFile()) {
+                        try {
+                            File targetFile = getTargetFile(file);
+                            if (targetFile.isFile() && 
buildContext.isUptodate(targetFile, file)) {
+                                return false;
+                            }
+                        } catch (MavenFilteringException e) {
+                            // can't really do anything than to assume we must 
copy the file...
+                        }
+                    }
+                    return true;
+                }
+
+                private File getTargetFile(File file) throws 
MavenFilteringException {
+                    Path relativize = resourcePath.relativize(file.toPath());
+                    return getDestinationFile(
+                            outputDirectory, targetPath, 
relativize.toString(), mavenResourcesExecution);
+                }
+            };
+            scanner.setBasedir(resourceDirectory);
 
             setupScanner(resource, scanner, 
mavenResourcesExecution.isAddDefaultExcludes());
 
@@ -276,13 +301,13 @@ public class DefaultMavenResourcesFiltering implements 
MavenResourcesFiltering {
 
             // deal with deleted source files
 
-            scanner = buildContext.newDeleteScanner(resourceDirectory);
+            Scanner deleteScanner = 
buildContext.newDeleteScanner(resourceDirectory);
 
-            setupScanner(resource, scanner, 
mavenResourcesExecution.isAddDefaultExcludes());
+            setupScanner(resource, deleteScanner, 
mavenResourcesExecution.isAddDefaultExcludes());
 
-            scanner.scan();
+            deleteScanner.scan();
 
-            for (String name : scanner.getIncludedFiles()) {
+            for (String name : deleteScanner.getIncludedFiles()) {
                 File destinationFile = getDestinationFile(outputDirectory, 
targetPath, name, mavenResourcesExecution);
 
                 destinationFile.delete();
diff --git 
a/src/test/java/org/apache/maven/shared/filtering/IncrementalResourceFilteringTest.java
 
b/src/test/java/org/apache/maven/shared/filtering/IncrementalResourceFilteringTest.java
index 0e6a5e9..5a66553 100644
--- 
a/src/test/java/org/apache/maven/shared/filtering/IncrementalResourceFilteringTest.java
+++ 
b/src/test/java/org/apache/maven/shared/filtering/IncrementalResourceFilteringTest.java
@@ -124,6 +124,55 @@ public class IncrementalResourceFilteringTest extends 
TestSupport {
         assertTrue(ctx.getRefreshFiles().contains(outputFile02));
     }
 
+    /**
+     * Check that missing targets are rebuilt even if source is not changed 
(MSHARED-1285)
+     */
+    public void testMissingTarget() throws Exception {
+        // run full build first
+        filter("time");
+
+        // erase target files
+        outputFile01.toFile().delete();
+        outputFile02.toFile().delete();
+        // report change only on one file
+        Set<Path> changedFiles = new HashSet<>();
+        changedFiles.add(inputFile01);
+        TestIncrementalBuildContext ctx = new 
TestIncrementalBuildContext(baseDirectory, changedFiles);
+        ThreadBuildContext.setThreadBuildContext(ctx);
+
+        filter("time");
+
+        assertTrue(ctx.getRefreshFiles().contains(outputFile01));
+        assertTrue(ctx.getRefreshFiles().contains(outputFile02));
+        assertTrue(outputFile01.toFile().exists());
+        assertTrue(outputFile02.toFile().exists());
+    }
+
+    /**
+     * Check that updated targets with unchanged sources are updated 
(MSHARED-1285)
+     */
+    public void testUpdatedTarget() throws Exception {
+        // run full build first
+        filter("time");
+
+        // touch target file02
+        FileUtils.touch(outputFile02.toFile());
+        Set<Path> changedFiles = new HashSet<>();
+        changedFiles.add(inputFile01);
+        // report change only on target file
+        changedFiles.add(outputFile02);
+        TestIncrementalBuildContext ctx = new 
TestIncrementalBuildContext(baseDirectory, changedFiles);
+        ThreadBuildContext.setThreadBuildContext(ctx);
+
+        // both files are updated
+        filter("notime");
+        assertTime("notime", "file01.txt");
+        assertTime("notime", "file02.txt");
+
+        assertTrue(ctx.getRefreshFiles().contains(outputFile01));
+        assertTrue(ctx.getRefreshFiles().contains(outputFile02));
+    }
+
     public void testFilterDeleted() throws Exception {
         // run full build first
         filter("time");

Reply via email to