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
feat: .usage() can now be used to configure a default command #975
Conversation
CC: @laggingreflex |
I haven't tried this code (yet), though in API it seems to match the example you gave yesterday, without the requirement to include the word 'command'. I think that, for new users, who are just wanting to make a simple single command that accepts positional arguments, this looks pretty-much ideal :-). |
Yep, this looks like exactly what I’d love for one of my single command CLIs :) |
@lostintangent @matatk if you want to take it for a spin, and give me some feedback before it goes live:
|
@bcoe Just pulled down the This is probably a dumb question, but it there a way to replace the highlighted text with It would be awesome if the |
Also, I noticed that if I define some additional global settings (e.g. aliases for the For optimizing the syntax for single-command CLIs, it would be awesome to be able to write the following: const { filePath } = require("yargs")
.usage(
"$0 [filePath] [options]",
"Start a new co-editing editing session",
yargs => {
yargs
.positional("filePath", {
describe: "The file path to begin collaborating on"
})
.alias({ h: "help", v: "version" })
.strict()
.fail(exit);
}
)
.parse(); Functionally, this seems to actually work beautifully. It's just that the help output isn't the same as when writing it this way: const { filePath } = require("yargs")
.usage(
"$0 [filePath] [options]",
"Start a new co-editing editing session",
yargs => {
yargs.positional("filePath", {
describe: "The file path to begin collaborating on"
});
}
)
.fail(exit)
.strict()
.alias({ h: "help", v: "version" }); I'm not entirely sure whether this method is actually "good" or not, and I'm happy with writing the code either way. I just thought I'd mention it since the CLI seems to be functionally equivalent in both scenarios, but the help text is different (and therefore may be a bug?). |
@bcoe I noticed that the file path behavior is completely unrelated to this PR, though I wasn't experiencing it previously since my usage of I opened up #983 as one potential "solution" to allowing the use of That said, the fact that the string literal |
regarding $0 behavior: @lostintangent my home was that the string literal regarding difference in output top-level vs. nested configuration: Testing, I think the problem might just be that you're missing const { filePath } = require("./")
.usage(
"$0 [filePath] [options]",
"Start a new co-editing editing session",
yargs => {
yargs.positional("filePath", {
describe: "The file path to begin collaborating on"
});
}
)
.fail(exit)
.strict()
.alias({ h: "help", v: "version" })
.parse() I seem to have the same output (mind confirming?). |
@bcoe Yeah that's a good point regarding displaying Regarding the other issue, I actually was calling const { filePath } = require("./")
.usage(
"$0 [filePath] [options]",
"Start a new co-editing editing session",
yargs => {
yargs.positional("filePath", {
describe: "The file path to begin collaborating on"
})
.fail(exit)
.strict()
.alias({ h: "help", v: "version" })
}
)
.parse() In my case, the |
So, if I were a consumer of a binary written with yargs and I saw |
@iarna @lostintangent does it feel less weird to replace it with Commands:
. [filePath] [options] start a new co-editing session/ |
@lostintangent regarding the behavior around test.js test.js [filePath] [options]
Positionals:
filePath The file path to begin collaborating on
Options:
-h, --help Show help [boolean]
-v, --version Show version number [boolean] rather than this? test.js [filePath] [options]
Commands:
$0 [filePath] [options] Start a new co-editing editing session [default]
Positionals:
filePath The file path to begin collaborating on
Options:
-h, --help Show help [boolean]
-v, --version Show version number [boolean] I don't think this behavior is a bug per-se (or it's at least expected). Basically, we needed to make some usability decisions around how to display help for all commands, vs. help for a default command ($0). It's hard to get this perfect but it's my hope we've reached an okay compromise with the behavior:
I wonder, is there anywhere in the docs we could call this out? |
@bcoe Ah OK, the behavior makes sense now that I think about it. Thanks for explaining that! I was a little confused initially since I have a CLI that is literally just a single command. Therefore, I wasn’t thinking of there being a difference between the top-level help and the command-level help. In fact, in the single-command CLI, maybe the “buggy” behavior is in fact my expected behavior, since you don’t neccesssarily need the top-level help (which then coincidentally gets around the “$0” conversation as well). Maybe we could just add a quick mention to the new “usage” method docs, that clarifies that the builder function is configuring the default command’s help output, not the top-level CLI’s help output? That would have been helpful in my case. Additionally, there may be some bugs in the default command’s help output, such as the script/bin name being displayed twice in the usage text (see screenshot above)? Regarding the “.” vs. “$0” display: I definitely think “.” is less strange looking, but I’m still not 100% sure. Is there any prior art we could take inspiration from here? When I look at Zeit’s now CLI (for example), their help output doesn’t display a special token for the default command since they also alias it as “deploy” and can just annotate it as also being the default (that’s nice and clean). Though their docs display the default command as “[]”, which I think I like better than “.” (since the brackets represent optional arcs, and we’re not trying to overload the dot)? |
@lostintangent if
I'm wondering if perhaps:
How are you linking the |
I like that proposal! For #1, would the “.” even be displayed if you added an alias for the default command? If not, then this behavior would seem to accommodate most scenarios really well. I’m using “yarn link”, so this totally might be a dev-only issue. I’ll check an end-user install when I get home and will report back if it still repros. |
@lostintangent figured out why now I'm working on getting fixing how we display command information; my coworkers gave me a prety good suggestion today, which was that we display the command like so:
|
@bcoe Awesome! That sounds good. |
BREAKING CHANGE: .usage() no longer accepts an options object as the second argument
@bcoe I tried out the latest changes, and can confirm that the double script name display issue is resolved! However, I noticed that the "usage description" in the command-level help now only seems to display the bin name name (e..g If I view the top-level help, the usage text is displayed correctly (note that my |
@lostintangent whoops, definitely had a somewhat screwed up release/merge with your work there. I think I've fixed the bugs in question, I've also modified things so that if there's only a default command configured, you'll see the help for this command rather than the top-level help. Thanks for all your help testing this new feature. |
@lostintangent Have you tried
Do we want the |
@wKovacs64 as long as your application is linked, rather than being run locally, I think you'll find that the {
"bin": "./my-app.js"
} Then run Did you like where I put the command description in the help output? I thought that having it to the left of the command seemed appropriate, and matched git's help. |
@bcoe That's what I was testing, my package.json looks just like that and I've linked it globally. The output includes the Edit: Oh. It's a Windows thing. Looks fine on macOS. |
@wKovacs64 @lostintangent @iarna it took another couple days of coding, but I think I've pulled together all your suggestions into a new usage format that I'm happy with: when multiple commands are configured: when a single root-level command is configured: You can try things out by running |
I don't see the |
Looks awesome! Thanks so much @bcoe. |
@wKovacs64 This is the repro of it working for me: https://gist.github.com/iarna/65a1f94660ad8240519698062e2faf88 You can |
@bcoe the new output formats look great; thanks. It seems to me that, for a CLI with no (sub-)commands, the line "the default command that is run" seems unnecessary, and possibly confusing, as there aren no commands. Other than that, this is exactly what I was hoping for; thanks! |
@iarna Your repro example outputs |
@wKovacs64 I would expect |
@matatk "the default command that is run" is just the description of the command as provided by the developer. If you don't want anything there, you don't provide a description. |
@iarna Ah, okay. When you said you didn't see the |
This pull allows you to configure the default command (your application's entry point) in the
.usage()
method -- combining the usage and command APIs in a way that I feel is more intuitive.Along with introducing this standardization, there have been a few cosmetic changes in an effort to make default commands (and commands in general) more intuitive:
BREAKING CHANGE: .usage() no longer accepts an options object as the second argument
would love feedback, CC: @matatk, @jeffijoe