Skip to content

Conversation

@bbadour
Copy link

@bbadour bbadour commented Nov 21, 2025

Use delegation to implement the Value+Flag paradigm used for other flag types.

Implement all of the Flag interfaces except Count.

Borrowed heavily from flag_bool.go and flag_generic.go

Add context to the error message when setting an external flag's value to its default value to avoid cryptic error messages like: "syntax error: expected file.go:234"

And suppress the error for odd-ball external flags that report the string representation of the zero-value of some structure as the default, but do not accept that string as input. Detect such odd-balls by their Get() method returning nil.

What type of PR is this?

  • feature

What this PR does / why we need it:

Solve:

  • cryptic error messages like "syntax error: expected flag.go:234"
  • errors requiring external boolean flags have a value when used
  • avoidable astonishment when AllowExtFlags flags behave differently from identical flags defined using urfave/cli

Which issue(s) this PR fixes:

Fixes #2225

Testing

Installed gfmrun and make passes. Also the same code passes the test cases for a large code base that uses the feature.

Release Notes

Improve support for `AllowExtFlags`

Use delegation to implement the Value+Flag paradigm used for other flag
types.

Implement all of the Flag interfaces except Count.

Borrowed heavily from flag_bool.go and flag_generic.go

Add context to the error message when setting an external flag's value
to its default value to avoid cryptic error messages like:
`"syntax error: expected file.go:234"`

And suppress the error for odd-ball external flags that report the
string representation of the zero-value of some structure as the
default, but do not accept that string as input. Detect such odd-balls
by their `Get()` method returning `nil`.
@bbadour bbadour requested a review from a team as a code owner November 21, 2025 20:48
}

func (e *extFlag) IsSet() bool {
return false
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Migrating some code from v1, I found this could be less astonishing if, instead, it were:

        if e == nil || e.f == nil || e.f.Value == nil {
                return false
        }
        return e.f.Value.String() != e.f.DefValue

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually you can set a flag in the "extFlag.Set()" method and check that here.

if e.f.DefValue != "" {
return e.Set("", e.f.DefValue)
// suppress errors for write-only external flags that always return nil
if err := e.Set("", e.f.DefValue); err != nil && e.f.Value.(flag.Getter).Get() != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if err := e.Set("", e.f.DefValue); err != nil && e.f.Value.(flag.Getter).Get() != nil {
if err := e.Set("", e.f.DefValue); err != nil {

do you need the Get() != nil check ?

}

// IsDefaultVisible returns true if the flag is not hidden, otherwise false
func (e *extFlag) IsDefaultVisible() bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this dependent on the DefaultValue ? similar to flag library?

}

// RunAction executes flag action if set
func (e *extFlag) RunAction(ctx context.Context, cmd *Command) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you dont need to define this method. interface casting will check if Flag is an ActionableFlag and call accordingly

Copy link
Contributor

@dearchap dearchap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bbadour Can you add some more tests ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve AllowExtFlags robustness

2 participants