dthree / vorpal

Node's framework for interactive CLIs
http://vorpal.js.org
MIT License
5.64k stars 280 forks source link

Need to disable options validation for .catch command #207

Closed sidorenkobw closed 7 years ago

sidorenkobw commented 7 years ago

Hi guys,

My idea is to create a shell which extends my current system shell. So I create my commands in vorpal and I want every input which is not a registered command to be executed in current system shell.

So I do the following:

var shell = require('vorpal')();

shell
    .command("cmd1")
        .description("cmd1")
        .action(function (args, callback) {
            shell.log("cmd1");
            callback();
        });

shell
    .catch('[words...]', 'Exec shell commands')
    .action(function (args, callback) {
        var cmd = args.words.join(" ");
        shell.log(cmd);

        require('child_process')
            .execSync(cmd, {stdio:[0,1,2]});

        callback();
    });

shell
    .show()

It works fine unless I am trying to run some system shell command with options, like: ls -l

In this case validation doesn't allow to run this callback saying:

[shell] ls -l Invalid option: 'l'. Showing Help:

Usage: [options] [words...]

Exec shell commands

Options:

--help  output usage information

Is there any way to disable options validation?

Thanks

MatthieuLemoine commented 7 years ago

I didn't find a way to disable options validation but I found a workaround to this issue by using parse. The idea is to replace whitespaces by whatever delimiter :

vorpal
  .catch('[words...]', 'Exec shell commands')
  .parse(command => command.split(' ').join('____'))
  .action((args, cb) => {
    const cmd = args.words[0].split('____').join(' ');
    vorpal.log(cmd);
    exec(cmd, { stdio : [0, 1, 2] });
    cb();
  });
sidorenkobw commented 7 years ago

Thank you, Matthieu!

As for vorpal, I think that ignoring options validation would be more logical way for processing catch command rather the current one. I also suggest to add ability to ignore options validation to any command in case if some one wants to make it in dynamic way.

Awesome project, BTW. Great job, guys!

MatthieuLemoine commented 7 years ago

My bad, there is a way to disable options validation, see #144. You just have to call allowUnknownOptions() :

vorpal
  .catch('[words...]', 'Exec shell commands')
  .allowUnknownOptions()
  .action((args, cb) => {
    const cmd = args.words.join(' ');
    try {
      exec(cmd, { stdio : 'inherit' });
    } catch (e) {
      vorpal.execSync('help');
    }
    cb();
  });
sidorenkobw commented 7 years ago

Thank you Matthieu! Looks like it's not documented.

MatthieuLemoine commented 7 years ago

Added in the Wiki : allowUnknownOptions