ronantakizawa/codereview-bench huggingface dataset:
Repository: etcd-io/etcd
File: server/etcdserver/server_test.go (Go)

Code before:
			Index:     11, // magic number
			Term:      11, // magic number
			ConfState: raftpb.ConfState{Voters: []uint64{1, 2, 3}},
		},
	})
	s := &EtcdServer{
		lgMu:         new(sync.RWMutex),
		lg:           lg,
		r:            *r,
		v2store:      st,
		cluster:      cl,
		reqIDGen:     idutil.NewGenerator(0, time.Time{}),
		SyncTicker:   &time.Ticker{},
		consistIndex: cindex.NewFakeConsistentIndex(0),
		beHooks:      serverstorage.NewBackendHooks(lg, nil),
	}
	// Mock a mad switch dispatching messages to wrong node.
	m := raftpb.Message{
		Type:   raftpb.MsgHeartbeat,
		To:     2, // Wrong ID.
		From:   3,
		Term:   11,
		Commit: 42, // Commit is larger than the last index.
	}
	if types.ID(m.To) == s.MemberId() {
		t.Fatalf("To must mismatch")
	}
	err := s.Process(context.Background(), m)
	if err == nil {
		t.Fatalf("Must ignore the message and return an error")
	}
}

// TestRemoveMember tests RemoveMember can propose and perform node removal.
func TestRemoveMember(t *testing.T) {
	lg := zaptest.NewLogger(t)
	n := newNodeConfChangeCommitterRecorder()
	n.readyc <- raft.Ready{
		SoftState: &raft.SoftState{RaftState: raft.StateLeader},
	}
	cl := newTestCluster(t)
	st := v2store.New()
	cl.SetStore(v2store.New())
	be, _ := betesting.NewDefaultTmpBackend(t)
	cl.SetBackend(schema.NewMembershipBackend(lg, be))

	cl.AddMember(&membership.Member{ID: 1234}, true)
	r := newRaftNode(raftNodeConfig{
		lg:          lg,
		Node:        n,
		raftStorage: raft.NewMemoryStorage(),

Review comment (suggestion):
```suggestion
		t.Fatalf("m.To (%d) is expected to mismatch m.memberId (%d)", m.To, s.MemberId())
```

Code after:
		Metadata: raftpb.SnapshotMetadata{
			Index: 11, // Magic number.
			Term:  11, // Magic number.
			ConfState: raftpb.ConfState{
				// Member ID list.
				Voters: []uint64{1, 2, 3},
			},
		},
	})
	s := &EtcdServer{
		lgMu:         new(sync.RWMutex),
		lg:           lg,
		memberId:     1,
		r:            *r,
		v2store:      st,
		cluster:      cl,
		reqIDGen:     idutil.NewGenerator(0, time.Time{}),
		SyncTicker:   &time.Ticker{},
		consistIndex: cindex.NewFakeConsistentIndex(0),
		beHooks:      serverstorage.NewBackendHooks(lg, nil),
	}
	// Mock a mad switch dispatching messages to wrong node.
	m := raftpb.Message{
		Type:   raftpb.MsgHeartbeat,
		To:     2, // Wrong ID, s.MemberId() is 1.
		From:   3,
		Term:   11,
		Commit: 42, // Commit is larger than the last index 11.
	}
	if types.ID(m.To) == s.MemberId() {
		t.Fatalf("m.To (%d) is expected to mismatch s.MemberId (%d)", m.To, s.MemberId())
	}
	err := s.Process(context.Background(), m)
	if err == nil {
		t.Fatalf("Must ignore the message and return an error")
	}
}

