Skip to content
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

Could have error() output to stderr? #997

Closed
crystalfp opened this issue Jul 18, 2019 · 17 comments
Closed

Could have error() output to stderr? #997

crystalfp opened this issue Jul 18, 2019 · 17 comments
Milestone

Comments

@crystalfp
Copy link

I have a command line application with the output redirected to a file.

node app.js mandatory-argument > output.dat

If mandatory-argument is not present, commander help() function is called. Unfortunately the help text goes to the output file due to the redirection. In the commander source file, the help output is hardcoded to go to stdout (line 1147).

A workaround is to call help() this way:

	const cb = (hlpText: string): string => {
		process.stderr.write(hlpText);
		return "";
	};
	program.help(cb);

But should be simpler if all commander messages go to stderr and not to stdout.
Thanks for looking!
mario

@shadowspawn
Copy link
Collaborator

@cengizhanbasak
Copy link

If you like me to do, I'll change the stdout to stderr.

@crystalfp
Copy link
Author

Yes, please.

@shadowspawn
Copy link
Collaborator

@crystalfp Are you displaying the help yourself? Or is Commander displaying the help when you call .parse?

@crystalfp
Copy link
Author

It is commander that displays the help.
I had to add the following code to display help when the program is called without arguments:


	// To send the help text to stderr
	const cb = (hlpText: string): string => {
		process.stderr.write(hlpText);
		return "";
	};
	program.help(cb);

@shadowspawn
Copy link
Collaborator

shadowspawn commented Oct 5, 2019

That isn't a bad work-around.

When using git-style executable subcommands, the help gets displayed automatically when there are no arguments (unless there is a default command). I was wondering if this was the behaviour you had encountered.

I don't think it is appropriate for all Commander messages to go to stderr though. When the help is explicitly requested, the caller is likely to expect the output to be on stdout, e.g.:

my-command --help | grep port

Update: adding a quote from GNU standard for --help:

4.8.2 --help

The standard --help option should output brief documentation for how to invoke the program, on standard output, then exit successfully.

@crystalfp
Copy link
Author

This was the only way to have the help text visible when stdout is routed to a file. Anyway, for my specific program, this workaround solved the problem. Ah, and I don't use subcommands.

I understand your points. I will continue with my workaround any time I have to redirect stdout.
Thanks!
mario

@shadowspawn
Copy link
Collaborator

An idea for future is is to have the optional parameter to the help calls be the logger, and this could be passed through to the help event listeners too. But listener might want to detect it it is a tty to turn on/off colour, so tradeoffs with function vs stream...

e.g. program.help(console.error); or program.help(process.stdout)

@shadowspawn
Copy link
Collaborator

shadowspawn commented Jan 24, 2020

I am currently thinking of making .helpInformation() public as a simple change that lets caller do what they want with the text.

Related PR:#992

@shadowspawn
Copy link
Collaborator

shadowspawn commented Feb 9, 2020

.helpInformation() is public in the published pre-release of Commander v5.0.0 (#1163), allowing a more direct way to write the help built-in information to stderr:

process.stderr.write(program.helpInformation());

@shadowspawn shadowspawn added the pending release Merged into a branch for a future release, but not released yet label Feb 9, 2020
@shadowspawn shadowspawn added this to the v5.0.0 milestone Feb 9, 2020
@shadowspawn shadowspawn removed the pending release Merged into a branch for a future release, but not released yet label Mar 14, 2020
@shadowspawn shadowspawn removed this from the v5.0.0 milestone Mar 14, 2020
@shadowspawn shadowspawn removed their assignment Mar 14, 2020
@shadowspawn
Copy link
Collaborator

shadowspawn commented Apr 23, 2020

This issue has not had activity in over six months (apart from my updates). It isn't likely to get acted on due to this report.

I do agree the help-displayed-as-an-error should go to stderr, but it is not a high priority based on feedback for this item.

Feel free to open a new issue if it comes up again, with new information and renewed interest.

Thank you for your contributions.

@shadowspawn shadowspawn added this to the v7.0.0 milestone Sep 9, 2020
@shadowspawn shadowspawn added the pending release Merged into a branch for a future release, but not released yet label Sep 9, 2020
@shadowspawn shadowspawn removed the pending release Merged into a branch for a future release, but not released yet label Jan 15, 2021
@shadowspawn
Copy link
Collaborator

If the help is displayed due to a usage error then it is displayed on stderr from Commander 7.0.0.

@hibes
Copy link

hibes commented Jun 7, 2021

Just to echo the sentiment presented here #1069, it would be really nice if I could control the output of explicit help requests also.

@shadowspawn
Copy link
Collaborator

@hibes

That is now supported:

program.help(); // stdout
program.help({ error: true }); // stderr

@hibes
Copy link

hibes commented Jun 7, 2021

From the readme:

.help(): display help information and exit immediately. You can optionally pass { error: true } to display on stderr and exit with an error status.

I meant that I would like to be able to configure a program such that ./program --help would send help text to stderr.

Edit:

Something like:

const program = new commander.Command();

program.configureHelpContext({error: true});

@shadowspawn
Copy link
Collaborator

Ah, ok. There is not direct support for that. You could achieve it with a Command subclass and an override.

If you have an interesting use case perhaps open a new issue, as you are asking about something different than the original poster in this issue, and not the usual behaviour for utilities:

@crystalfp
Copy link
Author

Thanks, but I solved in a different way. What I was outputting to stdout now goes to a file. Thanks again for the useful package!

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

No branches or pull requests

4 participants