How can I merge two strings that contain conventional CLI options (i.e. anything getopt() would parse correctly.)?
The first is pulled from a config file, and the second is from Symfony's Console\Input\getArgument(). I could also get the second one from $GLOBALS['argv']. I want to combine them, so that I can launch another program with them.
Either string could contain short options, long options, both with or without values.
Example
e.g., config.yml contains
phpunit_arguments: -d xdebug.mode=off --columns=115
...and then the user can call my program with php {filename} --columns=95 --debug. I want to merge those strings, so that I end up with:
-d xdebug.mode=off --columns=95 --debug
The columns from the first string was overridden by the one from the second.
Failed Attempt 1: Converting to arrays
If I can get those strings into arrays like the following, then I can just use array_merge_recursive():
array(
'-d xdebug.mode' => 'off',
'--columns' => 115
)
array(
'--columns' => 95,
'--debug'
)
...but to do that I need a parser that understand CLI options.
I've looked at the following, but none seem to be designed to take an arbitrary string and return a parsed array.
- PHP's
getopt() - Symfony's
Console\Input - PHPUnit's
TextUI\CliArguments\Builder - docopt.php
- Commando
- GetOptionKit
Failed Attempt 2: Concatenating
I tried just concatenating the two strings instead of merging them, and that technically works, but it creates UX problems. My program displays the args to the users, and concat'd string would contain duplicates, which would be confusing for some. The program also accepts input while it's running, and regenerates the options; over time, appending to the prior string would snowball and worse the confusion/UX.
e.g., after setting groups a few times, it'd end up as
-d xdebug.mode=off --columns=95 --debug --groups=database --groups=file --groups=console
You can create your own function that will smart merge configuration parameters and CLI arguments. Using a single regular expression, we can extract pre-signs like
-or--, command names and equality character with the value.Merging arguments using regular expressions and loops
Please read inline comments
Result
Running this command:
with this
config.yml:will output this:
So we can see that the arguments
-d xdebug.mode=offand--columns=115have been merged and override be the CLI arguments-d xdebug.mode=on --columns=95and also we have only the last one--groups=consoleset.Run it
You can check this parsing working online onto this repl.it.