// TestRemoveMember tests RemoveMember can propose and perform node removal.
func TestRemoveMember(t *testing.T) {
	lg := zaptest.NewLogger(t)
	n := newNodeConfChangeCommitterRecorder()
	n.readyc <- raft.Ready{
		SoftState: &raft.SoftState{RaftState: raft.StateLeader},
	}
	cl := newTestCluster(t)
	st := v2store.New()
	cl.SetStore(v2store.New())
	be, _ := betesting.NewDefaultTmpBackend(t)
	cl.SetBackend(schema.NewMembershipBackend(lg, be))
Repository: etcd-io/etcd
File: etcdserver/api/membership/cluster_test.go (Go)

Code before:
			currentVersion: "3.4.0",
			localVersion:   "3.4.0",
			expectedResult: false,
		},
		{
			name:           "When local version is one patch higher than cluster version",
			currentVersion: "3.4.0",
			localVersion:   "3.4.1",
			expectedResult: false,
		},
		{
			name:                         "When local version is two minor lower than cluster version",
			currentVersion:               "3.6.0",
			localVersion:                 "3.4.0",
			nextClusterVersionCompatible: true,
			expectedResult:               false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			currentVersion := semver.Must(semver.NewVersion(tt.currentVersion))
			localVersion := semver.Must(semver.NewVersion(tt.localVersion))
			if ret := IsValidVersionChange(currentVersion, localVersion, tt.nextClusterVersionCompatible); ret != tt.expectedResult {
				t.Errorf("Expected %v; Got %v", tt.expectedResult, ret)
			}
		})
	}
}

func TestDetectDowngrade(t *testing.T) {
	tests := []struct {
		clusterVersion               string
		nextClusterVersionCompatible bool
		expectErr                    bool
	}{
		{
			expectErr: false,
		},
		{
			clusterVersion: "3.5.0",
			expectErr:      true,
		},
		{
			clusterVersion:               "3.5.0",
			nextClusterVersionCompatible: true,
			expectErr:                    false,
		},
		{
			clusterVersion: "3.6.0",
			expectErr:      true,

Review comment (suggestion):
```suggestion
			ret := IsValidVersionChange(currentVersion, localVersion, tt.nextClusterVersionCompatible)	
			assert.Equal(t, tt.expectedResult, ret)
```

Code after:
			name:           "When local version is equal to cluster version",
			verFrom:        "3.4.0",
			verTo:          "3.4.0",
			expectedResult: false,
		},
		{
			name:           "When local version is one patch higher than cluster version",
			verFrom:        "3.4.0",
			verTo:          "3.4.1",
			expectedResult: false,
		},
		{
			name:                         "When local version is two minor lower than cluster version",
			verFrom:                      "3.6.0",
			verTo:                        "3.4.0",
			nextClusterVersionCompatible: true,
			expectedResult:               false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			verFrom := semver.Must(semver.NewVersion(tt.verFrom))
			verTo := semver.Must(semver.NewVersion(tt.verTo))
			ret := IsValidClusterVersionChange(verFrom, verTo, tt.nextClusterVersionCompatible)
			assert.Equal(t, tt.expectedResult, ret)
		})
	}
}

