@@ -48,13 +48,21 @@ var (
4848 buildFilenames = []string {"BUILD" , "BUILD.bazel" }
4949)
5050
51- func GetActualKindName (kind string , args language.GenerateArgs ) string {
52- if kindOverride , ok := args .Config .KindMap [kind ]; ok {
53- return kindOverride .KindName
51+ // Returns the mapped kind, or kind if no mapping is configured with the map_kind directive.
52+ func getMappedKind (c * config.Config , kind string ) string {
53+ if mapped , ok := c .KindMap [kind ]; ok {
54+ return mapped .KindName
5455 }
5556 return kind
5657}
5758
59+ // kindMatches returns whether r matches the canonical Python rule kind `expected`, respecting `# gazelle:map_kind` and
60+ // `# gazelle:alias_kind` directives in the config.Config c.
61+ func kindMatches (c * config.Config , r * rule.Rule , expected string ) bool {
62+ kind := r .Kind ()
63+ return kind == getMappedKind (c , expected ) || c .AliasMap [kind ] == expected
64+ }
65+
5866func matchesAnyGlob (s string , globs []string ) bool {
5967 // This function assumes that the globs have already been validated. If a glob is
6068 // invalid, it's considered a non-match and we move on to the next pattern.
@@ -112,10 +120,6 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
112120 }
113121 }
114122
115- actualPyBinaryKind := GetActualKindName (pyBinaryKind , args )
116- actualPyLibraryKind := GetActualKindName (pyLibraryKind , args )
117- actualPyTestKind := GetActualKindName (pyTestKind , args )
118-
119123 pythonProjectRoot := cfg .PythonProjectRoot ()
120124
121125 packageName := filepath .Base (args .Dir )
@@ -296,10 +300,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
296300 sort .Strings (mainFileNames )
297301 for _ , filename := range mainFileNames {
298302 pyBinaryTargetName := strings .TrimSuffix (filepath .Base (filename ), ".py" )
299- if err := ensureNoCollision (args .File , pyBinaryTargetName , actualPyBinaryKind ); err != nil {
303+ if err := ensureNoCollision (args .Config , args . File , pyBinaryTargetName , pyBinaryKind ); err != nil {
300304 fqTarget := label .New ("" , args .Rel , pyBinaryTargetName )
301305 log .Printf ("failed to generate target %q of kind %q: %v" ,
302- fqTarget .String (), actualPyBinaryKind , err )
306+ fqTarget .String (), getMappedKind ( args . Config , pyBinaryKind ) , err )
303307 continue
304308 }
305309
@@ -334,7 +338,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
334338 }
335339 generateEmptyLibrary := false
336340 for _ , r := range args .File .Rules {
337- if r .Kind () == actualPyLibraryKind && r . Name () == pyLibraryTargetName {
341+ if r .Name () == pyLibraryTargetName && kindMatches ( args . Config , r , pyLibraryKind ) {
338342 generateEmptyLibrary = true
339343 }
340344 }
@@ -350,11 +354,11 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
350354 // exists, and if it is of a different kind from the one we are
351355 // generating. If so, we have to throw an error since Gazelle won't
352356 // generate it correctly.
353- if err := ensureNoCollision (args .File , pyLibraryTargetName , actualPyLibraryKind ); err != nil {
357+ if err := ensureNoCollision (args .Config , args . File , pyLibraryTargetName , pyLibraryKind ); err != nil {
354358 fqTarget := label .New ("" , args .Rel , pyLibraryTargetName )
355359 err := fmt .Errorf ("failed to generate target %q of kind %q: %w. " +
356360 "Use the '# gazelle:%s' directive to change the naming convention." ,
357- fqTarget .String (), actualPyLibraryKind , err , pythonconfig .LibraryNamingConvention )
361+ fqTarget .String (), getMappedKind ( args . Config , pyLibraryKind ) , err , pythonconfig .LibraryNamingConvention )
358362 collisionErrors .Add (err )
359363 }
360364
@@ -404,11 +408,11 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
404408 // exists, and if it is of a different kind from the one we are
405409 // generating. If so, we have to throw an error since Gazelle won't
406410 // generate it correctly.
407- if err := ensureNoCollision (args .File , pyBinaryTargetName , actualPyBinaryKind ); err != nil {
411+ if err := ensureNoCollision (args .Config , args . File , pyBinaryTargetName , pyBinaryKind ); err != nil {
408412 fqTarget := label .New ("" , args .Rel , pyBinaryTargetName )
409413 err := fmt .Errorf ("failed to generate target %q of kind %q: %w. " +
410414 "Use the '# gazelle:%s' directive to change the naming convention." ,
411- fqTarget .String (), actualPyBinaryKind , err , pythonconfig .BinaryNamingConvention )
415+ fqTarget .String (), getMappedKind ( args . Config , pyBinaryKind ) , err , pythonconfig .BinaryNamingConvention )
412416 collisionErrors .Add (err )
413417 }
414418
@@ -443,10 +447,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
443447 // exists, and if it is of a different kind from the one we are
444448 // generating. If so, we have to throw an error since Gazelle won't
445449 // generate it correctly.
446- if err := ensureNoCollision (args .File , conftestTargetname , actualPyLibraryKind ); err != nil {
450+ if err := ensureNoCollision (args .Config , args . File , conftestTargetname , pyLibraryKind ); err != nil {
447451 fqTarget := label .New ("" , args .Rel , conftestTargetname )
448452 err := fmt .Errorf ("failed to generate target %q of kind %q: %w. " ,
449- fqTarget .String (), actualPyLibraryKind , err )
453+ fqTarget .String (), getMappedKind ( args . Config , pyLibraryKind ) , err )
450454 collisionErrors .Add (err )
451455 }
452456
@@ -480,11 +484,11 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
480484 // exists, and if it is of a different kind from the one we are
481485 // generating. If so, we have to throw an error since Gazelle won't
482486 // generate it correctly.
483- if err := ensureNoCollision (args .File , pyTestTargetName , actualPyTestKind ); err != nil {
487+ if err := ensureNoCollision (args .Config , args . File , pyTestTargetName , pyTestKind ); err != nil {
484488 fqTarget := label .New ("" , args .Rel , pyTestTargetName )
485489 err := fmt .Errorf ("failed to generate target %q of kind %q: %w. " +
486490 "Use the '# gazelle:%s' directive to change the naming convention." ,
487- fqTarget .String (), actualPyTestKind , err , pythonconfig .TestNamingConvention )
491+ fqTarget .String (), getMappedKind ( args . Config , pyTestKind ) , err , pythonconfig .TestNamingConvention )
488492 collisionErrors .Add (err )
489493 }
490494
@@ -593,8 +597,7 @@ func (py *Python) getRulesWithInvalidSrcs(args language.GenerateArgs, validFiles
593597 return strings .HasPrefix (src , "@" ) || strings .HasPrefix (src , "//" ) || strings .HasPrefix (src , ":" )
594598 }
595599 for _ , existingRule := range args .File .Rules {
596- actualPyBinaryKind := GetActualKindName (pyBinaryKind , args )
597- if existingRule .Kind () != actualPyBinaryKind {
600+ if ! kindMatches (args .Config , existingRule , pyBinaryKind ) {
598601 continue
599602 }
600603 var hasValidSrcs bool
@@ -670,12 +673,12 @@ func isEntrypointFile(path string) bool {
670673 }
671674}
672675
673- func ensureNoCollision (file * rule.File , targetName , kind string ) error {
676+ func ensureNoCollision (c * config. Config , file * rule.File , targetName , kind string ) error {
674677 if file == nil {
675678 return nil
676679 }
677680 for _ , t := range file .Rules {
678- if t .Name () == targetName && t . Kind () != kind {
681+ if t .Name () == targetName && ! kindMatches ( c , t , kind ) {
679682 return fmt .Errorf ("a target of kind %q with the same name already exists" , t .Kind ())
680683 }
681684 }
@@ -698,7 +701,7 @@ func generateProtoLibraries(args language.GenerateArgs, cfg *pythonconfig.Config
698701 pyProtoRulesForProto := map [string ]string {}
699702 if args .File != nil {
700703 for _ , r := range args .File .Rules {
701- if r . Kind () == "py_proto_library" {
704+ if kindMatches ( args . Config , r , pyProtoLibraryKind ) {
702705 pyProtoRules [r .Name ()] = false
703706
704707 protos := r .AttrStrings ("deps" )
0 commit comments