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

royteeuwen pushed a commit to branch feature/SLING-12146-windows-build
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit fece945075abb99e8981160f41795a00df7143f3
Author: Roy Teeuwen <[email protected]>
AuthorDate: Thu Aug 20 21:24:52 2026 +0200

    SLING-12146 - fix the Windows build
    
    Three separate causes behind the nine failures in the log attached to the 
issue:
    
    - No .gitattributes, so Git for Windows' default core.autocrlf=true rewrote 
the
      fixtures on checkout. That broke the two tests that hash and PGP-verify a 
.pom
      byte-for-byte, and the three that compare generated mail against LF-only 
text
      blocks. Reproduced by converting the resources to CRLF locally.
    
    - JBakeContentUpdater used Files.write(Path, Iterable), which terminates 
lines with
      the platform separator. On Windows that rewrote every line of the LF-only 
site
      sources, so update-local-site would have pushed a whole-file diff to the 
website
      rather than the intended change.
    
    - downloadFileFromRepository never closed the stream it wrote each artifact 
to,
      leaking a descriptor per file. On Windows the open handle leaves the 
directory
      entry in place after the delete, which is the DirectoryNotEmptyException 
the
      issue reports.
    
    Also drops the operatingSystems pin added as a workaround in #24, so the 
Windows
    build runs again and can confirm the fix.
---
 .gitattributes                                            |  3 +++
 .sling-module.json                                        |  5 +----
 .../apache/sling/cli/impl/jbake/JBakeContentUpdater.java  | 15 ++++++++++++---
 .../apache/sling/cli/impl/nexus/RepositoryService.java    |  6 ++++--
 .../sling/cli/impl/nexus/RepositoryServiceTest.java       | 15 +++++++++------
 5 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..9194060
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,3 @@
+# Fixtures are hashed and PGP-verified byte-for-byte, and the email templates 
are compared against
+# LF-only text blocks, so no checkout may rewrite line endings (Git for 
Windows defaults autocrlf on).
+* -text
diff --git a/.sling-module.json b/.sling-module.json
index 5b5a5e5..1adf09b 100644
--- a/.sling-module.json
+++ b/.sling-module.json
@@ -1,8 +1,5 @@
 {
     "jenkins": {
-        "jdks": [21],
-        "operatingSystems": [
-            "linux"
-        ]
+        "jdks": [21]
     }
 }
diff --git 
a/src/main/java/org/apache/sling/cli/impl/jbake/JBakeContentUpdater.java 
b/src/main/java/org/apache/sling/cli/impl/jbake/JBakeContentUpdater.java
index b2f9cc8..401bc52 100644
--- a/src/main/java/org/apache/sling/cli/impl/jbake/JBakeContentUpdater.java
+++ b/src/main/java/org/apache/sling/cli/impl/jbake/JBakeContentUpdater.java
@@ -65,7 +65,7 @@ public class JBakeContentUpdater {
                 })
                 .collect(Collectors.toList());
 
-        Files.write(downloadsTemplatePath, updatedLines);
+        writeLines(downloadsTemplatePath, updatedLines);
 
         return new DownloadsUpdate(updated[0], otherMajor[0], 
alreadyCurrent[0]);
     }
@@ -210,7 +210,7 @@ public class JBakeContentUpdater {
 
         if (!changed) releasesLines.add(dateLineIdx + 2, "* " + releaseName + 
" " + releaseVersion + " (" + date + ")");
 
-        Files.write(releasesPath, releasesLines);
+        writeLines(releasesPath, releasesLines);
     }
 
     /**
@@ -252,7 +252,7 @@ public class JBakeContentUpdater {
             newsLines.add(firstEntryIdx, entry);
         }
 
-        Files.write(newsPath, newsLines);
+        writeLines(newsPath, newsLines);
         return true;
     }
 
@@ -269,4 +269,13 @@ public class JBakeContentUpdater {
                 return date + "th";
         }
     }
+
+    /**
+     * Writes {@code lines} with LF terminators. {@link Files#write(Path, 
Iterable)} would use the platform
+     * separator, which on Windows rewrites every line of the LF-only site 
sources and produces a whole-file
+     * diff instead of the intended change.
+     */
+    private static void writeLines(Path path, List<String> lines) throws 
IOException {
+        Files.writeString(path, String.join("\n", lines) + "\n", 
StandardCharsets.UTF_8);
+    }
 }
diff --git 
a/src/main/java/org/apache/sling/cli/impl/nexus/RepositoryService.java 
b/src/main/java/org/apache/sling/cli/impl/nexus/RepositoryService.java
index 80f7fdd..9ee49bf 100644
--- a/src/main/java/org/apache/sling/cli/impl/nexus/RepositoryService.java
+++ b/src/main/java/org/apache/sling/cli/impl/nexus/RepositoryService.java
@@ -21,6 +21,7 @@ package org.apache.sling.cli.impl.nexus;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
@@ -433,8 +434,9 @@ public class RepositoryService {
             }
             String fileName = 
relativeFilePath.substring(relativeFilePath.lastIndexOf('/') + 1);
             Path filePath = 
Files.createFile(artifactFolderPath.resolve(fileName));
-            try (InputStream content = response.getEntity().getContent()) {
-                IOUtils.copyLarge(content, Files.newOutputStream(filePath));
+            try (InputStream content = response.getEntity().getContent();
+                    OutputStream target = Files.newOutputStream(filePath)) {
+                IOUtils.copyLarge(content, target);
             }
             return true;
         }
diff --git 
a/src/test/java/org/apache/sling/cli/impl/nexus/RepositoryServiceTest.java 
b/src/test/java/org/apache/sling/cli/impl/nexus/RepositoryServiceTest.java
index 6c16afa..0234efe 100644
--- a/src/test/java/org/apache/sling/cli/impl/nexus/RepositoryServiceTest.java
+++ b/src/test/java/org/apache/sling/cli/impl/nexus/RepositoryServiceTest.java
@@ -31,6 +31,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.sling.cli.impl.CredentialsService;
@@ -143,17 +144,19 @@ public class RepositoryServiceTest {
         for (Artifact artifact : localRepository.getArtifacts()) {
             
assertTrue(Files.exists(localRepository.getRootFolder().resolve(artifact.getRepositoryRelativePath())));
         }
-        List<Path> artifactFiles = Files.walk(localRepository.getRootFolder())
-                .filter(path -> path.toFile().isFile())
-                .collect(Collectors.toList());
+        List<Path> artifactFiles;
+        try (Stream<Path> paths = Files.walk(localRepository.getRootFolder())) 
{
+            artifactFiles = 
paths.filter(Files::isRegularFile).collect(Collectors.toList());
+        }
         LOGGER.debug("Cleaning {}.", localRepository.getRootFolder());
         for (Path artifactFile : artifactFiles) {
             LOGGER.debug("Deleting file {}.", artifactFile.toString());
             Files.delete(artifactFile);
         }
-        List<Path> emptyDirectories = 
Files.walk(localRepository.getRootFolder())
-                .filter(path -> path.toFile().isDirectory())
-                .collect(Collectors.toList());
+        List<Path> emptyDirectories;
+        try (Stream<Path> paths = Files.walk(localRepository.getRootFolder())) 
{
+            emptyDirectories = 
paths.filter(Files::isDirectory).collect(Collectors.toList());
+        }
         Collections.reverse(emptyDirectories);
         for (Path directory : emptyDirectories) {
             LOGGER.debug("Deleting empty folder {}.", directory.toString());

Reply via email to