Completed
Push — master ( 5d806c...481a63 )
by Greg
04:24 queued 01:12
created

RoboFile::tryOptRequired()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
use Robo\Result;
3
4
use Consolidation\AnnotatedCommand\CommandData;
5
use Consolidation\OutputFormatters\Options\FormatterOptions;
6
use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
7
use Consolidation\OutputFormatters\StructuredData\PropertyList;
8
use Symfony\Component\Console\Input\InputOption;
9
10
/**
11
 * Example RoboFile.
12
 *
13
 * To test:
14
 *
15
 * $ cd ROBO_PROJECT/examples
16
 * $ ../robo try:success
17
 *
18
 *   - or -
19
 *
20
 * $ cd ROBO_PROJECT
21
 * $ ./robo -f examples try:formatters
22
 */
23
class RoboFile extends \Robo\Tasks
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
24
{
25
   /**
26
     * Watch a file.
27
     *
28
     * Demonstrates the 'watch' command. Runs 'composer update' any time
29
     * composer.json changes.
30
     */
31
    public function tryWatch()
32
    {
33
        $this->taskWatch()->monitor(['composer.json', 'composer.lock'], function () {
34
            $this->taskComposerUpdate()->run();
35
        })->run();
36
    }
37
38
    /**
39
     * Demonstrates Robo input APIs.
40
     */
41
    public function tryInput()
42
    {
43
        $this->say('The <b>expression</b> <bogus>is</bogus> <info>a < b</> it even works');
44
        $answer = $this->ask('how are you?');
45
        $this->say('You are '.$answer);
46
        $yes = $this->confirm('Do you want one more question?');
47
        if (!$yes) {
48
            return Result::cancelled();
49
        }
50
        $lang = $this->askDefault('what is your favorite scripting language?', 'PHP');
51
        $this->say($lang);
52
        $pin = $this->askHidden('Ok, now tell your PIN code (it is hidden)');
53
        $this->yell('Ha-ha, your pin code is: '.$pin);
54
        $this->say('Bye!');
55
    }
56
57
    /**
58
     * Demonstrates parallel execution.
59
     *
60
     * @option $printed Print the output of each process.
61
     * @option $error Include an extra process that fails.
62
     */
63
    public function tryPara($options = ['printed' => false, 'error' => false])
64
    {
65
        $dir = dirname(__DIR__);
66
        $para = $this->taskParallelExec()
67
            ->printed($options['printed'])
68
            ->process("php $dir/tests/_data/parascript.php hey 4")
69
            ->process("php $dir/tests/_data/parascript.php hoy 3")
70
            ->process("php $dir/tests/_data/parascript.php gou 2")
71
            ->process("php $dir/tests/_data/parascript.php die 1");
72
        if ($options['error']) {
73
            $para->process("ls $dir/tests/_data/filenotfound");
74
        }
75
        return $para->run();
76
    }
77
78
    /**
79
     * try:opt-required
80
     */
81
    public function tryOptRequired($options = ['foo' => InputOption::VALUE_REQUIRED])
82
    {
83
        print "foo is " . $options['foo'];
84
    }
85
86
    /**
87
     * Demonstrates Robo argument passing.
88
     *
89
     * @param string $a The first parameter. Required.
90
     * @param string $b The second parameter. Optional.
91
     */
92
    public function tryArgs($a, $b = 'default')
93
    {
94
        $this->say("The parameter a is $a and b is $b");
95
    }
96
97
    /**
98
     * Demonstrate Robo variable argument passing.
99
     *
100
     * @param $a A list of commandline parameters.
101
     */
102
    public function tryArrayArgs(array $a)
103
    {
104
        $this->say("The parameters passed are:\n" . var_export($a, true));
105
    }
106
107
    /**
108
     * Demonstrate Robo boolean options.
109
     *
110
     * @param $opts The options.
111
     * @option boolean $silent Supress output.
112
     */
113
    public function tryOptbool($opts = ['silent|s' => false])
114
    {
115
        if (!$opts['silent']) {
116
            $this->say("Hello, world");
117
        }
118
    }
119
120
    /**
121
     * Demonstrate the use of the PHP built-in webserver.
122
     */
123
    public function tryServer()
124
    {
125
        return $this->taskServer(8000)
126
            ->dir('site')
127
            ->arg('site/index.php')
128
            ->run();
129
    }
130
131
    /**
132
     * Demonstrate the use of the Robo open-browser task.
133
     */
134
    public function tryOpenBrowser()
135
    {
136
        return $this->taskOpenBrowser([
137
            'http://robo.li',
138
            'https://github.com/consolidation-org/Robo'
139
            ])->run();
140
    }
141
142
    /**
143
     * Demonstrate Robo error output and command failure.
144
     */
145
    public function tryError()
146
    {
147
        return $this->taskExec('ls xyzzy' . date('U'))->dir('/tmp')->run();
148
    }
149
150
    /**
151
     * Demonstrate Robo standard output and command success.
152
     */
153
    public function trySuccess()
154
    {
155
        return $this->_exec('pwd');
156
    }
157
158
    /**
159
     * @field-labels
160
     *   name: Name
161
     *   species: Species
162
     *   legs: Legs
163
     *   food: Favorite Food
164
     *   id: Id
165
     * @return PropertyList
166
     */
167
    public function tryInfo()
168
    {
169
        $outputData = [
170
            'name' => 'fluffy',
171
            'species' => 'cat',
172
            'legs' => 4,
173
            'food' => 'salmon',
174
            'id' => 389245032,
175
        ];
176
177
        $data = new PropertyList($outputData);
178
179
        // Add a render function to transform cell data when the output
180
        // format is a table, or similar.  This allows us to add color
181
        // information to the output without modifying the data cells when
182
        // using yaml or json output formats.
183
        $data->addRendererFunction(
184
            // n.b. There is a fourth parameter $rowData that may be added here.
185
            function ($key, $cellData, FormatterOptions $options) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
186
                if ($key == 'name') {
187
                    return "<info>$cellData</>";
188
                }
189
                return $cellData;
190
            }
191
        );
192
193
        return $data;
194
    }
