GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Failed Conditions
Push — develop ( efbb25...d778eb )
by Maxime
70:00 queued 35:27
created

src/Rocketeer/Console/Commands/AbstractCommand.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * This file is part of Rocketeer
5
 *
6
 * (c) Maxime Fabre <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 */
12
13
namespace Rocketeer\Console\Commands;
14
15
use League\Container\ContainerAwareInterface;
16
use Rocketeer\Console\Style\RocketeerStyle;
17
use Rocketeer\Interfaces\IdentifierInterface;
18
use Rocketeer\Tasks\AbstractTask;
19
use Rocketeer\Tasks\Closure;
20
use Rocketeer\Tasks\Plugins\Installer;
21
use Rocketeer\Traits\ContainerAwareTrait;
22
use Rocketeer\Traits\Properties\HasEventsTrait;
23
use Symfony\Component\Console\Command\Command;
24
use Symfony\Component\Console\Input\InputInterface;
25
use Symfony\Component\Console\Input\InputOption;
26
use Symfony\Component\Console\Output\OutputInterface;
27
28
/**
29
 * An abstract command with various helpers for all
30
 * subcommands to inherit.
31
 *
32
 * @mixin RocketeerStyle
33
 */
34
abstract class AbstractCommand extends Command implements IdentifierInterface, ContainerAwareInterface
35
{
36
    use ContainerAwareTrait;
37
    use HasEventsTrait;
38
39
    /**
40
     * @var InputInterface
41
     */
42
    protected $input;
43
44
    /**
45
     * @var RocketeerStyle
46
     */
47
    protected $output;
48
49
    /**
50
     * The console command name.
51
     *
52
     * @var string
53
     */
54
    protected $name;
55
56
    /**
57
     * The console command description.
58
     *
59
     * @var string
60
     */
61
    protected $description;
62
63
    /**
64
     * Whether the command's task should be built
65
     * into a pipeline or run straight.
66
     *
67
     * @var bool
68
     */
69
    protected $straight = false;
70
71
    /**
72
     * the task to execute on fire.
73
     *
74
     * @var \Rocketeer\Tasks\AbstractTask
75
     */
76
    protected $task;
77
78
    /**
79
     * @param \Rocketeer\Tasks\AbstractTask|null $task
80
     */
81
    public function __construct(AbstractTask $task = null)
82
    {
83
        parent::__construct($this->name);
84
85
        $this->setDescription($this->description);
86
        $this->specifyParameters();
87
88
        // If we passed a Task, bind its properties
89
        // to the command
90
        if ($task) {
91
            $this->task = $task;
92
93
            if (!$this->description && $description = $task->getDescription()) {
94
                $this->setDescription($description);
95
            }
96
        }
97
    }
98
99
    /**
100
     * @return InputInterface
101
     */
102
    public function getInput()
103
    {
104
        return $this->input;
105
    }
106
107
    /**
108
     * @return RocketeerStyle
109
     */
110
    public function getOutput()
111
    {
112
        return $this->output;
113
    }
114
115
    //////////////////////////////////////////////////////////////////////
116
    ////////////////////////////// ARGUMENTS /////////////////////////////
117
    //////////////////////////////////////////////////////////////////////
118
119
    /**
120
     * Get the console command arguments.
121
     *
122
     * @return array
123
     */
124
    protected function getArguments()
125
    {
126
        return [];
127
    }
128
129
    /**
130
     * Get the console command options.
131
     *
132
     * @return array
133
     */
134
    protected function getOptions()
135
    {
136
        // General options
137
        $global = [
138
            ['parallel', 'P', InputOption::VALUE_NONE, 'Run the tasks asynchronously instead of sequentially'],
139
            [
140
                'pretend',
141
                'p',
142
                InputOption::VALUE_NONE,
143
                'Shows which command would execute without actually doing anything',
144
            ],
145
        ];
146
147
        // Options that override the predefined configuration
148
        $overrides = [
149
            ['on', 'C', InputOption::VALUE_REQUIRED, 'The connection(s) to execute the Task in'],
150
            ['stage', 'S', InputOption::VALUE_REQUIRED, 'The stage to execute the Task in'],
151
            ['server', null, InputOption::VALUE_REQUIRED, 'The server to execute the Task in'],
152
            ['branch', 'B', InputOption::VALUE_REQUIRED, 'The branch to deploy'],
153
            ['release', null, InputOption::VALUE_REQUIRED, 'What to tag the release as'],
154
        ];
155
156
        // Additional credentials passed to Rocketeer
157
        $credentials = [
158
            ['host', null, InputOption::VALUE_REQUIRED, 'The host to use if asked'],
159
            ['root', null, InputOption::VALUE_REQUIRED, 'The root directory to use if asked'],
160
            ['username', null, InputOption::VALUE_REQUIRED, 'The username to use if asked'],
161
            ['password', null, InputOption::VALUE_REQUIRED, 'The password to use if asked'],
162
            ['key', null, InputOption::VALUE_REQUIRED, 'The key to use if asked'],
163
            ['keyphrase', null, InputOption::VALUE_REQUIRED, 'The keyphrase to use if asked'],
164
            ['repository', null, InputOption::VALUE_REQUIRED, 'The repository to use if asked'],
165
        ];
166
167
        return array_merge(
168
            $global,
169
            $overrides,
170
            $credentials
171
        );
172
    }
173
174
    /**
175
     * Specify the arguments and options on the command.
176
     */
177
    protected function specifyParameters()
178
    {
179
        // We will loop through all of the arguments and options for the command and
180
        // set them all on the base command instance. This specifies what can get
181
        // passed into these commands as "parameters" to control the execution.
182
        foreach ($this->getArguments() as $arguments) {
183
            $this->addArgument(...$arguments);
184
        }
185
186
        foreach ($this->getOptions() as $options) {
187
            $this->addOption(...$options);
188
        }
189
    }
190
191
    //////////////////////////////////////////////////////////////////////
192
    ////////////////////////////// CONTAINER /////////////////////////////
193
    //////////////////////////////////////////////////////////////////////
194
195
    /**
196
     * @param string $key
197
     *
198
     * @return mixed
199
     */
200
    public function __get($key)
201
    {
202
        $key = $this->getLocatorHandle($key);
203
        if ($key === 'command') {
204
            return $this;
205
        }
206
207
        return $this->container->get($key);
208
    }
209
210
    /**
211
     * @param string $name
212
     * @param array  $arguments
213
     *
214
     * @return mixed
215
     */
216
    public function __call($name, $arguments)
217
    {
218
        // Defer calls to output
219
        if (method_exists($this->output, $name)) {
220
            return $this->output->$name(...$arguments);
221
        }
222
    }
223
224
    /**
225
     * Get the task this command executes.
226
     *
227
     * @return AbstractTask
228
     */
229
    public function getTask()
230
    {
231
        return $this->task;
232
    }
233
234
    /**
235
     * Get a global identifier for this entity.
236
     *
237
     * @return string
238
     */
239
    public function getIdentifier()
240
    {
241
        return 'commands.'.str_replace(':', '.', $this->name);
242
    }
243
244
    //////////////////////////////////////////////////////////////////////
245
    ////////////////////////////// EXECUTION /////////////////////////////
246
    //////////////////////////////////////////////////////////////////////
247
248
    /**
249
     * Execute the console command.
250
     *
251
     * @param \Symfony\Component\Console\Input\InputInterface   $input
252
     * @param \Symfony\Component\Console\Output\OutputInterface $output
253
     *
254
     * @return mixed
255
     */
256
    protected function execute(InputInterface $input, OutputInterface $output)
257
    {
258
        $this->input = $input;
259
        $this->output = new RocketeerStyle($input, $output);
260
261
        return $this->container->call([$this, 'fire']);
262
    }
263
264
    /**
265
     * Fire a Tasks Queue.
266
     *
267
     * @param string|string[]|Closure|Closure[]|\Rocketeer\Tasks\AbstractTask|\Rocketeer\Tasks\AbstractTask[] $tasks
268
     *
269
     * @return int
270
     */
271
    protected function fireTasksQueue($tasks)
272
    {
273
        $this->prepareEnvironment();
274
275
        // Fire tasks and events arround them
276
        $status = $this->runWithBeforeAfterEvents(function () use ($tasks) {
277
            if ($this->straight) {
278
                return $this->builder->buildTask($tasks)->fire();
279
            }
280
281
            $pipeline = $this->queue->run($tasks);
282
283
            return $pipeline->succeeded();
284
        });
285
286
        // Remove command instance
287
        $this->container->remove('command');
288
289
        // Save history to logs
290
        $this->explainer->info('Saved logs to '.$this->logs->getLogsRealpath());
291
292
        return $status ? 0 : 1;
293
    }
294
295
    /**
296
     * Run the tasks.
297
     *
298
     * @return mixed
299
     */
300
    abstract public function fire();
301
302
    //////////////////////////////////////////////////////////////////////
303
    /////////////////////////////// INPUT ////////////////////////////////
304
    //////////////////////////////////////////////////////////////////////
305
306
    /**
307
     * Get the value of a command argument.
308
     *
309
     * @param string $key
310
     *
311
     * @return string|array
312
     */
313
    public function argument($key = null)
314
    {
315
        if (is_null($key)) {
316
            return $this->input->getArguments();
317
        }
318
319
        return $this->input->getArgument($key);
320
    }
321
322
    /**
323
     * Get the value of a command option.
324
     *
325
     * @param string $key
326
     *
327
     * @return string|array
328
     */
329
    public function option($key = null)
330
    {
331
        if (is_null($key)) {
332
            return $this->input->getOptions();
333
        }
334
335
        return $this->input->getOption($key);
336
    }
337
338
    //////////////////////////////////////////////////////////////////////
339
    ////////////////////////////// HELPERS ///////////////////////////////
340
    //////////////////////////////////////////////////////////////////////
341
342
    /**
343
     * Time an operation and display it afterwards.
344
     *
345
     * @param callable $callback
346
     *
347
     * @return bool
348
     */
349
    public function time(callable $callback)
350
    {
351
        $results = $this->timer->time($this, $callback);
352
        $time = $this->timer->getLatestTime($this);
353
354
        $this->explainer->line('Execution time: <comment>'.$time.'s</comment>');
355
356
        return $results;
357
    }
358
359
    /**
360
     * Prepare the environment.
361
     */
362
    protected function prepareEnvironment()
363
    {
364
        // Bind command to container
365
        $this->container->add('command', $this);
366
367
        // Set active connections from flag
368
        if ($connections = $this->command->option('on')) {
369
            $this->connections->setActiveConnections($connections);
370
        }
371
372
        // Setup plugins if not setup already
373
        $vendor = $this->paths->getRocketeerPath().DS.'vendor';
374
        if (!$this->files->has($vendor)) {
375
            $this->queue->execute(Installer::class);
376
            $this->bootstrapper->bootstrapUserCode();
0 ignored issues
show
Documentation Bug introduced by Maxime Fabre
The method bootstrapUserCode does not exist on object<Rocketeer\Service...tstrapper\Bootstrapper>? 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...
377
        }
378
    }
379
}
380