func TestDetectDowngrade(t *testing.T) {
	tests := []struct {
		clusterVersion               string
		nextClusterVersionCompatible bool
		expectErr                    bool
	}{
		{
			expectErr: false,
		},
		{
			clusterVersion: "3.5.0",
			expectErr:      true,
		},
		{
			clusterVersion:               "3.5.0",
			nextClusterVersionCompatible: true,
			expectErr:                    false,
		},
		{
			clusterVersion: "3.6.0",
			expectErr:      true,
Repository: etcd-io/etcd
File: tests/framework/e2e/etcd_process.go (Go)

Code before:
func (f *BinaryFailpoints) SetupHTTP(ctx context.Context, failpoint, payload string) error {
	host := fmt.Sprintf("127.0.0.1:%d", f.member.Config().GoFailPort)
	failpointURL := url.URL{
		Scheme: "http",
		Host:   host,
		Path:   failpoint,
	}
	r, err := http.NewRequestWithContext(ctx, "PUT", failpointURL.String(), bytes.NewBuffer([]byte(payload)))
	if err != nil {
		return err
	}
	httpClient := http.Client{
		Timeout: 1 * time.Second,
	}
	if f.clientTimeout != 0 {
		httpClient.Timeout = f.clientTimeout
	}
	resp, err := httpClient.Do(r)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusNoContent {
		errMsg, err := io.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		return fmt.Errorf("bad status code: %d (%v)", resp.StatusCode, errMsg)
	}
	return nil
}

func (f *BinaryFailpoints) DeactivateHTTP(ctx context.Context, failpoint string) error {
	host := fmt.Sprintf("127.0.0.1:%d", f.member.Config().GoFailPort)
	failpointURL := url.URL{
		Scheme: "http",
		Host:   host,
		Path:   failpoint,
	}
	r, err := http.NewRequestWithContext(ctx, "DELETE", failpointURL.String(), nil)
	if err != nil {
		return err
	}
	httpClient := http.Client{
		// TODO: Decrease after deactivate is not blocked by sleep https://github.com/etcd-io/gofail/issues/64
		Timeout: 2 * time.Second,
	}
	if f.clientTimeout != 0 {
		httpClient.Timeout = f.clientTimeout
	}
	resp, err := httpClient.Do(r)

Review comment (suggestion):
return statusCode here as well? `fmt.Errorf("bad status code: %d (%v)", resp.StatusCode, err)`

Code after:
func (f *BinaryFailpoints) SetupHTTP(ctx context.Context, failpoint, payload string) error {
	host := fmt.Sprintf("127.0.0.1:%d", f.member.Config().GoFailPort)
	failpointURL := url.URL{
		Scheme: "http",
		Host:   host,
		Path:   failpoint,
	}
	r, err := http.NewRequestWithContext(ctx, "PUT", failpointURL.String(), bytes.NewBuffer([]byte(payload)))
	if err != nil {
		return err
	}
	httpClient := http.Client{
		Timeout: 1 * time.Second,
	}
	if f.clientTimeout != 0 {
		httpClient.Timeout = f.clientTimeout
	}
	resp, err := httpClient.Do(r)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusNoContent {
		errMsg, err := io.ReadAll(resp.Body)
		if err != nil {
			return fmt.Errorf("bad status code: %d, err: %w", resp.StatusCode, err)
		}
		return fmt.Errorf("bad status code: %d, err: %s", resp.StatusCode, errMsg)
	}
	return nil
}

func (f *BinaryFailpoints) DeactivateHTTP(ctx context.Context, failpoint string) error {
	host := fmt.Sprintf("127.0.0.1:%d", f.member.Config().GoFailPort)
	failpointURL := url.URL{
		Scheme: "http",
		Host:   host,
		Path:   failpoint,
	}
	r, err := http.NewRequestWithContext(ctx, "DELETE", failpointURL.String(), nil)
	if err != nil {
		return err
	}
	httpClient := http.Client{
		// TODO: Decrease after deactivate is not blocked by sleep https://github.com/etcd-io/gofail/issues/64
		Timeout: 2 * time.Second,
	}
	if f.clientTimeout != 0 {
		httpClient.Timeout = f.clientTimeout
	}
	resp, err := httpClient.Do(r)
Repository: etcd-io/etcd
File: tests/framework/e2e/etcd_process.go (Go)

Code before:
}

func (f *BinaryFailpoints) SetupHTTP(ctx context.Context, failpoint, payload string) error {
	host := fmt.Sprintf("127.0.0.1:%d", f.member.Config().GoFailPort)
	failpointURL := url.URL{
		Scheme: "http",
		Host:   host,
		Path:   failpoint,
	}
	r, err := http.NewRequestWithContext(ctx, "PUT", failpointURL.String(), bytes.NewBuffer([]byte(payload)))
	if err != nil {
		return err
	}
	httpClient := http.Client{
		Timeout: 1 * time.Second,
	}
	if f.clientTimeout != 0 {
		httpClient.Timeout = f.clientTimeout
	}
	resp, err := httpClient.Do(r)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusNoContent {
		errMsg, err := io.ReadAll(resp.Body)
		if err != nil {
			return fmt.Errorf("bad status code: %d (%v)", resp.StatusCode, err)
		}
		return fmt.Errorf("bad status code: %d (%v)", resp.StatusCode, errMsg)
	}
	return nil
}

func (f *BinaryFailpoints) DeactivateHTTP(ctx context.Context, failpoint string) error {
	host := fmt.Sprintf("127.0.0.1:%d", f.member.Config().GoFailPort)
	failpointURL := url.URL{
		Scheme: "http",
		Host:   host,
		Path:   failpoint,
	}
	r, err := http.NewRequestWithContext(ctx, "DELETE", failpointURL.String(), nil)
	if err != nil {
		return err
	}
	httpClient := http.Client{
		// TODO: Decrease after deactivate is not blocked by sleep https://github.com/etcd-io/gofail/issues/64
		Timeout: 2 * time.Second,
	}
	if f.clientTimeout != 0 {
		httpClient.Timeout = f.clientTimeout

Review comment (bug):
Currently `gofail PUT` doesn't return any data in the body. So can we keep it unchanged for simplicity?

Code after:
}

func (f *BinaryFailpoints) SetupHTTP(ctx context.Context, failpoint, payload string) error {
	host := fmt.Sprintf("127.0.0.1:%d", f.member.Config().GoFailPort)
	failpointURL := url.URL{
		Scheme: "http",
		Host:   host,
		Path:   failpoint,
	}
	r, err := http.NewRequestWithContext(ctx, "PUT", failpointURL.String(), bytes.NewBuffer([]byte(payload)))
	if err != nil {
		return err
	}
	httpClient := http.Client{
		Timeout: 1 * time.Second,
	}
	if f.clientTimeout != 0 {
		httpClient.Timeout = f.clientTimeout
	}
	resp, err := httpClient.Do(r)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusNoContent {
		errMsg, err := io.ReadAll(resp.Body)
		if err != nil {
			return fmt.Errorf("bad status code: %d, err: %w", resp.StatusCode, err)
		}
		return fmt.Errorf("bad status code: %d, err: %s", resp.StatusCode, errMsg)
	}
	return nil
}

func (f *BinaryFailpoints) DeactivateHTTP(ctx context.Context, failpoint string) error {
	host := fmt.Sprintf("127.0.0.1:%d", f.member.Config().GoFailPort)
	failpointURL := url.URL{
		Scheme: "http",
		Host:   host,
		Path:   failpoint,
	}
	r, err := http.NewRequestWithContext(ctx, "DELETE", failpointURL.String(), nil)
	if err != nil {
		return err
	}
	httpClient := http.Client{
		// TODO: Decrease after deactivate is not blocked by sleep https://github.com/etcd-io/gofail/issues/64
		Timeout: 2 * time.Second,
	}
	if f.clientTimeout != 0 {
		httpClient.Timeout = f.clientTimeout
Repository: etcd-io/etcd
File: tests/framework/e2e/etcd_process.go (Go)

Code before:
	failpointURL := url.URL{
		Scheme: "http",
		Host:   host,
		Path:   failpoint,
	}
	r, err := http.NewRequestWithContext(ctx, "PUT", failpointURL.String(), bytes.NewBuffer([]byte(payload)))
	if err != nil {
		return err
	}
	httpClient := http.Client{
		Timeout: 1 * time.Second,
	}
	if f.clientTimeout != 0 {
		httpClient.Timeout = f.clientTimeout
	}
	resp, err := httpClient.Do(r)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusNoContent {
		errMsg, err := io.ReadAll(resp.Body)
		if err != nil {
			return fmt.Errorf("bad status code: %d (%v)", resp.StatusCode, err)
		}
		return fmt.Errorf("bad status code: %d (%v)", resp.StatusCode, errMsg)
	}
	return nil
}

func (f *BinaryFailpoints) DeactivateHTTP(ctx context.Context, failpoint string) error {
	host := fmt.Sprintf("127.0.0.1:%d", f.member.Config().GoFailPort)
	failpointURL := url.URL{
		Scheme: "http",
		Host:   host,
		Path:   failpoint,
	}
	r, err := http.NewRequestWithContext(ctx, "DELETE", failpointURL.String(), nil)
	if err != nil {
		return err
	}
	httpClient := http.Client{
		// TODO: Decrease after deactivate is not blocked by sleep https://github.com/etcd-io/gofail/issues/64
		Timeout: 2 * time.Second,
	}
	if f.clientTimeout != 0 {
		httpClient.Timeout = f.clientTimeout
	}
	resp, err := httpClient.Do(r)
	if err != nil {
		return err

Review comment (suggestion):
I think we should use `string(errMsg)` here becasue `errMsg` is `[]byte`. It's not human-friendly.

Code after:
	failpointURL := url.URL{
		Scheme: "http",
		Host:   host,
		Path:   failpoint,
	}
	r, err := http.NewRequestWithContext(ctx, "PUT", failpointURL.String(), bytes.NewBuffer([]byte(payload)))
	if err != nil {
		return err
	}
	httpClient := http.Client{
		Timeout: 1 * time.Second,
	}
	if f.clientTimeout != 0 {
		httpClient.Timeout = f.clientTimeout
	}
	resp, err := httpClient.Do(r)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusNoContent {
		errMsg, err := io.ReadAll(resp.Body)
		if err != nil {
			return fmt.Errorf("bad status code: %d, err: %w", resp.StatusCode, err)
		}
		return fmt.Errorf("bad status code: %d, err: %s", resp.StatusCode, errMsg)
	}
	return nil
}

func (f *BinaryFailpoints) DeactivateHTTP(ctx context.Context, failpoint string) error {
	host := fmt.Sprintf("127.0.0.1:%d", f.member.Config().GoFailPort)
	failpointURL := url.URL{
		Scheme: "http",
		Host:   host,
		Path:   failpoint,
	}
	r, err := http.NewRequestWithContext(ctx, "DELETE", failpointURL.String(), nil)
	if err != nil {
		return err
	}
	httpClient := http.Client{
		// TODO: Decrease after deactivate is not blocked by sleep https://github.com/etcd-io/gofail/issues/64
		Timeout: 2 * time.Second,
	}
	if f.clientTimeout != 0 {
		httpClient.Timeout = f.clientTimeout
	}
	resp, err := httpClient.Do(r)
	if err != nil {
		return err
Repository: etcd-io/etcd
File: pkg/cobrautl/help.go (Go)

Code before:
			format = format + "=%q"
		} else {
			format = format + "=%s"
		}
		if len(flag.NoOptDefVal) > 0 {
			format = format + "]"
		}
		format = format + "\t%s\n"
		shorthand := flag.Shorthand
		fmt.Fprintf(x, format, shorthand, flag.Name, flag.DefValue, flag.Usage)
	})

	return x.String()
}

func getSubCommands(cmd *cobra.Command) []*cobra.Command {
	var subCommands []*cobra.Command
	for _, subCmd := range cmd.Commands() {
		subCommands = append(subCommands, subCmd)
		subCommands = append(subCommands, getSubCommands(subCmd)...)
	}
	return subCommands
}

// Deprecated: Please use go.etcd.io/etcd/etcdctl/v3/util instead.
func UsageFunc(cmd *cobra.Command, version, APIVersion string) error {
	subCommands := getSubCommands(cmd)
	tabOut := getTabOutWithWriter(os.Stdout)
	commandUsageTemplate.Execute(tabOut, struct {
		Cmd         *cobra.Command
		LocalFlags  string
		GlobalFlags string
		SubCommands []*cobra.Command
		Version     string
		APIVersion  string
	}{
		cmd,
		etcdFlagUsages(cmd.LocalFlags()),
		etcdFlagUsages(cmd.InheritedFlags()),
		subCommands,
		version,
		APIVersion,
	})
	tabOut.Flush()
	return nil
}

func getTabOutWithWriter(writer io.Writer) *tabwriter.Writer {
	aTabOut := new(tabwriter.Writer)
	aTabOut.Init(writer, 0, 8, 1, '\t', 0)
	return aTabOut

Review comment (suggestion):
The linter error is complaining that the comment isn't starting with `UsageFunc`
```suggestion
// UsageFunc is the usage function for the cobra command.
// Deprecated: Please use the UsageFunc in go.etcd.io/etcd/etcdctl/v3/util instead.
```

Code after:
			format = format + "=%q"
		} else {
			format = format + "=%s"
		}
		if len(flag.NoOptDefVal) > 0 {
			format = format + "]"
		}
		format = format + "\t%s\n"
		shorthand := flag.Shorthand
		fmt.Fprintf(x, format, shorthand, flag.Name, flag.DefValue, flag.Usage)
	})

	return x.String()
}

func getSubCommands(cmd *cobra.Command) []*cobra.Command {
	var subCommands []*cobra.Command
	for _, subCmd := range cmd.Commands() {
		subCommands = append(subCommands, subCmd)
		subCommands = append(subCommands, getSubCommands(subCmd)...)
	}
	return subCommands
}

// UsageFunc is the usage function for the cobra command.
// Deprecated: Please use go.etcd.io/etcd/etcdctl/v3/util instead.
func UsageFunc(cmd *cobra.Command, version, APIVersion string) error {
	subCommands := getSubCommands(cmd)
	tabOut := getTabOutWithWriter(os.Stdout)
	commandUsageTemplate.Execute(tabOut, struct {
		Cmd         *cobra.Command
		LocalFlags  string
		GlobalFlags string
		SubCommands []*cobra.Command
		Version     string
		APIVersion  string
	}{
		cmd,
		etcdFlagUsages(cmd.LocalFlags()),
		etcdFlagUsages(cmd.InheritedFlags()),
		subCommands,
		version,
		APIVersion,
	})
	tabOut.Flush()
	return nil
}

func getTabOutWithWriter(writer io.Writer) *tabwriter.Writer {
	aTabOut := new(tabwriter.Writer)
	aTabOut.Init(writer, 0, 8, 1, '\t', 0)
Repository: etcd-io/etcd
File: server/etcdmain/config.go (Go)

Code before:

// getBoolFlagVal returns the value of the a given bool flag is explicitly set in the cmd line arguments,
// and returns nil if it is not explicitly set.
func (cfg *config) getBoolFlagVal(flagName string) *bool {
	explicitlySet := false
	cfg.cf.flagSet.Visit(func(f *flag.Flag) {
		if f.Name == flagName {
			explicitlySet = true
		}
	})
	if !explicitlySet {
		return nil
	}
	flagVal, parseErr := strconv.ParseBool(cfg.cf.flagSet.Lookup(flagName).Value.String())
	if parseErr != nil {
		panic(parseErr)
	}
	return &flagVal
}

func (cfg *config) configFromFile(path string) error {
	eCfg, err := embed.ConfigFromFile(path)
	if err != nil {
		return err
	}
	// TODO: remove after adding feature-gates field in the config file.
	if eCfg.ExperimentalStopGRPCServiceOnDefrag {
		eCfg.ServerFeatureGate.(featuregate.MutableFeatureGate).Set("StopGRPCServiceOnDefrag=true")
	}
	cfg.ec = *eCfg

	return nil
}

func (cfg *config) validate() error {
	if cfg.cf.fallback.String() == fallbackFlagProxy {
		return fmt.Errorf("v2 proxy is deprecated, and --discovery-fallback can't be configured as %q", fallbackFlagProxy)
	}
	return cfg.ec.Validate()
}

func (cfg *config) parseWarningUnaryRequestDuration() (time.Duration, error) {
	if cfg.ec.ExperimentalWarningUnaryRequestDuration != 0 && cfg.ec.WarningUnaryRequestDuration != 0 {
		return 0, errors.New(
			"both --experimental-warning-unary-request-duration and --warning-unary-request-duration flags are set. " +
				"Use only --warning-unary-request-duration")
	}

	if cfg.ec.WarningUnaryRequestDuration != 0 {
		return cfg.ec.WarningUnaryRequestDuration, nil
	}

Review comment (suggestion):
This was missed in your previous PR, I would suggest to get this resolved firstly. 

This PR is already a followup PR, let's try not add too much followup PR in the chain.

Code after:
	return cfg.validate()
}

func (cfg *config) configFromFile(path string) error {
	eCfg, err := embed.ConfigFromFile(path)
	if err != nil {
		return err
	}
	cfg.ec = *eCfg

	return nil
}

func (cfg *config) validate() error {
	if cfg.cf.fallback.String() == fallbackFlagProxy {
		return fmt.Errorf("v2 proxy is deprecated, and --discovery-fallback can't be configured as %q", fallbackFlagProxy)
	}
	return cfg.ec.Validate()
}

func (cfg *config) parseWarningUnaryRequestDuration() (time.Duration, error) {
	if cfg.ec.ExperimentalWarningUnaryRequestDuration != 0 && cfg.ec.WarningUnaryRequestDuration != 0 {
		return 0, errors.New(
			"both --experimental-warning-unary-request-duration and --warning-unary-request-duration flags are set. " +
				"Use only --warning-unary-request-duration")
	}

	if cfg.ec.WarningUnaryRequestDuration != 0 {
		return cfg.ec.WarningUnaryRequestDuration, nil
	}

	if cfg.ec.ExperimentalWarningUnaryRequestDuration != 0 {
		cfg.ec.GetLogger().Warn(
			"--experimental-warning-unary-request-duration is deprecated, and will be decommissioned in v3.7. " +
				"Use --warning-unary-request-duration instead.")
		return cfg.ec.ExperimentalWarningUnaryRequestDuration, nil
	}

	return embed.DefaultWarningUnaryRequestDuration, nil
}
Repository: etcd-io/etcd
File: pkg/flags/flag.go (Go)

Code before:
				return fmt.Errorf("invalid value %q for %s: %v", val, key, serr)
			}
			if log && lg != nil {
				lg.Info(
					"recognized and used environment variable",
					zap.String("variable-name", key),
					zap.String("variable-value", val),
				)
			}
		}
	}
	return nil
}

