Skip to content

command with multiple words #655

Closed
Closed

Description

@bydga

Hi, i need to define command like:

program.command "env save [project] [environment]"
	.option "-i, --interactive", "descr.."
	.option "-f, --force", "descr.."
	.action () ->
		console.log arguments

however when calling it like prgname env save aaa bbb gets me output of:

{ '0': 'save',
  '1': 'aaa',
  '2':
   Command {
     commands: [],
     options: [ [Object], [Object] ],
     _execs: {},
     _allowUnknownOption: false,
     _args: [ [Object], [Object] ],
     _name: 'env',
     _noHelp: false,
     parent:
      Command {
        commands: [Object],
        options: [],
        _execs: {},
        _allowUnknownOption: false,
        _args: [],
        _name: 'maratonec',
        Command: [Function: Command],
        Option: [Function: Option],
        _events: [Object],
        _eventsCount: 9,
        rawArgs: [Object],
        args: [Object] },
     _description: 'Saves environment variables into local .env file',
     _events: { interactive: [Function], force: [Function] },
     _eventsCount: 2 } }

I don't want to use the git-style approach, since process spawning and requiring all libraries for every child-process is really slowing down the program (and cli uilities should be fast, shoudn't they?)

So is there a chance to define such command?

Activity

  1. sant123 commented on Jan 3, 2018

    @sant123

    Any advance on this?

  2. mojavelinux commented on Jan 10, 2018

    @mojavelinux
    Contributor

    Parsing the command is the easy part:

    var args = name.split(/ +(?=$|\[|<)/);
    var cmd = new Command(args.shift());
    

    The problem is in handling the user input. All arguments are pre-split, coming in as process.argv. This library would need to consider commands that have spaces and look for a match in the argv.

    Another way to think about this is to have nested action-based commands. But it seems that this library does not support that style. It only supports one level of nesting for action-based commands.

  3. mojavelinux commented on Jan 10, 2018

    @mojavelinux
    Contributor

    We could split the name and stash it away on Command. Then, in parseArgs, we could do something like:

    for (var i = 0; i < this.commands.length; i++) {
      var names = this.commands[i]._names
      if (names.length > 1) {
        if (args.slice(0, names.length).join(' ') === names.join(' ')) {
          this.emit('command:' + args.splice(0, names.length).join(' '), args, unknown);
          return this
        }
      }
    }
    

    It's a bit of a hack, but we're looking for the first command that will match, taking as many of the arguments as it needs to make the match, then falling through to the existing behavior.

  4. mojavelinux commented on Jan 10, 2018

    @mojavelinux
    Contributor

    If that seems like a reasonable approach, I'd be happy to prepare a PR.

  5. waldekmastykarz commented on Jan 27, 2018

    @waldekmastykarz

    It would be awesome if you could submit a PR for that @mojavelinux

  6. Igor-Lopes commented on May 30, 2018

    @Igor-Lopes

    Hello ! Any updates on this issue ?

  7. cjmacharia commented on Sep 26, 2018

    @cjmacharia

    Any updates?

  8. grant commented on Apr 6, 2019

    @grant
    Contributor

    Not sure if this is useful; I use process.argv. I do something like this:

      const subcommand: string = process.argv[3]; // clasp apis list => "list"
      const serviceName = process.argv[4]; // clasp apis enable drive => "drive"

    https://github.com/google/clasp/blob/master/src/commands/apis.ts#L28

    Seems to work fine.

  9. shadowspawn commented on Aug 10, 2019

    @shadowspawn
    Collaborator

    The idea of specifying subcommands as a command with multiple words is quite interesting, and I had not thought of it. I like the simplicity, but it feels like a work-around rather than a strong model for how commands are constructed.

    I want to consider nested action-based commands before this. I am closing this in favour of #764

    Thank you for your contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions