Closed aydun closed 1 year ago
I've tested this - it works! I've often stumbled across this problem, it would be great to see this merged.
Many thanks @aydun and @kenahoo
(It's enabled me to make this https://lab.civicrm.org/extensions/taggedlog/-/blob/main/cli/grep.php)
(It's enabled me to make this https://lab.civicrm.org/extensions/taggedlog/-/blob/main/cli/grep.php)
Wow @artfulrobot - that's great to see the feature getting used so quickly.
@aydun I've needed/wanted this so many times before that i finally came here to suggest it as an enhancement, and from there found the original suggestion and your pr. Gotta love sharing code :heart:
Oh, yes, this is very nice @aydun. It even has a test! 😃
There was one small catch -- the synthetic $argv
was missing the standard 0-th parameter. Compare:
$ php ~/src/cv/tests/Command/hello-args.php one two three
0: /Users/totten/src/cv/tests/Command/hello-args.php
1: one
2: two
3: three
$ cv scr ~/src/cv/tests/Command/hello-args.php one two three
0: one
1: two
2: three
I pushed up a revision to make it match. Unless there's an objection to the change, let's merge.
@totten's change makes $argv
and $argc
behave in their documented ways, so that's good by me as it's less confusing (even if the first thing I'mma do whenever I use this is array_shift($argv)!).
Let's merge!
Thanks @totten. I realised that if the required script uses a variable called $output
, it will overwrite the existing one resulting in errors. This last change prevents that.
(even if the first thing I'mma do whenever I use this is array_shift($argv)!).
Some rituals must be preserved.
I realised that if the required script uses a variable called $output ...
Agree, this looks like better isolation now. 👍
Thanks @aydun and @totten :-)
Thanks!
(@artfulrobot) (even if the first thing I'mma do whenever I use this is array_shift($argv)!).
This is a bit of tangential rant, but it might be interesting... argv
was one of my pet-peeves in scripting. Specifically, the need for impromptu parsing of argv. It doesn't really come up on tiny scripts (eg 20 SLOC; not enough options to worry about parsing them) or full programs (eg 5000+ SLOC; big enough to setup a standalone project and download nice CLI library). But for a certain size in the middle (50-500 SLOC), it's kind of annoying. I don't care to remember how many times I had to write an argv parse-loop for a script in this size-bracket.
Now-a-days, for scripts in that middle-space, I like to pull in "silly"/"clippy". If you understand the synopsis from a typical Unix manpage, then the notation may be familiar. Ex:
## Goal:
myscript [--foo] [-b|--bar=] files*
## Implementation:
$c['app']->main('[--foo] [-b|--bar=] files*', function($io, bool $foo, ?string $bar, array $files) {
$io->writeln("The foo is " .
($foo ? '<info>ON</info>' : '<error>OFF</error>'));
$io->writeln("The value of bar is <info>$bar</info>");
$io->writeln("The files are: " . json_encode($files));
});
In that example, the script accepts --foo
, -b=123
, -b 123
, -b123
, --bar 123
, --bar=123
, and then an open-ended array of filenames. It's definitely nicer thangetopt
or an impromptu parse-loop.
Of course, I've only used it for plumbing that's outside of Civi's runtime... it could be that (in this context) the path-of-least-resistence is still writing an argv parser in-situ...
@totten yes, it's frustrating. I like Python's argparse package (but not for php, obvs!)
for php I generally prefer getopt or simply manual because I like a script to be standalone. e.g. reading clippy:
To simplify the workflows for dependency management, the examples use pogo. pogo should be installed in the PATH. Alternatively, you can rework the examples - instead, create a new composer package for each script and run composer require
: has needed.
Ugh, no thanks!
If
cv scr
is called with arguments like this:cv scr myscript.php arg1 arg2 ...
myscript.php
will have$argv = ['arg1', 'arg2']
Quoted args are passed through correctly:
cv scr myscript.php one 'two and' three
=>$argv = ['one', 'two and', 'three']
Options starting with a hyphen can also be passed to the script if
--
is used:cv scr myscript.php -- -a b
=>$argv = ['-a', 'b']
The superglobal
$GLOBAL['argv']
is also available with the full command line but$argv
will usually be easier to work with.