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

Output stream #1371

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class Command extends EventEmitter {
this._exitCallback = null;
this._aliases = [];
this._combineFlagAndOptionalValue = true;
this._outputStream = process.stdout;

this._hidden = false;
this._hasHelpOption = true;
Expand Down Expand Up @@ -198,6 +199,7 @@ class Command extends EventEmitter {
cmd._storeOptionsAsProperties = this._storeOptionsAsProperties;
cmd._passCommandToAction = this._passCommandToAction;
cmd._combineFlagAndOptionalValue = this._combineFlagAndOptionalValue;
cmd._outputStream = this._outputStream;

cmd._executableFile = opts.executableFile || null; // Custom name for executable file, set missing to null to match constructor
this.commands.push(cmd);
Expand Down Expand Up @@ -687,6 +689,20 @@ Read more on https://git.io/JJc0W`);
return this;
};

/**
* The Stream to which this command writes
* normal output (help, usage, etc.).
*
* @param {stream.Writeable} writeStream
* @returns {Command} `this` command for chaining
* @api public
*/
outputStream(writeStream) {
if (writeStream === undefined) return this._outputStream;
this._outputStream = writeStream;
return this;
};

/**
* Whether to pass command to action handler,
* or just the options (specify false).
Expand Down Expand Up @@ -1287,7 +1303,7 @@ Read more on https://git.io/JJc0W`);
this._versionOptionName = versionOption.attributeName();
this.options.push(versionOption);
this.on('option:' + versionOption.name(), () => {
process.stdout.write(str + '\n');
this._outputStream.write(str + '\n');
this._exit(0, 'commander.version', str);
});
return this;
Expand Down Expand Up @@ -1500,7 +1516,7 @@ Read more on https://git.io/JJc0W`);

optionHelp() {
const width = this.padWidth();
const columns = process.stdout.columns || 80;
const columns = this._outputStream.columns || 80;
const descriptionWidth = columns - width - 4;
function padOptionDetails(flags, description) {
return pad(flags, width) + ' ' + optionalWrap(description, descriptionWidth, width + 2);
Expand Down Expand Up @@ -1542,7 +1558,7 @@ Read more on https://git.io/JJc0W`);
const commands = this.prepareCommands();
const width = this.padWidth();

const columns = process.stdout.columns || 80;
const columns = this._outputStream.columns || 80;
const descriptionWidth = columns - width - 4;

return [
Expand Down Expand Up @@ -1573,7 +1589,7 @@ Read more on https://git.io/JJc0W`);
const argsDescription = this._argsDescription;
if (argsDescription && this._args.length) {
const width = this.padWidth();
const columns = process.stdout.columns || 80;
const columns = this._outputStream.columns || 80;
const descriptionWidth = columns - width - 5;
desc.push('Arguments:');
desc.push('');
Expand Down Expand Up @@ -1636,7 +1652,7 @@ Read more on https://git.io/JJc0W`);
if (typeof cbOutput !== 'string' && !Buffer.isBuffer(cbOutput)) {
throw new Error('outputHelp callback must return a string or a Buffer');
}
process.stdout.write(cbOutput);
this._outputStream.write(cbOutput);
this.emit(this._helpLongFlag);
};

Expand Down
14 changes: 14 additions & 0 deletions tests/command.outputStream.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const commander = require('../');
const stream = require('stream');

test('when command output stream is not set then default is process.stdout', () => {
const program = new commander.Command();
expect(program.outputStream()).toBe(process.stdout);
});

test('when set command output stream then command output stream is set', () => {
const program = new commander.Command();
const customStream = new stream.Writable();
program.outputStream(customStream);
expect(program.outputStream()).toBe(customStream);
});
13 changes: 13 additions & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Type definitions for commander
// Original definitions by: Alan Agius <https://github.com/alan-agius4>, Marcelo Dezem <https://github.com/mdezem>, vvakame <https://github.com/vvakame>, Jules Randolph <https://github.com/sveinburne>

import * as stream from 'stream';

declare namespace commander {

interface CommanderError extends Error {
Expand Down Expand Up @@ -221,6 +223,17 @@ declare namespace commander {
*/
allowUnknownOption(arg?: boolean): this;

/**
* Set the Stream to which this command writes normal output (help, usage, etc.).
*
* @returns `this` command for chaining
*/
outputStream(writeStream: stream.Writable): this;
/**
* Get the Stream to which this command writes normal output (help, usage, etc.).
*/
outputStream(): stream.Writable;

/**
* Parse `argv`, setting options and invoking commands when defined.
*
Expand Down