| 236 | // key="value" - a value surrounded by quotes |
| 237 | // key - a flag |
| 238 | parseCommandOptions(optionString) { |
| 239 | const options = {}; |
| 240 | while (optionString != "") { |
| 241 | // Note that option names are allowed to be letters only; no numbers. |
| 242 | let match, matchedString, key, value; |
| 243 | // Case: option value surrounded by quotes (key= "a b"). Spaces are allowed in the value. |
| 244 | if (match = optionString.match(/^([a-zA-Z]+)="([^"]+)"(\s+|$)/)) { |
| 245 | matchedString = match[0]; |
| 246 | key = match[1]; |
| 247 | value = match[2]; |
| 248 | } // Case: option value not surrounded by quotes (key=value). Spaces aren't allowed. |
| 249 | else if (match = optionString.match(/^([a-zA-Z]+)=(\S+)(\s+|$)/)) { |
| 250 | matchedString = match[0]; |
| 251 | key = match[1]; |
| 252 | value = match[2]; |
| 253 | } // Case: single option (flag), or "any URL". This correctly parses URLs because URLs cannot |
| 254 | // contain unescaped equals or space characters. The key will be the option's name (or the |
| 255 | // URL), and the value will be true. |
| 256 | else if (match = optionString.match(/^([^\s"]+)(\s+|$)/)) { |
| 257 | matchedString = match[0]; |
| 258 | key = match[1]; |
| 259 | value = true; |
| 260 | } |
| 261 | // NOTE(philc): If this string doesn't match any of our option regexps, we could throw an |
| 262 | // error here or use an assert. I think this might only happen in the case where there's a |
| 263 | // single equals sign. For now, just add the whole string as a flag option. If the command in |
| 264 | // question doesn't accept this option, then an error will get surfaced to the user. |
| 265 | if (match == null) { |
| 266 | console.log(`Warning: '${optionString}' isn't a valid option string.`); |
| 267 | options[optionString] = true; |
| 268 | break; |
| 269 | } |
| 270 | |
| 271 | options[key] = value; |
| 272 | optionString = optionString.slice(matchedString.length); |
| 273 | } |
| 274 | |
| 275 | // We parse any `count` option immediately (to avoid having to parse it repeatedly later). |
| 276 | if ("count" in options) { |
| 277 | options.count = parseInt(options.count); |
| 278 | if (isNaN(options.count)) { |
| 279 | delete options.count; |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | return options; |
| 284 | }, |
| 285 | }; |
| 286 | |
| 287 | const Commands = { |