func IsSet(fs *flag.FlagSet, name string) bool {
	set := false
	fs.Visit(func(f *flag.Flag) {
		if f.Name == name {
			set = true
		}
	})
	return set
}

// GetBoolFlagVal returns the value of the a given bool flag is explicitly set in the cmd line arguments,
// and returns nil if it is not explicitly set.
func GetBoolFlagVal(fs *flag.FlagSet, flagName string) (*bool, error) {
	if !IsSet(fs, flagName) {
		return nil, nil
	}
	flagVal, parseErr := strconv.ParseBool(fs.Lookup(flagName).Value.String())
	if parseErr != nil {
		return nil, parseErr
	}
	return &flagVal, nil
}


Review comment (suggestion):
```suggestion
// GetBoolFlagVal returns the value of the a given bool flag if it is explicitly set
// in the cmd line arguments, otherwise returns nil.
```

Code after:
				return fmt.Errorf("invalid value %q for %s: %v", val, key, serr)
			}
			if log && lg != nil {
				lg.Info(
					"recognized and used environment variable",
					zap.String("variable-name", key),
					zap.String("variable-value", val),
				)
			}
		}
	}
	return nil
}

func IsSet(fs *flag.FlagSet, name string) bool {
	set := false
	fs.Visit(func(f *flag.Flag) {
		if f.Name == name {
			set = true
		}
	})
	return set
}

// GetBoolFlagVal returns the value of the a given bool flag if it is explicitly set
// in the cmd line arguments, otherwise returns nil.
func GetBoolFlagVal(fs *flag.FlagSet, flagName string) (*bool, error) {
	if !IsSet(fs, flagName) {
		return nil, nil
	}
	flagVal, parseErr := strconv.ParseBool(fs.Lookup(flagName).Value.String())
	if parseErr != nil {
		return nil, parseErr
	}
	return &flagVal, nil
}