shelljs-transpiler icon indicating copy to clipboard operation
shelljs-transpiler copied to clipboard

&& and || operations

Open nfischer opened this issue 9 years ago • 1 comments

Add in translation for && and || as follows:

$ true && echo 'hi'
hi
$ false || echo 'hi'
hi

In general, it may be tough to get this working as nicely as possible. commands like test -f file.txt return booleans, and it would be nice to take advantage of that in translation, while other commands like exec('git status') have .code attributes that should be examined instead.

Also, this should work with other formats, such as [ "my string" ] && echo hi.

It'd be really great if better support for && and || could be worked into n_shell or ShellJS proper.

nfischer avatar May 17 '16 19:05 nfischer

Update:

Most shelljs methods have .code attributes (.code === 0 means success). shell.test() is the notable exception.

Some design ideas

We could translate this into an 'if' expression:

// cp file.txt dest/ && echo 'file copied successfully!'
var result = shell.cp('file.txt', 'dest/');
if (result.code === 0) shell.echo('file copied successfully!');
// But what if we need the combined stdout/stderr/code from the 'and' expression?

We could consider adding pre-defined and() and or() functions into the translation. If we add those into the translator, it would look like:

// cp file.txt dest/ && echo 'file copied successfully!'
and([ shell.cp, 'file.txt', 'dest/' ], [ shell.echo, 'file copied successfully!' ]);

function and(cmd1, cmd2) {
  var ret = cmd1.invoke(shell, cmd1.slice(1));
  if (ret.code === 0) {
    var ret2 = cmd2.invoke(shell, cmd2.slice(1));
    // merge .stdout, .stderr, .code from ret & ret2
    return combinedShellString;
  }
  return ret; // otherwise, never execute cmd2
}

This should work, but the array syntax is pretty ugly.


We could also consider implementing this upstream in shelljs:

shell.cp('file.txt', 'dest/').and().echo('file copied successfully!');

function and() {
  // |this| is a ShellString object
  if (this.code === 0) {
    // Return some object which has modified shelljs methods. They execute the same,
    // but they concatenate
  } else {
    // Return some object which has different modified shelljs methods. They're all NOOPs,
    // and they return |this| (the |this| from this invocation)
  }
}

nfischer avatar Feb 07 '18 00:02 nfischer