diff --git a/gazelle/manifest/BUILD.bazel b/gazelle/manifest/BUILD.bazel index 2e5b6b8e99..281bcd29cf 100644 --- a/gazelle/manifest/BUILD.bazel +++ b/gazelle/manifest/BUILD.bazel @@ -5,7 +5,10 @@ go_library( srcs = ["manifest.go"], importpath = "github.com/bazelbuild/rules_python/gazelle/manifest", visibility = ["//visibility:public"], - deps = ["@in_gopkg_yaml_v2//:yaml_v2"], + deps = [ + "@com_github_emirpasic_gods//sets/treeset", + "@in_gopkg_yaml_v2//:yaml_v2", + ], ) go_test( diff --git a/gazelle/manifest/manifest.go b/gazelle/manifest/manifest.go index b92706a230..e19162bd5d 100644 --- a/gazelle/manifest/manifest.go +++ b/gazelle/manifest/manifest.go @@ -6,6 +6,8 @@ import ( "io" "os" + "github.com/emirpasic/gods/sets/treeset" + yaml "gopkg.in/yaml.v2" ) @@ -94,11 +96,30 @@ func (f *File) Decode(manifestPath string) error { return nil } +// ModulesMapping is the type used to map from importable Python modules to +// the wheel names that provide these modules. +type ModulesMapping map[string]string + +// MarshalYAML makes sure that we sort the module names before marshaling +// the contents of `ModulesMapping` to a YAML file. This ensures that the +// file is deterministically generated from the map. +func (m ModulesMapping) MarshalYAML() (interface{}, error) { + var mapslice yaml.MapSlice + keySet := treeset.NewWithStringComparator() + for key := range m { + keySet.Add(key) + } + for _, key := range keySet.Values() { + mapslice = append(mapslice, yaml.MapItem{Key: key, Value: m[key.(string)]}) + } + return mapslice, nil +} + // Manifest represents the structure of the Gazelle manifest file. type Manifest struct { // ModulesMapping is the mapping from importable modules to which Python // wheel name provides these modules. - ModulesMapping map[string]string `yaml:"modules_mapping"` + ModulesMapping ModulesMapping `yaml:"modules_mapping"` // PipDepsRepositoryName is the name of the pip_install repository target. // DEPRECATED PipDepsRepositoryName string `yaml:"pip_deps_repository_name,omitempty"` diff --git a/gazelle/manifest/manifest_test.go b/gazelle/manifest/manifest_test.go index 40a231f2bd..3b50fd1b3e 100644 --- a/gazelle/manifest/manifest_test.go +++ b/gazelle/manifest/manifest_test.go @@ -10,7 +10,7 @@ import ( "github.com/bazelbuild/rules_python/gazelle/manifest" ) -var modulesMapping = map[string]string{ +var modulesMapping = manifest.ModulesMapping{ "arrow": "arrow", "arrow.__init__": "arrow", "arrow.api": "arrow", @@ -76,4 +76,4 @@ func TestFile(t *testing.T) { t.FailNow() } }) -} \ No newline at end of file +}