2 namespace Consolidation\TestUtils;
4 use Consolidation\AnnotatedCommand\CommandData;
5 use Consolidation\AnnotatedCommand\AnnotationData;
6 use Consolidation\AnnotatedCommand\CommandError;
7 use Symfony\Component\Console\Command\Command;
8 use Symfony\Component\Console\Event\ConsoleCommandEvent;
9 use Symfony\Component\Console\Input\InputInterface;
10 use Symfony\Component\Console\Input\InputOption;
11 use Symfony\Component\Console\Output\OutputInterface;
14 * Test file used in the Annotation Factory tests. It is also
15 * discovered in the testCommandDiscovery() test.
17 * The testCommandDiscovery test search base is the 'src' directory;
18 * any command files located immediately inside the search base are
19 * eligible for discovery, and will be included in the search results.
21 class ExampleCommandFile
26 public function __construct($state = '')
28 $this->state = $state;
31 public function setOutput($output)
33 $this->output = $output;
37 * Import config from a config directory.
39 * @command config:import
40 * @param $label A config directory label (i.e. a key in \$config_directories array in settings.php).
41 * @interact-config-label
42 * @option preview Format for displaying proposed changes. Recognized values: list, diff.
43 * @option source An arbitrary directory that holds the configuration files. An alternative to label argument
44 * @option partial Allows for partial config imports from the source directory. Only updates and new configs will be processed with this flag (missing configs will not be deleted).
45 * @aliases cim,config-import
47 public function import($label = null, $options = ['preview' => 'list', 'source' => InputOption::VALUE_REQUIRED, 'partial' => false])
52 * Calculate the fibonacci sequence between two numbers.
54 * Graphic output will look like
55 * +----+---+-------------+
62 * +--------+-------------+
64 * @param int $start Number to start from
65 * @param int $steps Number of steps to perform
67 * @option $graphic Display the sequence graphically using cube
70 public function fibonacci($start, $steps, $opts = ['graphic' => false])
77 * Run the PHP Codesniffer on a file or directory.
80 * A file or directory to analyze.
81 * @option $autofix Whether to run the automatic fixer or not.
82 * @option $strict Show warnings as well as errors.
83 * Default is to show only errors.
85 public function sniff(
92 return var_export($options, true);
96 * This is the my:cat command
98 * This command will concatenate two parameters. If the --flip flag
99 * is provided, then the result is the concatenation of two and one.
101 * @param string $one The first parameter.
102 * @param string $two The other parameter.
103 * @option boolean $flip Whether or not the second parameter should come first in the result.
105 * @usage bet alpha --flip
106 * Concatenate "alpha" and "bet".
107 * @arbitrary This annotation is here merely as a marker used in testing.
109 public function myCat($one, $two = '', array $options = ['flip' => false])
111 if ($options['flip']) {
112 return "{$two}{$one}";
114 return "{$one}{$two}";
120 public function myRepeat($one, $two = '', array $options = ['repeat' => 1])
122 return str_repeat("{$one}{$two}", $options['repeat']);
126 * This is the my:join command
128 * This command will join its parameters together. It can also reverse and repeat its arguments.
132 * Join a and b to produce "a,b"
134 * Example with no parameters or options
136 public function myJoin(array $args, array $options = ['flip' => false, 'repeat' => 1])
138 if ($options['flip']) {
139 $args = array_reverse($args);
141 $result = implode('', $args);
142 return str_repeat($result, $options['repeat']);
146 * This is a command with no options
148 * This command will concatenate two parameters.
150 * @param $one The first parameter.
151 * @param $two The other parameter.
154 * Concatenate "alpha" and "bet".
156 public function commandWithNoOptions($one, $two = 'default')
158 return "{$one}{$two}";
162 * This command work with app's input and output
164 * @command command:with-io-parameters
166 public function commandWithIOParameters(InputInterface $input, OutputInterface $output)
168 return $input->getFirstArgument();
172 * This command has no arguments--only options
174 * Return a result only if not silent.
176 * @option silent Supress output.
178 public function commandWithNoArguments(array $opts = ['silent|s' => false])
180 if (!$opts['silent']) {
181 return "Hello, world";
186 * Shortcut on annotation
188 * This command defines the option shortcut on the annotation instead of in the options array.
190 * @param $opts The options
191 * @option silent|s Supress output.
193 public function shortcutOnAnnotation(array $opts = ['silent' => false])
195 if (!$opts['silent']) {
196 return "Hello, world";
201 * This is the test:arithmatic command
203 * This command will add one and two. If the --negate flag
204 * is provided, then the result is negated.
206 * @command test:arithmatic
207 * @param integer $one The first number to add.
208 * @param integer $two The other number to add.
209 * @option negate Whether or not the result should be negated.
210 * @aliases arithmatic
211 * @usage 2 2 --negate
212 * Add two plus two and then negate.
217 public function testArithmatic($one, $two = 2, array $options = ['negate' => false, 'unused' => 'bob'])
219 $result = $one + $two;
220 if ($options['negate']) {
224 // Integer return codes are exit codes (errors), so
225 // return a the result as a string so that it will be printed.
230 * This is the test:state command
232 * This command tests to see if the state of the Commandfile instance
234 public function testState()
240 * This is the test:passthrough command
242 * This command takes a variable number of parameters as
243 * an array and returns them as a csv.
245 public function testPassthrough(array $params)
247 return implode(',', $params);
251 * This command wraps its parameter in []; its alter hook
252 * then wraps the result in <>.
254 public function testHook($parameter)
256 return "[$parameter]";
260 * Wrap the results of test:hook in <>.
262 * @hook alter test:hook
264 public function hookTestHook($result)
270 * This test is very similar to the preceding test, except
271 * it uses an annotation hook instead of a named-function hook.
277 public function testAnnotationHook($parameter)
279 return "($parameter)";
283 * Wrap the results of test:hook in whatever the @before and @after
284 * annotations contain.
286 * @hook alter @hookme
288 public function hookTestAnnotatedHook($result, CommandData $commandData)
290 $before = $commandData->annotationData()->get('before', '-');
291 $after = $commandData->annotationData()->get('after', '-');
292 return "$before$result$after";
296 * Alter the results of the hook with its command name.
298 * @hook alter @addmycommandname
300 public function hookAddCommandName($result, CommandData $commandData)
302 $annotationData = $commandData->annotationData();
303 return "$result from " . $annotationData['command'];
307 * Here is a hook with an explicit command annotation that we will alter
308 * with the preceeding hook
313 public function alterMe()
315 return "splendiferous";
319 * Here is another hook that has no command annotation that should be
320 * altered with the default value for the command name
324 public function alterMeToo()
326 return "fantabulous";
330 * @command test:replace-command
332 public function testReplaceCommand($value)
334 $this->output->writeln($value);
338 * @hook replace-command test:replace-command
340 public function hookTestReplaceCommandHook($value)
342 $this->output->writeln("bar");
346 * @hook pre-command test:post-command
348 public function hookTestPreCommandHook(CommandData $commandData)
350 // Use 'writeln' to detect order that hooks are called
351 $this->output->writeln("foo");
355 * @command test:post-command
357 public function testPostCommand($value)
359 $this->output->writeln($value);
363 * @hook post-command test:post-command
365 public function hookTestPostCommandHook($result, CommandData $commandData)
367 // Use 'writeln' to detect order that hooks are called
368 $this->output->writeln("baz");
371 public function testHello($who)
373 return "Hello, $who.";
376 public function testException($what)
378 throw new \Exception($what);
382 * @hook init test:hello
384 public function initializeTestHello($input, AnnotationData $annotationData)
386 $who = $input->getArgument('who');
388 $input->setArgument('who', 'Huey');
393 * @hook command-event test:hello
395 public function commandEventTestHello(ConsoleCommandEvent $event)
397 // Note that Symfony Console will not allow us to alter the
398 // input from this hook, so we'll just print something to
399 // show that this hook was executed.
400 $input = $event->getInput();
401 $who = $input->getArgument('who');
402 $this->output->writeln("Here comes $who!");
406 * @hook interact test:hello
408 public function interactTestHello($input, $output)
410 $who = $input->getArgument('who');
412 $input->setArgument('who', 'Goofey');
417 * @hook validate test:hello
419 public function validateTestHello($commandData)
421 $args = $commandData->arguments();
422 if ($args['who'] == 'Donald Duck') {
423 return new CommandError("I won't say hello to Donald Duck.");
425 if ($args['who'] == 'Drumph') {
426 throw new \Exception('Irrational value error.');
431 * Test default values in arguments
433 * @param string|null $one
434 * @param string|null $two
437 public function defaults($one = null, $two = null)
440 return "$one and $two";
445 return "nothing provided";
451 public function defaultOptionOne(array $options = ['foo' => '1'])
453 return "Foo is " . $options['foo'];
459 public function defaultOptionTwo(array $options = ['foo' => '2'])
461 return "Foo is " . $options['foo'];
467 public function defaultOptionNone(array $options = ['foo' => InputOption::VALUE_REQUIRED])
469 return "Foo is " . $options['foo'];
475 public function defaultOptionalValue(array $options = ['foo' => InputOption::VALUE_OPTIONAL])
477 return "Foo is " . var_export($options['foo'], true);
483 public function defaultOptionDefaultsToTrue(array $options = ['foo' => true])
485 return "Foo is " . var_export($options['foo'], true);
489 * This is the test:required-array-option command
491 * This command will print all the valused of passed option
496 public function testRequiredArrayOption(array $opts = ['arr|a' => []])
498 return implode(' ', $opts['arr']);
502 * This is the test:array-option command
504 * This command will print all the valused of passed option
509 public function testArrayOption(array $opts = ['arr|a' => ['1', '2', '3']])
511 return implode(' ', $opts['arr']);
515 * @command global-options-only
517 public function globalOptionsOnly($arg, array $options = [])
519 return "Arg is $arg, options[help] is " . var_export($options['help'], true) . "\n";