@@ -131,63 +131,102 @@ func GetGeneratedFiles(protoFile, projectDir, modulePath string, hasGo, hasTS bo
131131 return files
132132}
133133
134- // FindGeneratedFilesForProto finds actual generated files for a proto file using glob .
135- func FindGeneratedFilesForProto (protoFile , projectDir , vendorDir , modulePath string ) ([]string , error ) {
134+ // FindGeneratedFilesForProto finds actual enabled outputs for a proto file.
135+ func FindGeneratedFilesForProto (protoFile , projectDir , vendorDir , modulePath string , langs Languages ) ([]string , error ) {
136136 protoDir := filepath .Dir (protoFile )
137137 baseName := strings .TrimSuffix (filepath .Base (protoFile ), ".proto" )
138138
139- // Search in local proto directory first (preferred location)
140- localPattern := filepath .Join (projectDir , protoDir , baseName + "*.pb.*" )
141- localMatches , err := filepath .Glob (localPattern )
142- if err != nil {
143- return nil , err
139+ var csharpBase strings.Builder
140+ capNext := true
141+ for i := range len (baseName ) {
142+ c := baseName [i ]
143+ switch {
144+ case c >= 'a' && c <= 'z' :
145+ if capNext {
146+ c -= 'a' - 'A'
147+ }
148+ csharpBase .WriteByte (c )
149+ capNext = false
150+ case c >= 'A' && c <= 'Z' :
151+ csharpBase .WriteByte (c )
152+ capNext = false
153+ case c >= '0' && c <= '9' :
154+ csharpBase .WriteByte (c )
155+ capNext = true
156+ default :
157+ capNext = true
158+ }
144159 }
145-
146- // Also check vendor symlink path
147- searchDir := filepath .Join (vendorDir , modulePath , protoDir )
148- vendorMatches , err := filepath .Glob (filepath .Join (searchDir , baseName + "*.pb.*" ))
149- if err != nil {
150- return nil , err
160+ csharpFile := csharpBase .String ()
161+ if csharpFile != "" && csharpFile [0 ] >= '0' && csharpFile [0 ] <= '9' &&
162+ strings .HasPrefix (baseName , "_" ) {
163+ csharpFile = "_" + csharpFile
151164 }
152165
153- // Deduplicate by resolving to real paths
154- // Prefer non-vendor paths over vendor paths (they may be symlinked to the same file)
155- seen := make (map [string ]string ) // realPath -> relativePath
166+ var relativePatterns []string
167+ if langs .Has (LanguageCpp ) {
168+ relativePatterns = append (relativePatterns , baseName + ".pb.cc" , baseName + ".pb.h" )
169+ }
170+ if langs .Has (LanguageGo ) {
171+ relativePatterns = append (relativePatterns , baseName + "*.pb.go" )
172+ }
173+ if langs .Has (LanguageTypeScript ) {
174+ relativePatterns = append (relativePatterns , baseName + "*.pb.ts" )
175+ }
176+ if langs .Has (LanguageRust ) {
177+ relativePatterns = append (relativePatterns , baseName + "*.pb.rs" )
178+ }
179+ if langs .Has (LanguagePython ) {
180+ relativePatterns = append (relativePatterns , baseName + "_pb2.py" , baseName + "_pb2.pyi" )
181+ }
156182
157- // Process local matches first (preferred)
158- for _ , m := range localMatches {
159- rel , err := filepath .Rel (projectDir , m )
160- if err != nil {
161- rel = m
162- }
163- realPath , err := filepath .EvalSymlinks (m )
164- if err != nil {
165- realPath = m
166- }
167- seen [realPath ] = rel
183+ searches := []struct {
184+ dir string
185+ patterns []string
186+ }{
187+ {dir : filepath .Join (projectDir , protoDir ), patterns : relativePatterns },
188+ {dir : filepath .Join (vendorDir , modulePath , protoDir ), patterns : relativePatterns },
189+ }
190+ if langs .Has (LanguageCSharp ) {
191+ searches = append (searches , struct {
192+ dir string
193+ patterns []string
194+ }{
195+ dir : projectDir ,
196+ patterns : []string {csharpFile + ".cs" },
197+ })
168198 }
169199
170- // Process vendor matches, only add if not already seen
171- for _ , m := range vendorMatches {
172- realPath , err := filepath .EvalSymlinks (m )
173- if err != nil {
174- realPath = m
175- }
176- if _ , exists := seen [realPath ]; ! exists {
177- rel , err := filepath .Rel (projectDir , m )
200+ // Deduplicate by resolving to real paths. Prefer project-local paths over
201+ // their vendor-symlink aliases.
202+ seen := make (map [string ]string )
203+ for _ , search := range searches {
204+ for _ , pattern := range search .patterns {
205+ matches , err := filepath .Glob (filepath .Join (search .dir , pattern ))
178206 if err != nil {
179- rel = m
207+ return nil , err
208+ }
209+ for _ , match := range matches {
210+ realPath , err := filepath .EvalSymlinks (match )
211+ if err != nil {
212+ realPath = match
213+ }
214+ if _ , exists := seen [realPath ]; exists {
215+ continue
216+ }
217+ rel , err := filepath .Rel (projectDir , match )
218+ if err != nil {
219+ rel = match
220+ }
221+ seen [realPath ] = rel
180222 }
181- seen [realPath ] = rel
182223 }
183224 }
184225
185- // Collect results and sort for deterministic output.
186226 relPaths := make ([]string , 0 , len (seen ))
187227 for _ , rel := range seen {
188228 relPaths = append (relPaths , rel )
189229 }
190230 slices .Sort (relPaths )
191-
192231 return relPaths , nil
193232}
0 commit comments