Copilot commented on code in PR #2224:
URL: https://github.com/apache/maven-resolver/pull/2224#discussion_r4349954932


##########
maven-resolver-api/src/test/java/org/eclipse/aether/repository/LocalRepositoryTest.java:
##########
@@ -49,4 +54,33 @@ void allSomePaths() {
     private void doIt(File file) {
         new LocalRepository(file.toPath().toUri().toASCIIString());
     }
+
+    /**
+     * Verifies that a plain Windows path string (e.g. {@code 
C:\Users\foo\repo}) passed to
+     * {@link LocalRepository#LocalRepository(String)} preserves the drive 
letter and does not
+     * resolve against the JVM working directory. Previously, {@code 
RepositoryUriUtils.basedir()}
+     * treated the drive letter as a URL scheme and stripped it, producing a 
drive-relative path
+     * ({@code \Users\foo\repo}) that {@code Path.of(...).toUri()} then 
resolved against the JVM
+     * working directory — which can be on a different drive on Windows CI 
runners.
+     */
+    @Test
+    @EnabledOnOs(OS.WINDOWS)
+    void windowsPlainPathPreservesDriveLetter() {

Review Comment:
   Given the fix special-cases drive-letter parsing, consider adding a second 
assertion/case in this Windows test for a lowercase drive letter input (e.g., 
`c:\\...`) and/or forward-slash form (`C:/...`). This helps prevent regressions 
where drive-letter detection only works for one casing or separator style.



##########
maven-resolver-api/src/test/java/org/eclipse/aether/repository/LocalRepositoryTest.java:
##########
@@ -49,4 +54,33 @@ void allSomePaths() {
     private void doIt(File file) {
         new LocalRepository(file.toPath().toUri().toASCIIString());
     }
+
+    /**
+     * Verifies that a plain Windows path string (e.g. {@code 
C:\Users\foo\repo}) passed to
+     * {@link LocalRepository#LocalRepository(String)} preserves the drive 
letter and does not
+     * resolve against the JVM working directory. Previously, {@code 
RepositoryUriUtils.basedir()}
+     * treated the drive letter as a URL scheme and stripped it, producing a 
drive-relative path
+     * ({@code \Users\foo\repo}) that {@code Path.of(...).toUri()} then 
resolved against the JVM
+     * working directory — which can be on a different drive on Windows CI 
runners.
+     */
+    @Test
+    @EnabledOnOs(OS.WINDOWS)
+    void windowsPlainPathPreservesDriveLetter() {
+        // Use the current drive letter so the path is always valid on any 
Windows machine.
+        String currentDrive = 
Paths.get(".").toAbsolutePath().getRoot().toString(); // e.g. "C:\"
+        char driveLetter = currentDrive.charAt(0);
+        String plainPath = driveLetter + 
":\\Users\\runneradmin\\AppData\\Local\\Temp\\my-repo";
+
+        LocalRepository repo = new LocalRepository(plainPath);
+        String repoPath = repo.getBasePath().toString();

Review Comment:
   The test hard-codes a user/profile-specific subpath 
(`\\Users\\runneradmin\\...`) and later asserts full string equality. Even if 
the repository doesn’t need to exist, string round-tripping can differ due to 
normalization (separator normalization, case normalization, etc.), which risks 
flakiness across Windows environments. Prefer building the path from an 
OS-provided base (e.g., `java.io.tmpdir` / 
`Paths.get(System.getProperty(\"java.io.tmpdir\"))`) and asserting using `Path` 
equality/normalization (e.g., compare `Paths.get(plainPath)` to 
`repo.getBasePath()`), while still separately asserting the drive letter is 
preserved.



##########
maven-resolver-api/src/main/java/org/eclipse/aether/repository/RepositoryUriUtils.java:
##########
@@ -76,7 +78,15 @@ private static String basedir(String url) {
         String retValue;
 
         if (!protocol.isEmpty()) {
-            retValue = url.substring(protocol.length() + 1);
+            // A single uppercase letter is a Windows drive letter (e.g. 
"C:\path"), not a URL scheme.
+            // Keep it in the path; do not strip it as if it were a protocol 
prefix.
+            if (protocol.length() == 1
+                    && Character.isLetter(protocol.charAt(0))
+                    && Character.isUpperCase(protocol.charAt(0))) {
+                retValue = url;
+            } else {
+                retValue = url.substring(protocol.length() + 1);
+            }
         } else {

Review Comment:
   Drive-letter detection is currently limited to *uppercase* single-letter 
prefixes. Windows paths can be provided as `c:\\...` as well; in that case this 
code will still treat `c` as a URL scheme and strip the drive letter 
(reintroducing the original bug). Consider detecting drive letters by pattern 
(e.g., `^[A-Za-z]:[\\\\/].*`) rather than `isUpperCase`, and apply the same 
predicate consistently in both `basedir()` and the `toUri()` protocol-branch 
condition.



##########
maven-resolver-api/src/test/java/org/eclipse/aether/repository/LocalRepositoryTest.java:
##########
@@ -49,4 +54,33 @@ void allSomePaths() {
     private void doIt(File file) {
         new LocalRepository(file.toPath().toUri().toASCIIString());
     }
+
+    /**
+     * Verifies that a plain Windows path string (e.g. {@code 
C:\Users\foo\repo}) passed to
+     * {@link LocalRepository#LocalRepository(String)} preserves the drive 
letter and does not
+     * resolve against the JVM working directory. Previously, {@code 
RepositoryUriUtils.basedir()}
+     * treated the drive letter as a URL scheme and stripped it, producing a 
drive-relative path
+     * ({@code \Users\foo\repo}) that {@code Path.of(...).toUri()} then 
resolved against the JVM
+     * working directory — which can be on a different drive on Windows CI 
runners.
+     */
+    @Test
+    @EnabledOnOs(OS.WINDOWS)
+    void windowsPlainPathPreservesDriveLetter() {
+        // Use the current drive letter so the path is always valid on any 
Windows machine.
+        String currentDrive = 
Paths.get(".").toAbsolutePath().getRoot().toString(); // e.g. "C:\"
+        char driveLetter = currentDrive.charAt(0);
+        String plainPath = driveLetter + 
":\\Users\\runneradmin\\AppData\\Local\\Temp\\my-repo";
+
+        LocalRepository repo = new LocalRepository(plainPath);
+        String repoPath = repo.getBasePath().toString();
+
+        // The resolved path must start with the same drive letter, not a 
different one.
+        assertEquals(
+                String.valueOf(driveLetter),
+                repoPath.substring(0, 1).toUpperCase(),
+                "Drive letter must be preserved when parsing a plain Windows 
path: " + repoPath);

Review Comment:
   `String#toUpperCase()` is locale-sensitive; in uncommon locales this can 
produce unexpected results for certain letters. Since this is a single 
character comparison, prefer a locale-independent approach (e.g., 
`Character.toUpperCase(...)`) or use `toUpperCase(Locale.ROOT)` to keep the 
assertion deterministic.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to