Print a warning on redundant overrides

Bug: 328495189
Test: manual
Change-Id: I35bff9d6751e9aa304e4c2d7e24b9a44a3994264
diff --git a/cmd/release_config/release_config/main.go b/cmd/release_config/release_config/main.go
index 076abfa..4870f25 100644
--- a/cmd/release_config/release_config/main.go
+++ b/cmd/release_config/release_config/main.go
@@ -23,6 +23,7 @@
 
 func main() {
 	var top string
+	var quiet bool
 	var releaseConfigMapPaths rc_lib.StringList
 	var targetRelease string
 	var outputDir string
@@ -30,11 +31,16 @@
 	var configs *rc_lib.ReleaseConfigs
 
 	flag.StringVar(&top, "top", ".", "path to top of workspace")
+	flag.BoolVar(&quiet, "quiet", false, "disable warning messages")
 	flag.Var(&releaseConfigMapPaths, "map", "path to a release_config_map.textproto. may be repeated")
 	flag.StringVar(&targetRelease, "release", "trunk_staging", "TARGET_RELEASE for this build")
 	flag.StringVar(&outputDir, "out_dir", rc_lib.GetDefaultOutDir(), "basepath for the output. Multiple formats are created")
 	flag.Parse()
 
+	if quiet {
+		rc_lib.DisableWarnings()
+	}
+
 	if err = os.Chdir(top); err != nil {
 		panic(err)
 	}
diff --git a/cmd/release_config/release_config_lib/flag_artifact.go b/cmd/release_config/release_config_lib/flag_artifact.go
index 51673a5..6d8085d 100644
--- a/cmd/release_config/release_config_lib/flag_artifact.go
+++ b/cmd/release_config/release_config_lib/flag_artifact.go
@@ -64,19 +64,24 @@
 	if fa.Value.GetObsolete() {
 		return fmt.Errorf("Attempting to set obsolete flag %s. Trace=%v", name, fa.Traces)
 	}
+	var newValue *release_config_proto.Value
 	switch val := flagValue.proto.Value.Val.(type) {
 	case *release_config_proto.Value_StringValue:
-		fa.Value = &release_config_proto.Value{Val: &release_config_proto.Value_StringValue{val.StringValue}}
+		newValue = &release_config_proto.Value{Val: &release_config_proto.Value_StringValue{val.StringValue}}
 	case *release_config_proto.Value_BoolValue:
-		fa.Value = &release_config_proto.Value{Val: &release_config_proto.Value_BoolValue{val.BoolValue}}
+		newValue = &release_config_proto.Value{Val: &release_config_proto.Value_BoolValue{val.BoolValue}}
 	case *release_config_proto.Value_Obsolete:
 		if !val.Obsolete {
 			return fmt.Errorf("%s: Cannot set obsolete=false.  Trace=%v", name, fa.Traces)
 		}
-		fa.Value = &release_config_proto.Value{Val: &release_config_proto.Value_Obsolete{true}}
+		newValue = &release_config_proto.Value{Val: &release_config_proto.Value_Obsolete{true}}
 	default:
 		return fmt.Errorf("Invalid type for flag_value: %T.  Trace=%v", val, fa.Traces)
 	}
+	if proto.Equal(newValue, fa.Value) {
+		warnf("%s: redundant override (set in %s)\n", flagValue.path, *fa.Traces[len(fa.Traces)-2].Source)
+	}
+	fa.Value = newValue
 	return nil
 }
 
diff --git a/cmd/release_config/release_config_lib/util.go b/cmd/release_config/release_config_lib/util.go
index c59deb3..b04f344 100644
--- a/cmd/release_config/release_config_lib/util.go
+++ b/cmd/release_config/release_config_lib/util.go
@@ -25,6 +25,8 @@
 	"google.golang.org/protobuf/proto"
 )
 
+var disableWarnings bool
+
 type StringList []string
 
 func (l *StringList) Set(v string) error {
@@ -62,6 +64,18 @@
 	})
 }
 
+// Turn off all warning output
+func DisableWarnings() {
+	disableWarnings = true
+}
+
+func warnf(format string, args ...any) (n int, err error) {
+	if !disableWarnings {
+		return fmt.Printf(format, args...)
+	}
+	return 0, nil
+}
+
 func GetDefaultOutDir() string {
 	outEnv := os.Getenv("OUT_DIR")
 	if outEnv == "" {