| 16 | }); |
| 17 | |
| 18 | function CLI(usage, settings) { |
| 19 | if (process.argv.length < 3) { |
| 20 | this.abort(usage); // Abort will exit the process |
| 21 | } |
| 22 | |
| 23 | this.usage = usage; |
| 24 | this.optional = {}; |
| 25 | this.items = []; |
| 26 | this.test = false; |
| 27 | |
| 28 | for (const argName of settings.arrayArgs) { |
| 29 | this.optional[argName] = []; |
| 30 | } |
| 31 | |
| 32 | let currentOptional = null; |
| 33 | let mode = 'both'; // Possible states are: [both, option, item] |
| 34 | |
| 35 | for (const arg of process.argv.slice(2)) { |
| 36 | if (arg === '--help') this.abort(usage); |
| 37 | if (arg === '--') { |
| 38 | // Only items can follow -- |
| 39 | mode = 'item'; |
| 40 | } else if (mode === 'both' && arg[0] === '-') { |
| 41 | // Optional arguments declaration |
| 42 | |
| 43 | if (arg[1] === '-') { |
| 44 | currentOptional = arg.slice(2); |
| 45 | } else { |
| 46 | currentOptional = arg.slice(1); |
| 47 | } |
| 48 | |
| 49 | if (settings.boolArgs && settings.boolArgs.includes(currentOptional)) { |
| 50 | this.optional[currentOptional] = true; |
| 51 | mode = 'both'; |
| 52 | } else { |
| 53 | // Expect the next value to be option related (either -- or the value) |
| 54 | mode = 'option'; |
| 55 | } |
| 56 | } else if (mode === 'option') { |
| 57 | // Optional arguments value |
| 58 | |
| 59 | if (settings.arrayArgs.includes(currentOptional)) { |
| 60 | this.optional[currentOptional].push(arg); |
| 61 | } else { |
| 62 | this.optional[currentOptional] = arg; |
| 63 | } |
| 64 | |
| 65 | // The next value can be either an option or an item |
| 66 | mode = 'both'; |
| 67 | } else if (arg === 'test') { |
| 68 | this.test = true; |
| 69 | } else if (['both', 'item'].includes(mode)) { |
| 70 | // item arguments |
| 71 | this.items.push(arg); |
| 72 | |
| 73 | // The next value must be an item |
| 74 | mode = 'item'; |
| 75 | } else { |