Issues (10)

src/Robo/Plugin/Commands/YamlCommands.php (1 issue)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpTaskman\Core\Robo\Plugin\Commands;
6
7
use Consolidation\AnnotatedCommand\AnnotatedCommand;
8
use PhpTaskman\CoreTasks\Plugin\Task\CollectionFactoryTask;
9
use Robo\Collection\CollectionBuilder;
10
use Robo\Contract\VerbosityThresholdInterface;
11
use Robo\Exception\TaskException;
12
use Symfony\Component\Console\Event\ConsoleCommandEvent;
13
14
/**
15
 * Class DynamicCommands.
16
 */
17
final class YamlCommands extends AbstractCommands
18
{
19
    /**
20
     * Bind input values of custom command options to config entries.
21
     *
22
     * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event
23
     *
24
     * @hook pre-command-event *
25
     */
26
    public function bindInputOptionsToConfig(ConsoleCommandEvent $event): void
27
    {
28
        $command = $event->getCommand();
29
30
        if (null === $command) {
31
            return;
32
        }
33
34
        if (AnnotatedCommand::class !== \get_class($command)) {
35
            return;
36
        }
37
38
        if (!($command instanceof AnnotatedCommand)) {
39
            return;
40
        }
41
42
        /** @var \Consolidation\AnnotatedCommand\AnnotatedCommand $command */
43
        /** @var \Consolidation\AnnotatedCommand\AnnotationData $annotatedData */
44
        $annotatedData = $command->getAnnotationData();
45
46
        if (!$annotatedData->get('dynamic-command')) {
47
            return;
48
        }
49
50
        // Dynamic commands may define their own options bound to specific configuration. Dynamically set the
51
        // configuration from command options.
52
        $config = $this->getConfig();
53
        $commands = $config->get('commands');
54
55
        if (empty($commands[$command->getName()]['options'])) {
56
            return;
57
        }
58
59
        foreach ($commands[$command->getName()]['options'] as $optionName => $option) {
60
            if (empty($option['config']) && $event->getInput()->hasOption($optionName)) {
61
                continue;
62
            }
63
64
            $inputValue = $event->getInput()->getOption($optionName);
65
66
            if (null === $inputValue) {
67
                continue;
68
            }
69
70
            $config->set(
71
                $option['config'],
72
                $event->getInput()->getOption($optionName)
73
            );
74
        }
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function getConfigurationFile(): string
81
    {
82
        return __DIR__ . '/../../../../config/commands/default.yml';
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88
    public function getDefaultConfigurationFile(): string
89
    {
90
        return __DIR__ . '/../../../../config/default.yml';
91
    }
92
93
    /**
94
     * Run a task.
95
     *
96
     * @dynamic-command true
97
     *
98
     * @throws \Robo\Exception\TaskException
99
     *
100
     * @return \Robo\Collection\CollectionBuilder
101
     */
102
    public function runTasks(): CollectionBuilder
103
    {
104
        $command = $this->input()->getArgument('command');
105
106
        if (!\is_string($command)) {
107
            throw new TaskException($this, 'The command must be a string.');
108
        }
109
110
        $inputOptions = [];
111
112
        foreach ($this->input()->getOptions() as $name => $value) {
113
            if ($this->input()->hasParameterOption('--' . $name)) {
114
                $inputOptions[$name] = $value;
115
            }
116
        }
117
118
        $command = $this->getConfig()->get('commands.' . $command);
119
120
        // Handle different types of command definitions.
121
        if (isset($command['tasks'])) {
122
            $arguments = [
123
                'tasks' => $command['tasks'],
124
                'options' => $inputOptions,
125
                'preconditions' => $command['preconditions'] ?? [],
126
            ];
127
128
            if (\is_string($arguments['preconditions'])) {
129
                $arguments['preconditions'] = [$arguments['preconditions']];
130
            }
131
132
            /** @var CollectionFactoryTask $preconditionsTask */
133
            $preconditionsTask = $this->task(CollectionFactoryTask::class);
134
            $preconditionsTask->setVerbosityThreshold(VerbosityThresholdInterface::VERBOSITY_DEBUG);
135
            $preconditionsTask->setTaskArguments([
136
                'tasks' => $arguments['preconditions'],
137
                'options' => [],
138
            ]);
139
140
            if (false === $preconditionsTask->run()->wasSuccessful()) {
141
                $arguments['tasks'] = [];
142
            }
143
        } else {
144
            $arguments = [
145
                'tasks' => $command,
146
                'options' => [],
147
            ];
148
        }
149
150
        /** @var CollectionFactoryTask $collectionFactory */
151
        $collectionFactory = $this->task(CollectionFactoryTask::class);
152
153
        return $collectionFactory->setTaskArguments($arguments);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $collectionFactor...skArguments($arguments) returns the type PhpTaskman\CoreTasks\Plu...k\CollectionFactoryTask which is incompatible with the type-hinted return Robo\Collection\CollectionBuilder.
Loading history...
154
    }
155
}
156