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

Add an opts.array #65

Open
shadowspawn opened this issue May 11, 2024 · 5 comments
Open

Add an opts.array #65

shadowspawn opened this issue May 11, 2024 · 5 comments

Comments

@shadowspawn
Copy link
Collaborator

An issue from the original Minimist repo from @stevendesu with 11 upvotes

https://web.archive.org/web/20200904203616/https://github.com/substack/minimist/issues/136/


I have a command line argument that I wish to always be an array, but it may only contain one value:

Current Behavior

const argv = require("minimist")(process.argv.slice(2), {
    alias: {
        "distributions": ["d"]
    }
});

console.log(argv);
$> node ./index.js -d one -d two
{ _: [],
  distributions: ['one', 'two'],
  d: ['one', 'two']
}
$> node ./index.js -d one
{ _: [],
  distributions: 'one',
  d: 'one'
}

Desired New Option

const argv = require("minimist")(process.argv.slice(2), {
    array: ["distributions"], // <-----------------------------------
    alias: {
        "distributions": ["d"]
    }
});

console.log(argv);
$> node ./index.js -d one
{ _: [],
  distributions: ['one'],
  d: ['one']
}
@shadowspawn
Copy link
Collaborator Author

Related, Deno has made the array behaviour explicit with opts.collect : https://deno.com/blog/v1.23#collect-option

@ghost
Copy link

ghost commented Jun 6, 2024

I would prefer arrays to be parsed without having to specify the arg name for each array value, e.g. node ./index.js -d one two three -> d: ["one", "two", "three"] similar to how Yargs parses arrays.

Perhaps there could be 2 new options: collect for the Deno style outlined in the original request and array for the Yargs style.

@ljharb
Copy link
Member

ljharb commented Jun 6, 2024

That seems very strange, and not what I'm familiar with from yargs. Options - single or double dashed - are only ever followed by a single value, and it seems very surprising to allow an interface that deviates from that.

In yargs, I typically do -a 1 -a 2 -a 3.

@shadowspawn
Copy link
Collaborator Author

I would prefer arrays to be parsed without having to specify the arg name for each array value

yargs-parser defaults to greedy arrays for an explicit array, but that has caused enough parsing problems that might be changed to off by default in Yargs v18.

const yargsFactory = require('yargs/yargs')

const argv = yargsFactory(process.argv.slice(2))
   .array('arr')
   .parse();

console.log(argv);
% node arr.js --arr 1 2 3
{ _: [], arr: [ 1, 2, 3 ], '$0': 'arr.js' }

Greedy arrays work ok if there are not positional arguments. When there might be positional arguments it leads to ambiguous parsing. Withfoo -d one two is two the second option value in an array, or is it a positional?

@ghost
Copy link

ghost commented Jun 6, 2024

Withfoo -d one two is two the second option value in an array, or is it a positional?

My assumption would be that it's decided by however the -d option is configured. Ideally, I would be able to specify that the -d option should take 2 and only 2 values. As I type this though, I realize that it doesn't really jive with the minimist way where options are not configured individually.

Since I'm out of my depth here as a non-CLI argument/option patterns and practices expert, I'll just leave you with a description of what I wanted to do yesterday and why:

TLDR; One of the options I was trying to add to my script was --static src-dir dest-dir but minimist made me do
--from src-dir --to dest-dir. The former looks simpler and makes more sense to me, the latter causes my eyes to do more work to match pairs, especially when more than one --static could be specified.

Backstory:

I wanted to add some nice CLI options to my reusable esbuild script and make it easy for the other devs to use. I started out with Yargs because I had used it in the past. As I re-familiarized myself with it's API, I started realizing it was way too complex to simply add some options to a script. I didn't need a whole command-group based parser with 7 dependencies, just a simple options parser. Unfortunately I didn't look more closely at those 7 dependencies because then I might have realized that I could have just used yargs-parser. Since npmtrends.com didn't help me find that, I settled on minimist which I remembered seeing lots of times in the past decade or so.

As I shifted over to using minimist I found out that my CLI options would have to change from how I planned them with Yargs. I had an option --static src-dir dest-dir and with minimist I had to switch it to --from src-dir --to dest-dir. I don't love this change, but it's done now and maybe next time I will consider using yargs-parser as that seems pretty popular on it's own with 20 million downloads a week more than the root yargs package.

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

No branches or pull requests

2 participants