diff --git a/src/signals/engine.ts b/src/signals/engine.ts index 9bbbec67be..16768a0877 100644 --- a/src/signals/engine.ts +++ b/src/signals/engine.ts @@ -5515,11 +5515,11 @@ function sanitizeOutcomeDimensionKey(key: string): string { } function isCodeFile(file: string): boolean { - // Mirrors isCodeFile in local-branch.ts — kept in sync (cs/swift/groovy added - // so C#/Swift/Groovy source counts as code, matching the test conventions + // Mirrors isCodeFile in local-branch.ts — kept in sync (cs/swift/groovy/php added + // so C#/Swift/Groovy/PHP source counts as code, matching the test conventions // isTestPath already recognizes). return ( - /\.(ts|tsx|mts|cts|js|jsx|mjs|cjs|py|rb|rs|kt|scala|java|go|sql|cs|swift|groovy)$/i.test(file) && + /\.(ts|tsx|mts|cts|js|jsx|mjs|cjs|py|rb|rs|kt|scala|java|go|sql|cs|swift|groovy|php)$/i.test(file) && !isTestFile(file) ); } diff --git a/src/signals/local-branch.ts b/src/signals/local-branch.ts index 98bc80ac8d..733f33afc3 100644 --- a/src/signals/local-branch.ts +++ b/src/signals/local-branch.ts @@ -1267,12 +1267,12 @@ export function isTestFile(file: string): boolean { } export function isCodeFile(file: string): boolean { - // cs/swift/groovy round out the JVM/.NET/Swift set: isTestPath already + // cs/swift/groovy/php round out the JVM/.NET/Swift/PHP set: isTestPath already // recognizes their `SomethingTest(s)`/`Spec` test files, so their source must - // count as code too — otherwise a C#/Swift/Groovy source file is neither test + // count as code too — otherwise a C#/Swift/Groovy/PHP source file is neither test // nor code in the local scorer. return ( - /\.(ts|tsx|mts|cts|js|jsx|mjs|cjs|py|rb|rs|kt|scala|java|go|sql|cs|swift|groovy)$/i.test(file) && + /\.(ts|tsx|mts|cts|js|jsx|mjs|cjs|py|rb|rs|kt|scala|java|go|sql|cs|swift|groovy|php)$/i.test(file) && !isTestFile(file) ); } diff --git a/test/unit/local-branch-file-classifiers.test.ts b/test/unit/local-branch-file-classifiers.test.ts index 04be90e767..bceda14e1e 100644 --- a/test/unit/local-branch-file-classifiers.test.ts +++ b/test/unit/local-branch-file-classifiers.test.ts @@ -122,6 +122,10 @@ describe("isCodeFile", () => { "Api/Controllers/UserController.cs", "Sources/App/Router.swift", "src/main/groovy/Pipeline.groovy", + // PHP source — isTestPath already recognizes PHPUnit/PHPSpec `SomethingTest`/`Spec` + // files, so PHP source must count as code too (else it is neither test nor code). + "app/Http/Controllers/UserController.php", + "src/Service/PaymentGateway.php", ]) { expect(isCodeFile(path)).toBe(true); } @@ -141,6 +145,8 @@ describe("isCodeFile", () => { // C#/Swift test files carry a code extension but are tests, not code. "Services/AccountTests.cs", "AppTests/LoginTests.swift", + // PHP class-suffix test file (PHPUnit) — code extension, but a test, not code. + "app/Service/PaymentTest.php", ]) { expect(isCodeFile(path)).toBe(false); }