Skip to content

Commit

Permalink
Implement "limit-last" mode for multipleOptions
Browse files Browse the repository at this point in the history
We're flipping the order of the arguments array before and after running
through it in order to retroactively inject stuff into result.argv. This
is a SERIOUSLY suboptimal approach, but because I don't predict that the
"limit-last" option will be used that often, a sloppy approach is better
than blowing days of effort over a "clean" approach.
  • Loading branch information
Alhadis committed Dec 7, 2015
1 parent 995efb1 commit d0f7bd4
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
41 changes: 33 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,19 +219,14 @@ function getOpts(input, optdef, config){
break;
}

/** Use the first option; treat any following duplicates as items of argv */
case "limit-first":{
/** Use the first/last options; treat any following/preceding duplicates as argv items respectively */
case "limit-first":
case "limit-last":{
let values = Array.isArray(value) ? value : [value];
result.argv.push(option.prevMatchedName, ...values);
break;
}

/** Use only the last option; treat any preceding duplicates as items of argv */
case "limit-last":{

break;
}


/** Chuck a hissy-fit if that's what the author wants */
case "error":{
Expand Down Expand Up @@ -322,6 +317,26 @@ function getOpts(input, optdef, config){
};


/** Reverses the argument order of the given array, keeping options and their parameter lists intact */
let flip = function(input){
input = input.reverse();

/** Flip any options back into the right order */
for(let i = 0, l = input.length; i < l; ++i){
let arg = input[i];
let opt = shortNames[arg] || longNames[arg];

if(opt){
let from = Math.max(0, i - opt.arity);
let to = i + 1;
let extract = input.slice(from, to).reverse();
input.splice(from, extract.length, ...extract);
}
}

return input;
};


/** Tackle bundling: make sure there's at least one option with a short name to work with */
let nameKeys = Object.keys(shortNames);
Expand Down Expand Up @@ -379,6 +394,11 @@ function getOpts(input, optdef, config){
}


/** If we're handling duplicate options with "limit-last", flip the input order */
if("limit-last" === multipleOptions)
input = flip(input);


/** Start processing the arguments we were given to handle */
for(let i = 0, l = input.length; i < l; ++i){
let arg = input[i];
Expand Down Expand Up @@ -428,6 +448,11 @@ function getOpts(input, optdef, config){
/** Ended abruptly? */
if(currentOption) wrapItUp();


/** Check if we need to flip the returned .argv array back into the right order again */
if("limit-last" === multipleOptions)
result.argv = flip(result.argv);

return result;
}

Expand Down
11 changes: 11 additions & 0 deletions test/tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@
}
},

{
"name": "Duplicate-option handling: limit-last",
"input": "alpha --set-size 640 480 beta --set-size 800 600 gamma --set-size 1024 768",
"config": {"noAliasPropagation": "first-only", "multipleOptions": "limit-last"},
"optdef": {"-s, --set-size": "<width=\\d+> <height=\\d+>"},
"expected": {
"options": {"setSize": ["1024", "768"]},
"argv": ["alpha", "--set-size", "640", "480", "beta", "--set-size", "800", "600", "gamma"]
}
},

{
"name": "Duplicate-option handling: error",
"input": "--arg 1 alpha --arg 2",
Expand Down

0 comments on commit d0f7bd4

Please sign in to comment.