Comments (23)
I am changing labels on this issue to target v3, because that's what the code in the issue uses. I think this issue was classified as v2 by mistake.
I also reworded the issue a bit.
from cli.
No problem :) That's okay.
Would you like to make an open-source contribution? More specifically:
- You fork
urfave/cli
- You fix the bug in
urfave/cli
you described (so BoolWithInverseFlag will display correctly as--[no-]summary
in--help
) - You submit a Pull Request in this GitHub repository with the bugfix.
This is what I mean. I hope it's easier to understand now.
Ah, and I don't want you to do anything. I'm only asking.
from cli.
@Skeeve yes that is the current behavior, you are using the BoolWithInverseFlag correctly. I think what you want is the output to have "--no-summary" on a different line correct ? You might be able to modify the help template to get what you want. Let me take a look and see what can be done.
from cli.
Yes. On a different line and with a different text.
from cli.
@Skeeve, would this be OK for you? This is how Dart's package:args
does this, and I quite like it:
NAME:
sendsomething - report some stuff
USAGE:
sendsomething [global options] [arguments...]
GLOBAL OPTIONS:
--verbose, -v Show more output. (default: false)
--dry-run, --dryrun, -d Do a dry-run. (default: false)
--to value [ --to value ] Define alternative recipients.
--[no-]summary Only send the summary. (default: false)
--help, -h show help (default: false)
The problem with your example in the issue is: where to define the second Usage
string? You mention:
"Only send the summary."
for--summary
"Suppress the default summary."
for--no-summary
but currently BoolWithInverseFlag
only accepts a single Usage
.
But your use case seems that semantically, you have 3 actions for "summary": "suppress the default summary", something in the middle, and "only send the summary". If this is the case then I'm afraid BoolWithInverseFlag
won't help you.
from cli.
You are right with your assumption.
--summary
: send only the summary, i.e. suppress the other mails--no-summary
: send no summary, i.e. send only the other mails- none of them: Send everything
So I think I have to stick with defining two flags.
But to answer your question: I think, that option would be better than what cli has now.
from cli.
Would you be up to submit a Pull Request with a fix?
from cli.
Would you be up to submit a Pull Request with a fix?
I didn't change anything in cli, so no. I cannot submit a pull request. It's just that I define two normal bool flags in my program.
from cli.
Yeah yeah – I meant "are you willing to modify urfave/cli code that fixes how help is displayed?".
from cli.
Sorry, I don't get it. I'm not a native speaker, so I think I need more explanation what you want me to do.
from cli.
Okay. Understood. Will think about it. I will try to find some time on Sunday to look into that. Will be a good training in understanding GO for me.
from cli.
@bartekpacia I thought a bit about it and in fact, I wouldn't need to define two variables as the BoolWithInversFlag already has three states:
https://play.golang.com/p/MetA6KyQmM_f
- not set
- set to true
- set to false
which is exactly what I want. Remains the issue: how to define different texts. But I think this is just a case of proper wording.
Additionally the (default: false)
shouldn't be shown in the help unless a default was explicitly set.
If that's okay with you, I'll try my luck ;) at coding it.
from cli.
That's an interesting find. If it solves your problem, that's great.
But I'm not sure if it's "the way" to solve this problem – I think it's no longer "declarative" then.
Maybe a new BoolWithInverseFlag
(or OptionalBool
?) function should be created to allow for retrieval of the information you need:
Example
package main
import (
"context"
"fmt"
cli "github.com/urfave/cli/v3"
)
func main() {
cmd := &cli.Command{
Flags: []cli.Flag{
&cli.BoolWithInverseFlag{
BoolFlag: &cli.BoolFlag{
Name: "env",
},
},
},
Action: func(_ context.Context, cmd *cli.Command) error {
var value *bool
value = cmd.BoolWithInverse("env")
if value != nil {
if value {
fmt.Println("env is set to true")
} else {
fmt.Println("env is set to false")
}
} else {
fmt.Println("env is not set")
}
return nil
},
}
_ = cmd.Run(context.Background(), []string{"prog"})
_ = cmd.Run(context.Background(), []string{"prog", "--no-env"})
_ = cmd.Run(context.Background(), []string{"prog", "--env"})
fmt.Println("flags:", len(flagWithInverse.Flags()))
}
If that's okay with you, I'll try my luck ;) at coding it.
Sure! This is an open-source project, the more people submit fixes (even small ones), the better for everyone.
from cli.
I think it's no longer "declarative" then.
Why? What bothers you? That the default should only be shown if a default is set? To me this seems quite logical.
Or is there anything else which doesn't feel right for you?
from cli.
Maybe a new BoolWithInverseFlag (or OptionalBool?) function should be created to allow for retrieval of the information you need
The current BoolFlag already has all the information I need.
- You provide the flag -> The value will be
true
andiISet()
will be true - You do not provide the flag -> The value will be
false
andIsSet()
will befalse
My understanding of the BoolWithInverseFlag is, that it only provides a third option:
- You provide the negative flag -> The value will be
false
andIsSet()
will be true
If the bool is a counter, the value will be a positive or negative number depending on the amount of times it was given. Maybe even 0 if positive and negative were given the same number of times.
I had a quick look at BoolWithInverseFlag but couldn't understand the implementation fully. To me it seems as if it simply combines two BoolFlags which is, I think, overvomplicated. I think a simple Bool would do. The only difference is, that the cli parser needs to know that the negative switch needs to be taken into account.
from cli.
P.S. Can you please educate me on how to run tests? Maybe the question sounds dumb, but I'm still new to go.
from cli.
@Skeeve, thank you very much for looking into the code and sharing your thoughts. Indeed I think something may be wrong – maybe we don't need BoolWithInverseFlag
at all? v3 is still in alpha, so we can still change it.
Can you please educate me on how to run tests? Maybe the question sounds dumb, but I'm still new to go.
Sure! To run all tests in all packages in the directory, do:
go test ./...
But in case of urfave/cli
, which is only a single package, you can do this:
go test .
I hope it helps :) See also this StackOverflow answer. If you have any more questions just ask!
from cli.
maybe we don't need BoolWithInverseFlag at all? v3 is still in alpha, so we can still change it.
I do think so, provided it's okay if every BoolFlag has a negative counterpart.
On the other hand:
Maybe the config options WithInverse bool
and an optional InverseUsage string
for BoolFag
could solve what I found.
If WithInverse
is true, the flag has an inverse. Otherwise it will be the same as the current BoolFlag
.
If InverseUsage
is defined, it gives the usage text for the --no-
flag.
We need to also allow the simultaneous use of --no-env
and --env
. I think it makes sense given that default values for flags can be set via config file or environment. So having --no-env
as a default config defined, it would be possible to use --env
on the commandline.
from cli.
Yes, I agree with almost everything that you wrote above. I'm curious what other maintainers think.
One thing I don't agree with is this:
We need to also allow the simultaneous use of --no-env and --env.
At first glance, it seems illogical to me.
from cli.
At first glance, it seems illogical to me.
Didn‘t my argument make any sense? About having an environment variable or a default config file defining (for example) —env
while you want to have —no-env
in the call?
from cli.
In general, arguments/flags passed as arguments on the command-line are given higher priority than the ones in the config file. So in your example, I'd expect --env
from the config file to be ignored, and only --no-env
to be taken into account.
Frankly, I've never used altsrc
with urfave/cli, so I'm not experienced with it. Maybe you could show an example of what you mean?
from cli.
Frankly, I've never used altsrc with urfave/cli, so I'm not experienced with it. Maybe you could show an example of what you mean?
Me neither. But if what you say is true, then I think my arguments don’t count.
from cli.
I'm curious what other maintainers think.
So how do we find out?
from cli.
Related Issues (20)
- Wrong help output when a Command has "HideHelpCommand=true" but no defined subcommands
- DefaultCommand does not work when defined on a sub-Command HOT 9
- subcommand help did show global options. HOT 1
- Shell completions are broken when login shell is different than currently active shell
- Use mkdocs `mike` for multi-version docs
- Strictly limit default dependencies to stdlib HOT 6
- Build out all of the v3 documentation
- Vendor usage of `github.com/xrash/smetrics` for suggestions HOT 2
- Delete stale branches HOT 5
- Use gofumpt
- Man page generation feature is not documented anywhere HOT 3
- Doc generation default value set by environment variable HOT 4
- Expose shell completions scripts in by default in the `completion` command HOT 5
- More powerful shell completion HOT 2
- Ensure `go mod tidy` works as expected HOT 1
- Target `stable` and `oldstable` in main CI
- Flags are alphabetically sorted when using categories HOT 3
- Should I expect completion of nested command's flags to work? HOT 31
- AfterFunc execution details HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cli.