Skip to content

Conversation

@nfischer
Copy link
Member

This is a PR to refactor commands to return ShellString objects instead of regular strings. This still has some broken tests, so it's far from ready, but I think in principle this approach will work.

Feel free to fix any tests and/or post the diffs.

Fixes #356, #154.

@nfischer nfischer added this to the v0.7.0 milestone Feb 16, 2016
@ariporad
Copy link
Contributor

@nfischer: It looks like this was implemented on top of #344, is that correct? If so, it looks like we'll have to do some git-fu to fix it.

@ariporad
Copy link
Contributor

@nfischer: Maybe I'm missing something, but how is returning a ShellString any different from returning a normal string?

Also, what are your thoughts on converting them to ShellStrings inside common.wrap, vs. the command itself.

@nfischer
Copy link
Member Author

@ariporad Convering in common.wrap is fine with me, as long as it works.

JavaScript has strings and Strings. The capital String is an object. The two are very similar (the same methods). They differ in type though, and that's significant. Because Strings are objects, we can assign properties to them without modifying the prototype (and that's the important part). ShellStrings are intentionally very similar to Strings. We can easily add features though, like .to(), pipes, stderr, code, etc

@nfischer
Copy link
Member Author

This still isn't ready to merge. I'll ping this thread when it's ready for review.

@nfischer
Copy link
Member Author

@ariporad Please take a look at my implementation. This is quite a big refactor, but I think it has some nice benefits.

  • This fixes Don't modify string prototype #159 (unfortunately, this breaks backwards compatibility, but I think it's worth it)
  • This will make it easy to add support for pipes, once everything is common.wraped (blocked by fix(verbose): verbose-style logging is consistent #362)
  • This makes sure exec() (synchronous) returns a ShellString, which allows users to write things like exec('git status').to('file.txt') instead of exec('git status').stdout.to('file.txt'). This makes the second syntax actually invalid, and it also removes the deprecated output attribute (we can add that back pretty easily though if it's important).

We can also consider extending this type to have a .forEach() method that iterates over each line in the standard output. Ex:

cat('file.txt').forEach(function (line) {
  echo("  " + line);
}); // indent every line of the file in stdout

This might make it easy to refactor ls() to return a ShellString, and still allow users to iterate over its output. This hasn't been implemented yet, however, and probably should be a separate PR.

src/common.js Outdated
that.to = wrap('to', _to, {idx: 1});
that.toEnd = wrap('toEnd', _toEnd, {idx: 1});
that.stdout = str;
that.stderr = typeof stderr !== 'undefined' ? stderr : state.error;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should default to state.error here, because:

var str = ShellString('foo');
str.stderr; // This should be null, having it be anything else wouldn't make any sense.
str.to('foo.txt');

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rationale was for commands like sed(), which can sometimes have stderr output, and still return a value (imagine one file exists, and one file doesn't exist).

One alternative would be to not default it, but to have each call to ShellString() explicitly have a stderr argument if it needs it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Will push in a second

@nfischer nfischer force-pushed the refactor-shellstring branch from b1814aa to 9e6e0c2 Compare February 19, 2016 22:16
@ariporad
Copy link
Contributor

@nfischer: Is it possible to convert the result to a ShellString in common.wrap? Otherwise, LGTM!

@nfischer
Copy link
Member Author

@ariporad I thought about putting it in common.wrap(). The issue is that some commands return arrays (i.e. ls()), some return nothing (i.e. cp()), and some probably should return plain strings (like tempdir()). With some cleverness, we might be able to refactor for that, but it might just compliment things more (like an argument {idx: 1, shellstring: true}).

@ariporad
Copy link
Contributor

Ok.

LGTM!

Ari

On Fri, Feb 19, 2016 at 3:25 PM, Nate Fischer notifications@github.com
wrote:

@ariporad https://github.com/ariporad I thought about putting it in
common.wrap(). The issue is that some commands return arrays (i.e. ls()),
some return nothing (i.e. cp()), and some probably should return plain
strings (like tempdir()). With some cleverness, we might be able to
refactor for that, but it might just compliment things more (like an
argument {idx: 1, shellstring: true}).


Reply to this email directly or view it on GitHub
#360 (comment).

 - fix(string): no longer overrides string prototype
 - exec() now returns a ShellString object
@nfischer nfischer force-pushed the refactor-shellstring branch from cd04c29 to 6ebc2d3 Compare February 19, 2016 22:54
@nfischer
Copy link
Member Author

@ariporad Ok, the issues should be resolved now. LGTM, feel free to merge

@nfischer
Copy link
Member Author

@ariporad I went ahead and added some of these methods to the array returned by ls(), since I think this is a good direction to go. I left it as a separate commit for now, so it should be easier for you to find those changes. Let me know what you think.

If everything looks good, feel free to squash the changes together (or not, doesn't matter to me), and merge.

After this is merged, I can redo #269 so that each ShellString also has a code attribute (so it's similar to the object exec() returns).

@ariporad
Copy link
Contributor

@nfischer: One small nit, but it's not that big a deal, so I'll say LGTM.

As for the code prop, I say that we should just make error() return the code, because everything returns stderr.

@ariporad
Copy link
Contributor

Merge at will.

ariporad added a commit that referenced this pull request Feb 20, 2016
refactor(ShellString): refactor shellstring
@ariporad ariporad merged commit d0b7d09 into master Feb 20, 2016
@ariporad ariporad deleted the refactor-shellstring branch February 20, 2016 22:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Standardize command output

3 participants