-
Notifications
You must be signed in to change notification settings - Fork 742
Add "-n" option to echo #590
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
Conversation
}); | ||
|
||
test.cb('-ne option', t => { | ||
const script = "require('../global.js'); echo('-ne', 'message');"; |
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.
Can we also test echo -en 'foo\n'
to make sure that -e
still works?
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.
Sure, I can add a test for that.
output = format.apply(null, messages) + '\n'; | ||
} | ||
|
||
console.log.apply(console, messages); |
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.
Let's only use process.stdout.write
for when -n
is passed. Calling process.exit
immediately after process.stdout.write
has some issues.
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 don't think it matters, because console.log
is just a wrapper around process.stdout.write
. See this.
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.
For reference, it has been that way since at least v0.7.4.
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.
Hmmm ok, let's use this approach then.
src/echo.js
Outdated
var option = ['-e', '-n', '-ne', '-en'].indexOf(messages[0]); | ||
var output; | ||
|
||
if (option >= 0) { |
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.
It might be easier to just check:
- is the first argument a real option?
- do the options contain
-n
?
And just switch the behavior on that condition. That way we can keep using console.log
by default, which has some nicer behavior (see my comment below).
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.
How do we check if the first argument is a real option? Would using the cmdOptions
attribute in common.register
solve this?
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 think we can use common.parseOptions
to parse the first argument. If we catch the option not recognized
error, then just print that string.
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.
Yeah, but it won't throw the error as an exception, it'll return early from the echo
function. You can hack around it by setting config.fatal
to have it throw an exception. A clearer way is to add an option to common.error
to throw an exception instead of exiting (regardless of config.fatal
).
The approach you have here works if we only have two options, but it gets cumbersome if we ever support -E
(which we may want to support in the future).
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.
Ok, I've added a function to echo.js
that parses options just for echo
. This means adding -E
later on will be easier.
src/echo.js
Outdated
return output; | ||
} | ||
|
||
function parseEchoOptions(opts) { |
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.
Actually, let's use common.parseOptions()
. It actually does throw an exception upon error regardless of config.fatal
. It behaves exactly how we want, and it'll be much cleaner to reuse the 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.
parseOptions
will still log to stdout when it doesn't recognize an option:
> try {
... common.parseOptions('-b', {a: 'test'})
... } catch (_) {
... console.log('whoops')
... }
shell.js: option not recognized: b
whoops
This is not good if someone tries to echo a string that happens to start with '-'
.
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.
Ah, I see the issue. I think it may be better to either:
- hack around this by temporarily setting
config.silent = true
(document what we're doing in comments) - add a way to silence
parseOptions
(exception only, no stdio)
I think the approach we take depends on if we want to expose this feature in parseOptions
in the plugin API.
@freitagbr What do you think?
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 would prefer an extra silence
argument or option for parseOptions
. Plugins could probably make use of the option, too.
4f4b422
to
74242aa
Compare
@nfischer I refactored |
74242aa
to
09d8643
Compare
@freitagbr please rebase off |
09d8643
to
11629fb
Compare
Done. |
src/echo.js
Outdated
// ignore -e | ||
if (options) { | ||
// first argument was options string, | ||
// so do not print it |
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.
Join these lines?
src/echo.js
Outdated
// If the first argument starts with '-', | ||
// parse it as options string. | ||
// If parseOptions throws, | ||
// it wasn't an options string. |
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.
Join these lines?
src/echo.js
Outdated
output += '\n'; | ||
} | ||
} else { | ||
output = format.apply(null, messages) + '\n'; |
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.
We're appending \n
in this branch, but we're also appending it above. Can we flatten-out this logic? Something like:
try {
options = common.parseOptions(messages[0], { ... }, { silent: true });
messages.shift();
} catch (e) {
options = {};
}
output = format.apply(null, messages);
if (!options.no_newline) {
output += '\n';
}
process.stdout.write(output);
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 think we still need to check if the first argument starts with '-'
, because we don't know if it needs to be printed or not otherwise.
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.
Ok, sure. parseOptions
has useless behavior if you pass it a string that doesn't start with -
.
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.
Approval. See #614 in case you want to fix that first, otherwise FFTM
I'll wait for the pull request I submitted (#615) to be merged before moving on here. |
There's an issue here. When passing a string starting with
This is obviously not how |
@freitagbr can you manually clear out I doubt there's a great way to test it, but maybe you could add a test like: const ret = shell.echo('-n', ''); // echo nothing
t.falsy(ret.stderr);
t.is(ret.stdout, '');
t.is(ret.code, 0); This case wouldn't add stderr anyway, but it'll save us from huge future regressions while also not polluting the output. |
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.
Needs a fix for .stderr
609d7c8
to
e018604
Compare
@nfischer I added the fix, though there is already a test case that checks that |
@freitagbr it needs to check for |
Ok, test added. PTAL |
ava-test/echo.js
Outdated
}); | ||
|
||
test('stderr with unrecognized options is null', t => { | ||
const ret = shell.echo('-asdf'); |
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.
@freitagbr will this output to the console? If so, let's at least add a TODO to mute console output
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.
Yes it does. I suppose we can fix this along with mocking process.stdout
like you suggested for #622.
ava-test/echo.js
Outdated
}); | ||
}); | ||
|
||
test('stderr with unrecognized options is null', t => { |
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.
s/null/empty/ or s/null/falsy/
We may want to switch stderr from null
to the empty string in a future release.
ec4810e
to
37ea827
Compare
@nfischer PTAL |
Fixes #559