195
196
    /**
197
     * Demonstrate Robo formatters.  Default format is 'table'.
198
     *
199
     * @field-labels
200
     *   first: I
201
     *   second: II
202
     *   third: III
203
     * @default-string-field second
204
     * @usage try:formatters --format=yaml
205
     * @usage try:formatters --format=csv
206
     * @usage try:formatters --fields=first,third
207
     * @usage try:formatters --fields=III,II
208
     * @aliases tf
209
     *
210
     * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields
211
     */
212
    public function tryFormatters($somthing = 'default', $options = ['format' => 'table', 'fields' => ''])
0 ignored issues
show
Unused Code introduced by
The parameter $somthing is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
213
    {
214
        $outputData = [
215
            'en' => [ 'first' => 'One',  'second' => 'Two',  'third' => 'Three' ],
216
            'de' => [ 'first' => 'Eins', 'second' => 'Zwei', 'third' => 'Drei'  ],
217
            'jp' => [ 'first' => 'Ichi', 'second' => 'Ni',   'third' => 'San'   ],
218
            'es' => [ 'first' => 'Uno',  'second' => 'Dos',  'third' => 'Tres'  ],
219
        ];
220
        return new RowsOfFields($outputData);
221
    }
222
223
    /**
224
     * Try word wrapping
225
     *
226
     * @field-labels
227
     *   first: First
228
     *   second: Second
229
     *
230
     * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields
231
     */
232
    public function tryWrap()
233
    {
234
        $data = [
235
            [
236
                'first' => 'This is a really long cell that contains a lot of data. When it is rendered, it should be wrapped across multiple lines.',
237
                'second' => 'This is the second column of the same table. It is also very long, and should be wrapped across multiple lines, just like the first column.',
238
            ]
239
        ];
240
        return new RowsOfFields($data);
241
    }
242
243
    /**
244
     * Demonstrate an alter hook with an option
245
     *
246
     * @hook alter try:formatters
247
     * @option $french Add a row with French numbers.
248
     * @usage try:formatters --french
249
     */
