From 6a5dae68a37f1b012399c1d9287309536fb34401 Mon Sep 17 00:00:00 2001 From: jimcody1995 Date: Mon, 6 Jul 2026 08:00:52 +0200 Subject: [PATCH] fix(signals): classify Perl and Scala protobuf stubs as generated Recognize protoc Perl *_pb.pm and Scala .pb.scala output in isGeneratedFile so generated-only diffs classify correctly for slop signals and the changed-files summary classifier dependency. Co-authored-by: Cursor --- src/signals/path-matchers.ts | 6 ++++-- test/unit/path-matchers.test.ts | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/signals/path-matchers.ts b/src/signals/path-matchers.ts index dd89572411..b259556ed3 100644 --- a/src/signals/path-matchers.ts +++ b/src/signals/path-matchers.ts @@ -78,12 +78,12 @@ function isGeneratedFileFrom(parts: NormalizedPath): boolean { // `.pb.cc` / `.pb.h`, the Swift plugin emits `.pb.swift`, the Dart plugin emits `.pb.dart`, // the Kotlin plugin emits `.pb.kt`, the C# plugin emits `.pb.cs`, the Rust plugin emits `.pb.rs`, // the Elixir plugin emits `.pb.ex`, the Erlang gpb plugin emits `.pb.erl` / `.pb.hrl`, the Crystal - // plugin emits `.pb.cr`, the Haskell plugin emits `.pb.hs`, and the Objective-C plugin emits + // plugin emits `.pb.cr`, the Haskell plugin emits `.pb.hs`, the Scala plugin emits `.pb.scala`, and the Objective-C plugin emits // `.pbobjc.{h,m}` plus gRPC `.pbrpc.{h,m}` service stubs. Swift gRPC emits sibling `.grpc.swift` // service stubs; grpc-kotlin emits sibling `*GrpcKt.kt` coroutine service stubs; grpc-java emits // sibling `*Grpc.java` service stubs. // `.pb.dart`/`.pb.kt`/`.pb.cs` (the `.pb` infix keeps hand-written sources from matching). - /\.pb\.(go|ts|js|cc|h|swift|dart|kt|cs|rs|ex|erl|hrl|cr|hs)$/.test(norm) || + /\.pb\.(go|ts|js|cc|h|swift|dart|kt|cs|rs|ex|erl|hrl|cr|hs|scala)$/.test(norm) || /\.grpc\.swift$/.test(norm) || /grpckt\.kt$/.test(norm) || /grpc\.java$/.test(norm) || @@ -100,6 +100,8 @@ function isGeneratedFileFrom(parts: NormalizedPath): boolean { /_pb\.nim$/.test(norm) || // Lua protobuf: message stubs are `*_pb.lua`. /_pb\.lua$/.test(norm) || + // Perl protobuf: message stubs are `*_pb.pm`. + /_pb\.pm$/.test(norm) || // JavaScript/TypeScript grpc-node protobuf: message stubs are `*_pb.{js,ts,d.ts}`; gRPC emits // sibling `*_grpc_pb.{js,ts,d.ts}` service stubs (underscore form, not `.pb.js`). /_pb\.(js|ts)$/.test(norm) || diff --git a/test/unit/path-matchers.test.ts b/test/unit/path-matchers.test.ts index a2aa2a2c37..f574055c29 100644 --- a/test/unit/path-matchers.test.ts +++ b/test/unit/path-matchers.test.ts @@ -153,6 +153,18 @@ describe("isGeneratedFile", () => { expect(classifyChangedFile("gen/service_pb.lua")).toBe("generated"); }); + it("matches Perl protobuf output alongside the other protoc plugins", () => { + expect(isGeneratedFile("gen/service_pb.pm")).toBe(true); + expect(isGeneratedFile("lib/MyApp.pm")).toBe(false); + expect(classifyChangedFile("gen/service_pb.pm")).toBe("generated"); + }); + + it("matches Scala protobuf output alongside the other protoc plugins", () => { + expect(isGeneratedFile("proto/messages.pb.scala")).toBe(true); + expect(isGeneratedFile("src/Main.scala")).toBe(false); + expect(classifyChangedFile("proto/messages.pb.scala")).toBe("generated"); + }); + it("matches Kotlin gRPC coroutine stubs alongside the other protoc plugins", () => { expect(isGeneratedFile("gen/GreeterGrpcKt.kt")).toBe(true); expect(isGeneratedFile("src/Greeter.kt")).toBe(false); @@ -508,6 +520,8 @@ describe("classifyChangedFile", () => { ["proto/messages.pb.hs", "generated"], ["gen/service_pb.nim", "generated"], ["gen/service_pb.lua", "generated"], + ["gen/service_pb.pm", "generated"], + ["proto/messages.pb.scala", "generated"], ["gen/GreeterGrpcKt.kt", "generated"], ["gen/GreeterGrpc.java", "generated"], ["gen/service_grpc_pb.js", "generated"],