@@ -160,18 +160,36 @@ private static Optional<PackageResolutionResult> trySonarSources(Configuration c
160160 }
161161
162162 /**
163- * Converts relative path strings to normalized absolute paths under the given base directory.
163+ * Converts path strings to normalized absolute paths.
164+ *
165+ * <p>Relative paths are resolved against the given base directory. Windows-style absolute paths
166+ * (e.g. {@code C:\path\to\src} or {@code C:/path/to/src}) are used as-is without prepending the
167+ * base directory, which would otherwise produce a nonsensical path on non-Windows systems.
164168 *
165169 * <p>Uses {@link Path#normalize()} to resolve {@code .} and {@code ..} components without
166170 * performing any I/O, so that {@code sonar.sources=.} correctly resolves to the base directory
167171 * rather than producing an un-normalized path like {@code /project/.}.
168172 */
169173 static List <String > toAbsolutePaths (List <String > paths , File baseDir ) {
170174 return paths .stream ()
171- .map (path -> new File (baseDir , path ).toPath ().normalize ().toString ())
175+ .map (path -> {
176+ File file = isWindowsAbsolutePath (path ) ? new File (path ) : new File (baseDir , path );
177+ return file .toPath ().normalize ().toString ();
178+ })
172179 .toList ();
173180 }
174181
182+ /**
183+ * Returns {@code true} if the given path is a Windows-style absolute path (e.g. {@code C:\...}
184+ * or {@code C:/...}), regardless of the current operating system.
185+ */
186+ private static boolean isWindowsAbsolutePath (String path ) {
187+ return path .length () >= 3
188+ && Character .isLetter (path .charAt (0 ))
189+ && path .charAt (1 ) == ':'
190+ && (path .charAt (2 ) == '\\' || path .charAt (2 ) == '/' );
191+ }
192+
175193 private static List <String > findConventionalFolders (File baseDir ) {
176194 List <String > folders = new ArrayList <>();
177195 for (String folderName : CONVENTIONAL_FOLDERS ) {
@@ -186,8 +204,19 @@ private static List<String> findConventionalFolders(File baseDir) {
186204 private static List <String > adjustRoots (List <String > roots , File baseDir ) {
187205 return roots .stream ()
188206 .map (root -> {
189- File rootFile = new File (root ).isAbsolute () ? new File (root ) : new File (baseDir , root );
190- return adjustPackageRoot (rootFile , baseDir );
207+ File rootAsFile = new File (root );
208+ if (rootAsFile .isAbsolute ()) {
209+ // Native absolute path (works on any OS, including Windows running on Windows).
210+ return adjustPackageRoot (rootAsFile , baseDir );
211+ }
212+ if (isWindowsAbsolutePath (root )) {
213+ // Windows-style absolute path (e.g. C:\src) on a non-Windows system: File.isAbsolute()
214+ // returns false, so we must not pass it to new File(baseDir, root) or getAbsolutePath()
215+ // would prepend the JVM working directory. Return as-is; __init__.py traversal is not
216+ // meaningful for a foreign-OS path.
217+ return root ;
218+ }
219+ return adjustPackageRoot (new File (baseDir , root ), baseDir );
191220 })
192221 .distinct ()
193222 .toList ();
0 commit comments