250
    public function alterFormatters($result, CommandData $commandData)
251
    {
252
        if ($commandData->input()->getOption('french')) {
253
            $result['fr'] = [ 'first' => 'Un',  'second' => 'Deux',  'third' => 'Trois'  ];
254
        }
255
256
        return $result;
257
    }
258
259
    /**
260
     * Demonstrate what happens when a command or a task
261
     * throws an exception.  Note that typically, Robo commands
262
     * should return Result objects rather than throw exceptions.
263
     */
264
    public function tryException($options = ['task' => false])
265
    {
266
        if (!$options['task']) {
267
            throw new RuntimeException('Command failed with an exception.');
268
        }
269
        return new ExceptionTask('Task failed with an exception.');
270
    }
271
272
    /**
273
     * Demonstrate deprecated task behavior.
274
     *
275
     * Demonstrate what happens when using a task that is created via
276
     * direct instantiation, which omits initialization done by the
277
     * container.  Emits a warning message.
278
     */
279
    public function tryDeprecated()
280
    {
281
        // Calling 'new' directly without manually setting
282
        // up dependencies will result in a deprecation warning.
283
        // @see RoboFile::trySuccess()
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
284
        return (new \Robo\Task\Base\Exec('pwd'))->run();
285
    }
286
287
    /**
288
     * Demonstrate the use of a collection builder to chain multiple tasks
289
     * together into a collection, which is executed once constructed.
290
     *
291
     * For demonstration purposes only; this could, of course, be done
292
     * with a single FilesystemStack.
293
     */
294
    public function tryBuilder()
295
    {
296
        return $this->collectionBuilder()
0 ignored issues
show
Documentation Bug introduced by
The method taskFilesystemStack does not exist on object<Robo\Collection\CollectionBuilder>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
297
            ->taskFilesystemStack()
298
                ->mkdir('a')
299
                ->touch('a/a.txt')
300
            ->taskFilesystemStack()
301
                ->mkdir('a/b')
302
                ->touch('a/b/b.txt')
303
            ->taskFilesystemStack()
304
                ->mkdir('a/b/c')
305
                ->touch('a/b/c/c.txt')
306
            ->run();
307
    }
308
309
    public function tryBuilderRollback()
310
    {
311
        // This example will create two builders, and add
312
        // the first one as a child of the second in order
313
        // to demonstrate nested rollbacks.
314
        $collection = $this->collectionBuilder()
0 ignored issues
show
Documentation Bug introduced by
The method taskFilesystemStack does not exist on object<Robo\Collection\CollectionBuilder>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
315
            ->taskFilesystemStack()
316
                ->mkdir('g')
317
                ->touch('g/g.txt')
318
            ->rollback(
319
                $this->taskDeleteDir('g')
320
            )
321
            ->taskFilesystemStack()
322
                ->mkdir('g/h')
323
                ->touch('g/h/h.txt')
324
            ->taskFilesystemStack()
325
                ->mkdir('g/h/i/c')
326
                ->touch('g/h/i/i.txt');
327
328
        return $this->collectionBuilder()
0 ignored issues
show
Documentation Bug introduced by
The method taskExec does not exist on object<Robo\Collection\CollectionBuilder>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
329
            ->progressMessage('Start recursive collection')
330
            ->addTask($collection)
331
            ->progressMessage('Done with recursive collection')
332
            ->taskExec('ls xyzzy' . date('U'))
333
                ->dir('/tmp')
334
            ->run();
335
    }
336
337
    public function tryWorkdir()
