Skip to content

Commit 4e62826

Browse files
Fix package resolution for non-Java source files (#7356)
1 parent 81641f9 commit 4e62826

2 files changed

Lines changed: 32 additions & 9 deletions

File tree

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/source/index/PackageResolverImpl.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@
88
import java.nio.file.InvalidPathException;
99
import java.nio.file.Path;
1010
import javax.annotation.Nullable;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
1113

1214
public class PackageResolverImpl implements PackageResolver {
1315

16+
private static final Logger log = LoggerFactory.getLogger(PackageResolverImpl.class);
17+
1418
private static final String PACKAGE_KEYWORD = "package";
1519
private final FileSystem fileSystem;
1620

@@ -33,6 +37,7 @@ public PackageResolverImpl(FileSystem fileSystem) {
3337
@Nullable
3438
@Override
3539
public Path getPackage(Path sourceFile) throws IOException {
40+
Language language = Language.getByFileName(sourceFile.getFileName().toString());
3641
Path folder = sourceFile.getParent();
3742
try (BufferedReader br = Files.newBufferedReader(sourceFile)) {
3843
String line;
@@ -42,6 +47,13 @@ public Path getPackage(Path sourceFile) throws IOException {
4247
continue;
4348
}
4449

50+
int charAfterPackageKeyword = packageDeclarationStart + PACKAGE_KEYWORD.length();
51+
if (charAfterPackageKeyword >= line.length()
52+
|| !Character.isWhitespace(line.charAt(charAfterPackageKeyword))) {
53+
// "package" keyword is not followed by a whitespace
54+
continue;
55+
}
56+
4557
int lineLength = line.length();
4658
int packageNameStart = packageDeclarationStart + PACKAGE_KEYWORD.length();
4759
while (packageNameStart < lineLength
@@ -51,18 +63,21 @@ public Path getPackage(Path sourceFile) throws IOException {
5163

5264
int packageNameEnd = line.indexOf(';', packageNameStart);
5365
if (packageNameEnd == -1) {
54-
packageNameEnd = lineLength; // no ';' is possible if this is a Groovy file
66+
packageNameEnd = lineLength; // possible if this is a non-Java (e.g. Groovy, Scala) file
5567
}
5668

5769
String packageName = line.substring(packageNameStart, packageNameEnd);
5870
Path packagePath;
5971
try {
6072
packagePath = fileSystem.getPath(packageName.replace('.', File.separatorChar));
6173
} catch (InvalidPathException e) {
74+
log.debug("Invalid package {} found for source file {}", packageName, sourceFile, e);
6275
continue;
6376
}
6477

65-
if (folder.endsWith(packagePath)) {
78+
// we only do the "sanity check" for Java, as with the other languages
79+
// it is possible to have package that does not correspond to folder
80+
if (language != Language.JAVA || folder.endsWith(packagePath)) {
6681
return packagePath;
6782
}
6883
}

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/source/index/RepoIndexBuilder.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
157157
}
158158

159159
Path sourceRoot =
160-
language.isNonCode() ? getNonCodeSourceRoot(file) : getCodeSourceRoot(file);
160+
language.isNonCode() ? getNonCodeSourceRoot(file) : getCodeSourceRoot(language, file);
161161
if (sourceRoot != null) {
162162
String relativeSourceRoot = repoRoot.relativize(sourceRoot).toString();
163163
int sourceRootIdx =
@@ -177,19 +177,27 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
177177
return FileVisitResult.CONTINUE;
178178
}
179179

180-
private Path getCodeSourceRoot(Path file) throws IOException {
180+
private Path getCodeSourceRoot(Language language, Path file) throws IOException {
181181
indexingStats.sourceFilesVisited++;
182182
Path packagePath = packageResolver.getPackage(file);
183183
if (packagePath != null) {
184184
packageTree.add(packagePath);
185185

186186
Path folder = file.getParent();
187-
// remove package path suffix from folder path to get source root
188-
return folder
189-
.getRoot()
190-
.resolve(folder.subpath(0, folder.getNameCount() - packagePath.getNameCount()));
187+
if (folder.endsWith(packagePath)) {
188+
// In non-JVM languages package names do not have to correspond to folder structure,
189+
// so using package to find source root is not always possible
190+
return folder
191+
.getRoot()
192+
.resolve(folder.subpath(0, folder.getNameCount() - packagePath.getNameCount()));
193+
}
194+
}
195+
196+
if (language != Language.JAVA) {
197+
// Fallback for non-JVM languages
198+
return resourceResolver.getResourceRoot(file);
191199
} else {
192-
// assuming default package
200+
// For Java assuming default package
193201
return file.getParent();
194202
}
195203
}

0 commit comments

Comments
 (0)