Skip to content
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

Options appear in the order of defintion #39

Closed
amagura opened this issue Aug 6, 2014 · 9 comments
Closed

Options appear in the order of defintion #39

amagura opened this issue Aug 6, 2014 · 9 comments

Comments

@amagura
Copy link

amagura commented Aug 6, 2014

Problem Description

Options in the hash produced by yargs appear in the order in which they were defined, rather than in the order in which they appeared on the command-line: this makes it impossible to determine which option(s)/operand(s) should be handled first.

Example

Consider the following example were both -h and -V are mutually exclusive in the sense that the program exits immediately after they occur.

// ya.js
var yargs = require('yargs')
  , args  = yargs
    .describe('h', 'print this message and exit').boolean('h')
    .describe('V', 'print version information and exit').boolean('V')
    .argv
  ;

var argz = Object.keys(args);
argz.forEach(function(arg) {
  if (args[arg] === false) delete args[arg]; /* without this, all options defined appear
 in the `args` hash, but with this, only options that were present on the command-line
 are retained in the `args` hash. */
});
var argz = Object.keys(args);
argz.forEach(function(arg) {
  switch(arg) {
    case 'h':
      yargs.showHelp();
      process.exit(0);
    case 'V':
      console.log('1.0');
      process.exit(0);
  }
});

No matter what order I put the options in, unless -V is passed by itself, it will never get handled because -h is defined before -V, and note that even if you change the describe(...) settings around so that -V is defined before -h, if you don't also update the .boolean(...) settings, then -h will still be defined before -V.

Proposed Solution

You can probably fix the above by simply adding options as they appear on the command-line, like so:

args = {};
process.argv.forEach(function(opt) {
  args[opt] = true; /* set to true just because this is only an example of a
 solution in theory, and not an actual working solution. */
});
@codelahoma
Copy link

The order of keys in the return value of Object.keys is implementation specific, and should not be depended upon.

@megawac
Copy link

megawac commented Apr 22, 2015

You can just sort the result from keys? var argz = Object.keys(args).sort()

@amagura
Copy link
Author

amagura commented Apr 23, 2015

@megawac how does that help? That'll just sort them alphabetically: they need to be sorted according to the order of their appearance on the command-line.

@codelahoma last time I checked, yargs was meant to only work with nodejs, but maybe it works with other things, however, I only would use it with nodejs.

Closing this issue since it'll never be taken seriously by the people in charge of this repo.

@amagura amagura closed this as completed Apr 23, 2015
@bcoe
Copy link
Member

bcoe commented Apr 23, 2015

@amagura I definitely take this issue seriously, it's just a hard problem and I've been wrapped up working on a few big refactors.

Correct me if I'm wrong @codelahoma, in V8 Object.keys is insertion ordered?

@bcoe bcoe reopened this Apr 23, 2015
@codelahoma
Copy link

@bcoe It's been hotly debated for over six years, but V8 does not always follow insertion order, and they continue to say it's WorkingAsIntended.

@amagura
Copy link
Author

amagura commented Apr 25, 2015

@bcoe my apologies, I was just a little frustrated at the time.

@adius
Copy link

adius commented May 21, 2015

It would be really cool if it was possible to retrieve the arguments in the order they appear.
Using an object, however, is the wrong way as they have no order by design.
The correct data-structure would be something like this I guess:

var argsSorted = [
  {
    name: 'width',
    value: '10'
  },
  {
    name: 'height',
    value: '10'
  }
]

But I'm not sure how it should be exposed. Maybe provide require('yargs').argvSorted.
Maybe we could also add the specified infos like required, default, … so that it can easily be used without having to cross reference.
What do you think?

@maxrimue maxrimue mentioned this issue Dec 3, 2015
15 tasks
@ErisDS
Copy link

ErisDS commented Jun 27, 2017

This appears to be implemented and working now?!

@bcoe
Copy link
Member

bcoe commented Nov 9, 2019

yargs-parser now appears to insert arguments in parser order, rather than the order that they're defined with .option().

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

No branches or pull requests

6 participants