From 9160e1ca40cb0d53a2fe03016e5b8c51a3d7f42d Mon Sep 17 00:00:00 2001 From: jimcody1995 Date: Sun, 5 Jul 2026 17:47:28 +0200 Subject: [PATCH] fix(signals): classify Haskell protobuf stubs as generated Recognize proto-lens .pb.hs output in isGeneratedFile with classifyChangedFile hot-path coverage and hand-authored negatives. Co-authored-by: Cursor --- src/signals/path-matchers.ts | 7 ++++--- test/unit/path-matchers.test.ts | 7 +++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/signals/path-matchers.ts b/src/signals/path-matchers.ts index e1953dbb8c..52eaaf72e2 100644 --- a/src/signals/path-matchers.ts +++ b/src/signals/path-matchers.ts @@ -54,10 +54,11 @@ 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`, and the Objective-C plugin emits `.pbobjc.{h,m}` plus gRPC `.pbrpc.{h,m}` - // service stubs. Swift gRPC emits sibling `.grpc.swift` service stubs. + // plugin emits `.pb.cr`, the Haskell plugin emits `.pb.hs`, and the Objective-C plugin emits + // `.pbobjc.{h,m}` plus gRPC `.pbrpc.{h,m}` service stubs. Swift gRPC emits sibling `.grpc.swift` + // 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)$/.test(norm) || + /\.pb\.(go|ts|js|cc|h|swift|dart|kt|cs|rs|ex|erl|hrl|cr|hs)$/.test(norm) || /\.grpc\.swift$/.test(norm) || /\.pbobjc\.(h|m)$/.test(norm) || /\.pbrpc\.(h|m)$/.test(norm) || diff --git a/test/unit/path-matchers.test.ts b/test/unit/path-matchers.test.ts index 8bd49bfc39..f2257ee4ea 100644 --- a/test/unit/path-matchers.test.ts +++ b/test/unit/path-matchers.test.ts @@ -120,6 +120,12 @@ describe("isGeneratedFile", () => { expect(classifyChangedFile("proto/messages.pb.cr")).toBe("generated"); }); + it("matches Haskell protobuf output alongside the other protoc plugins", () => { + expect(isGeneratedFile("proto/messages.pb.hs")).toBe(true); + expect(isGeneratedFile("src/Main.hs")).toBe(false); + expect(classifyChangedFile("proto/messages.pb.hs")).toBe("generated"); + }); + it("matches Swift protobuf, Dart freezed/retrofit, C# designer/XAML, and Objective-C protoc output", () => { for (const path of [ "proto/messages.pb.swift", @@ -446,6 +452,7 @@ describe("classifyChangedFile", () => { ["proto/messages.pb.hrl", "generated"], ["proto/messages.pb.cr", "generated"], ["dist/pkg.wasm.map", "generated"], + ["proto/messages.pb.hs", "generated"], ["vendor/lib.go", "vendored"], ["package-lock.json", "lockfile"], ["bun.lock", "lockfile"],