338
    {
339
        // This example works like tryBuilderRollback,
340
        // but does equivalent operations using a working
341
        // directory. The working directory is deleted on rollback
342
        $collection = $this->collectionBuilder();
343
344
        $workdir = $collection->workDir('w');
345
346
        $collection
0 ignored issues
show
Documentation Bug introduced by
The method taskFilesystemStack does not exist on object<Robo\Collection\CollectionBuilder>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
347
            ->taskFilesystemStack()
348
                ->touch("$workdir/g.txt")
349
            ->taskFilesystemStack()
350
                ->mkdir("$workdir/h")
351
                ->touch("$workdir/h/h.txt")
352
            ->taskFilesystemStack()
353
                ->mkdir("$workdir/h/i/c")
354
                ->touch("$workdir/h/i/i.txt");
355
356
        return $this->collectionBuilder()
0 ignored issues
show
Documentation Bug introduced by
The method taskExec does not exist on object<Robo\Collection\CollectionBuilder>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
357
            ->progressMessage('Start recursive collection')
358
            ->addTask($collection)
359
            ->progressMessage('Done with recursive collection')
360
            ->taskExec('ls xyzzy' . date('U'))
361
                ->dir('/tmp')
362
            ->run();
363
    }
364
365
    /**
366
     * Demonstrates Robo temporary directory usage.
367
     */
368
    public function tryTmpDir()
369
    {
370
        // Set up a collection to add tasks to
371
        $collection = $this->collectionBuilder();
372
373
        // Get a temporary directory to work in. Note that we get a path
374
        // back, but the directory is not created until the task runs.
375
        $tmpPath = $collection->tmpDir();
376
377
        $result = $collection
0 ignored issues
show
Documentation Bug introduced by
The method taskWriteToFile does not exist on object<Robo\Collection\CollectionBuilder>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
378
            ->taskWriteToFile("$tmpPath/file.txt")
379
                ->line('Example file')
380
            ->run();
381
382
        if (is_dir($tmpPath)) {
383
            $this->say("The temporary directory at $tmpPath was not cleaned up after the collection completed.");
384
        } else {
385
            $this->say("The temporary directory at $tmpPath was automatically deleted.");
386
        }
387
388
        return $result;
389
    }
390
391
    /**
392
     * Description
393
     * @param $options
394
     * @option delay Miliseconds delay
395
     * @return type
396
     */
397
    public function tryProgress($options = ['delay' => 500])
398
    {
399
        $delay = $options['delay'];
400
        $delayUntilProgressStart = \Robo\Robo::config()->get(\Robo\Config::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL);
401
        $this->say("Progress bar will display after $delayUntilProgressStart seconds of activity.");
402
403
        $processList = range(1, 10);
404
        return $this->collectionBuilder()
0 ignored issues
show
Documentation Bug introduced by
The method taskForEach does not exist on object<Robo\Collection\CollectionBuilder>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
405
            ->taskForEach($processList)
406
                ->iterationMessage('Processing {value}')
407
                ->call(
408
                    function ($value) use($delay) {
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
409
                        // TaskForEach::call should only be used to do
410
                        // non-Robo operations. To use Robo tasks in an
411
                        // iterator, @see TaskForEach::withBuilder.
412
                        usleep($delay * 1000); // delay units: msec, usleep units: usec
413
                    }
414
                )
415
            ->run();
416
    }
417
418
    public function tryIter()
419
    {
420
        $workdir = 'build/iter-example';
421
        $this->say("Creating sample direcories in $workdir.");
422
423
        $processList = ['cats', 'dogs', 'sheep', 'fish', 'horses', 'cows'];
424
        return $this->collectionBuilder()
0 ignored issues
show
Documentation Bug introduced by
The method taskFilesystemStack does not exist on object<Robo\Collection\CollectionBuilder>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
425
            ->taskFilesystemStack()
426
                ->mkdir($workdir)
427
            ->taskCleanDir($workdir)
428
            ->taskForEach($processList)
429
                ->withBuilder(
430
                    function ($builder, $key, $value) use ($workdir) {
431
                        return $builder
432
                            ->taskFilesystemStack()
433
                                ->mkdir("$workdir/$value");
434
                    }
435
                )
436
            ->run();
437
    }
438
}
439
440
class ExceptionTask extends \Robo\Task\BaseTask
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
441
{
442
    protected $message;
443
444
    public function __construct($message)
445
    {
446
        $this->message = $message;
447
    }
448
449
    public function run()
450
    {
451
        throw new RuntimeException($this->message);
452
    }
453
}
454