fix(skills): address QA round 13

QA13-1: Strip inline trailing comments when scanning dependency/build
files so comment-only mentions of fastapi or spring-boot no longer emit
synthetic framework markers.

QA13-2: Detect Spring Boot in Gradle version-catalog alias setups by
including libs.versions.toml in the scan and matching spring.boot /
spring-boot alias patterns as well as org.springframework.boot.

Add regression tests for:
- FastAPI inline comments
- Android inline spring-boot comments
- Spring Boot version-catalog alias detection
This commit is contained in:
Derek Pearson 2026-03-22 08:16:20 -04:00
parent c297fe2e34
commit 73bd5d9331
2 changed files with 49 additions and 5 deletions

View file

@ -435,7 +435,10 @@ export function detectProjectSignals(basePath: string): ProjectSignals {
}
const springBootFiles = scannedFiles.filter((file) =>
file.endsWith("pom.xml") || file.endsWith("build.gradle") || file.endsWith("build.gradle.kts"),
file.endsWith("pom.xml") ||
file.endsWith("build.gradle") ||
file.endsWith("build.gradle.kts") ||
file.endsWith("libs.versions.toml"),
);
if (containsDependencyMarker(basePath, springBootFiles, "spring-boot")) {
pushUnique(detectedFiles, "dep:spring-boot");
@ -773,7 +776,7 @@ function containsDependencyMarker(basePath: string, relativePaths: string[], mar
if (marker === "fastapi" && /\bfastapi(?:[-_][a-z0-9]+)?\b/.test(content)) {
return true;
}
if (marker === "spring-boot" && /(org\.springframework\.boot|spring-boot(?:-starter)?)/.test(content)) {
if (marker === "spring-boot" && /(org\.springframework\.boot|spring[-.]boot(?:[-.]starter)?)/.test(content)) {
return true;
}
} catch {
@ -786,10 +789,10 @@ function containsDependencyMarker(basePath: string, relativePaths: string[], mar
function stripDependencyComments(relativePath: string, content: string): string {
if (relativePath.endsWith("requirements.txt")) {
return content.replace(/^\s*#.*$/gm, "");
return content.replace(/(^|\s)#.*$/gm, "");
}
if (relativePath.endsWith("pyproject.toml")) {
return content.replace(/^\s*#.*$/gm, "");
return content.replace(/(^|\s)#.*$/gm, "");
}
if (relativePath.endsWith("pom.xml")) {
return content.replace(/<!--[\s\S]*?-->/g, "");
@ -797,7 +800,7 @@ function stripDependencyComments(relativePath: string, content: string): string
if (relativePath.endsWith("build.gradle") || relativePath.endsWith("build.gradle.kts")) {
return content
.replace(/\/\*[\s\S]*?\*\//g, "")
.replace(/^\s*\/\/.*$/gm, "");
.replace(/\/\/.*$/gm, "");
}
return content;
}

View file

@ -793,6 +793,17 @@ test("detectProjectSignals: FastAPI comments do not trigger dep:fastapi", () =>
}
});
test("detectProjectSignals: FastAPI inline comments do not trigger dep:fastapi", () => {
const dir = makeTempDir("signals-fastapi-inline-comment");
try {
writeFileSync(join(dir, "requirements.txt"), "flask==3.0 # maybe fastapi later\n", "utf-8");
const signals = detectProjectSignals(dir);
assert.ok(!signals.detectedFiles.includes("dep:fastapi"), "inline comments should not trigger FastAPI detection");
} finally {
cleanup(dir);
}
});
test("detectProjectSignals: Django project does NOT get dep:fastapi marker", () => {
const dir = makeTempDir("signals-django-no-fastapi");
try {
@ -870,3 +881,33 @@ test("detectProjectSignals: Android Gradle project does not emit dep:spring-boot
cleanup(dir);
}
});
test("detectProjectSignals: Android inline comments do not emit dep:spring-boot", () => {
const dir = makeTempDir("signals-android-inline-comment");
try {
writeFileSync(join(dir, "build.gradle"), "plugins { id 'com.android.application' } // spring-boot maybe later", "utf-8");
mkdirSync(join(dir, "app"), { recursive: true });
writeFileSync(join(dir, "app", "build.gradle"), "plugins { id 'com.android.application' }", "utf-8");
const signals = detectProjectSignals(dir);
assert.ok(!signals.detectedFiles.includes("dep:spring-boot"), "inline comments should not trigger Spring Boot detection");
} finally {
cleanup(dir);
}
});
test("detectProjectSignals: Spring Boot version-catalog alias emits dep:spring-boot", () => {
const dir = makeTempDir("signals-spring-version-catalog");
try {
mkdirSync(join(dir, "gradle"), { recursive: true });
writeFileSync(join(dir, "build.gradle.kts"), "plugins { alias(libs.plugins.spring.boot) }", "utf-8");
writeFileSync(
join(dir, "gradle", "libs.versions.toml"),
"[plugins]\nspring-boot = { id = 'org.springframework.boot', version = '3.2.0' }\n",
"utf-8",
);
const signals = detectProjectSignals(dir);
assert.ok(signals.detectedFiles.includes("dep:spring-boot"), "should detect Spring Boot via version-catalog alias");
} finally {
cleanup(dir);
}
});