-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
String slice issue v1 #981
Conversation
Codecov Report
@@ Coverage Diff @@
## v1 #981 +/- ##
==========================================
+ Coverage 71.65% 72.24% +0.58%
==========================================
Files 30 30
Lines 2410 2490 +80
==========================================
+ Hits 1727 1799 +72
- Misses 577 581 +4
- Partials 106 110 +4
Continue to review full report at Codecov.
|
bump |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pausing review here because I think this PR might not be approaching the fix in the ideal way. Right now, we'd be accepting that the new values are getting appended incorrectly, and then removing the default based on their string representation after the fact, rather than preventing them from getting incorrectly joined in the first place.
The bigger issue I see is that there's already code to handle removing the defaults—this is in master:
Lines 22 to 26 in cae7b0c
func (s *StringSlice) Set(value string) error { | |
if !s.hasBeenSet { | |
s.slice = []string{} | |
s.hasBeenSet = true | |
} |
This means on the first setting of a slice flag, we should in theory be zeroing out the value. I'm not sure why that's not working (or no longer working, if it used to), but I think the better fix would be to address that issue at the root rather than patch it downstream on flag lookup.
flag_int64_slice.go
Outdated
return parsed | ||
} | ||
return nil | ||
} | ||
|
||
func removeFromInt64Slice(slice []int64, val int64) (newVal []int64) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: We shouldn't be using named returns unless the function signature is ambiguous, or we absolutely have to
There are caveats with the scope of a named variable that aren't always intuitive, and naked returns pretty much always obfuscate what code should be doing. It also encourages us to mutate an existing variable rather than returning directly.
I'd probably write the function like this:
func removeFromInt64Slice(slice []int64, val int64) ([]int64) {
for i, v := range slice {
if v == val {
return slice[count+1:]
}
}
return slice
}
That said, there's an issue here, which I'm not sure if is intentional or not. This function removes all items up to and including the first occurrence of val
, but the name implies that we would just be removing val
. I don't think it manifests because of how this function is called, but we should either fix the implementation or rename the function to avoid future misuse of this helper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have updated the function to behave like it's named
func removeFromInt64Slice(slice []int64, val int64) []int64 {
for i, v := range slice {
if v == val {
return append(slice[:i], slice[i+1:]...)
}
}
return slice
}
See it in action: https://play.golang.org/p/ZjJxp38tKNQ
I agree with your comment but unfortunately, this is right now not possible in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for missing it earlier, I was definitely comparing this change to what we had in master
rather than v1
.
Looks pretty good, just a couple small notes.
- Add check for blank default value - Reduce indentation of code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
||
func isInt64SliceEqual(newValue, defaultValue []int64) bool { | ||
// If one is nil, the other must also be nil. | ||
if (newValue == nil) != (defaultValue == nil) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the first time I every see an expression like this in golang. 👀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woooooooooah, love it!
Since urfave/cli v1.22.3, string flag no longer persists the default value if the flag is explicitly initialized. Please refer to urfave/cli#981. Signed-off-by: Derek Su <derek.su@suse.com>
Since urfave/cli v1.22.3, string flag no longer persists the default value if the flag is explicitly initialized. Please refer to urfave/cli#981. Signed-off-by: Derek Su <derek.su@suse.com>
Since urfave/cli v1.22.3, string flag no longer persists the default value if the flag is explicitly initialized. Please refer to urfave/cli#981. Signed-off-by: Derek Su <derek.su@suse.com>
Motivation
Fixes #790
The issue describes a bug where the default values of a
Slice
type flag persist even after the user explicitly sets the flag. Consider the following code:Suppose, we execute this code using
--Hostnames a.b.c --Hostnames e.f.g
, we would expect thec.StringSlice("Hostnames")
function to return aStringSlice
with length equal to 2 and containinga.b.c
ande.f.g
. As of writing this PR, the call toc.StringSlice("Hostnames")
returns aStringSlice
with length equal to 3 and containinglocalhost
,a.b.c
ande.f.g
. This behavior is incorrect.The same behavior can be replicated in the
IntSliceFlag
andInt64SliceFlag
also. This PR aims to fix this inconsistency.Release Notes
[BUG FIX] String flag no longer persists the default value if the flag is explicitly initialized.
Changes
flag_int64_slice.go
: UpdatelookupInt64Slice
function to extract default values of the flag and then subsequently remove them.flag_int_slice.go
: UpdatelookupIntSlice
function to extract default values of the flag and then subsequently remove them.flag_string_slice.go
: UpdatelookupStringSlice
function to extract default values of the flag and then subsequently remove them.flag_test.go
: Add unit tests.Testing
Unit tests are added to cover the following scenarios: