5 * Contains \Drupal\Console\Core\Command\Chain\ChainCommand.
8 namespace Drupal\Console\Core\Command\Chain;
10 use Dflydev\PlaceholderResolver\DataSource\ArrayDataSource;
11 use Dflydev\PlaceholderResolver\RegexPlaceholderResolver;
12 use Symfony\Component\Console\Input\InputInterface;
13 use Symfony\Component\Console\Output\OutputInterface;
14 use Symfony\Component\Console\Input\ArrayInput;
15 use Symfony\Component\Console\Input\InputOption;
16 use Symfony\Component\Filesystem\Filesystem;
17 use Symfony\Component\Yaml\Parser;
18 use Drupal\Console\Core\Utils\ChainQueue;
19 use Drupal\Console\Core\Utils\ChainDiscovery;
20 use Drupal\Console\Core\Command\Shared\InputTrait;
25 * @package Drupal\Console\Core\Command\Chain
27 class ChainCommand extends BaseCommand
34 protected $chainQueue;
37 * ChainCommand constructor.
39 * @param ChainQueue $chainQueue
40 * @param ChainDiscovery $chainDiscovery
42 public function __construct(
43 ChainQueue $chainQueue,
44 ChainDiscovery $chainDiscovery
46 $this->chainQueue = $chainQueue;
48 parent::__construct($chainDiscovery);
49 $this->ignoreValidationErrors();
55 protected function configure()
59 ->setDescription($this->trans('commands.chain.description'))
63 InputOption::VALUE_OPTIONAL,
64 $this->trans('commands.chain.options.file')
71 protected function interact(InputInterface $input, OutputInterface $output)
73 $file = $this->getFileOption();
75 $chainContent = $this->chainDiscovery
78 $this->getOptionsAsArray()
81 $inlinePlaceHolders = $this->chainDiscovery
82 ->extractInlinePlaceHolders($chainContent);
84 foreach ($inlinePlaceHolders as $inlinePlaceHolder => $inlinePlaceHolderValue) {
85 if (is_array($inlinePlaceHolderValue)) {
86 $placeHolderValue = $this->getIo()->choice(
88 $this->trans('commands.chain.messages.select-value-for-placeholder'),
91 $inlinePlaceHolderValue,
92 current($inlinePlaceHolderValue)
95 $placeHolderValue = $this->getIo()->ask(
98 'commands.chain.messages.enter-value-for-placeholder'
102 $inlinePlaceHolderValue
106 if (!$input->hasOption($inlinePlaceHolder)) {
110 InputOption::VALUE_OPTIONAL,
116 $input->setOption($inlinePlaceHolder, $placeHolderValue);
123 protected function execute(InputInterface $input, OutputInterface $output)
125 $interactive = false;
127 $file = $input->getOption('file');
129 $this->getIo()->error($this->trans('commands.chain.messages.missing-file'));
134 $fileSystem = new Filesystem();
135 $file = calculateRealPath($file);
137 if (!$fileSystem->exists($file)) {
138 $this->getIo()->error(
140 $this->trans('commands.chain.messages.invalid-file'),
148 $chainContent = $this->chainDiscovery
151 $this->getOptionsAsArray()
154 // Resolve inlinePlaceHolders
155 $inlinePlaceHolders = $this->chainDiscovery
156 ->extractInlinePlaceHolders($chainContent);
158 if ($inlinePlaceHolders) {
159 $this->getIo()->error(
161 $this->trans('commands.chain.messages.missing-inline-placeholders'),
162 implode(', ', array_keys($inlinePlaceHolders))
166 $this->getIo()->info(
168 'commands.chain.messages.set-inline-placeholders'
172 foreach ($inlinePlaceHolders as $inlinePlaceHolder => $inlinePlaceHolderValue) {
173 $missingInlinePlaceHoldersMessage = sprintf(
176 strtoupper($inlinePlaceHolder)
179 $this->getIo()->block($missingInlinePlaceHoldersMessage);
185 // Resolve environmentPlaceHolders
186 $environmentPlaceHolders = $this->chainDiscovery
187 ->extractEnvironmentPlaceHolders($chainContent);
188 if ($environmentPlaceHolders) {
189 $this->getIo()->error(
192 'commands.chain.messages.missing-environment-placeholders'
196 array_values($environmentPlaceHolders)
201 $this->getIo()->info(
203 'commands.chain.messages.set-environment-placeholders'
207 foreach ($environmentPlaceHolders as $envPlaceHolder) {
208 $missingEnvironmentPlaceHoldersMessage = sprintf(
209 'export %s=%s_VALUE',
211 strtoupper($envPlaceHolder)
214 $this->getIo()->block($missingEnvironmentPlaceHoldersMessage);
220 $parser = new Parser();
221 $chainData = $parser->parse($chainContent);
224 if (array_key_exists('commands', $chainData)) {
225 $commands = $chainData['commands'];
228 $chainInlineOptions = $input->getOptions();
229 unset($chainInlineOptions['file']);
231 foreach ($commands as $command) {
233 $arguments = !empty($command['arguments']) ? $command['arguments'] : [];
234 $options = !empty($command['options']) ? $command['options'] : [];
236 foreach ($arguments as $key => $value) {
237 $moduleInputs[$key] = is_null($value) ? '' : $value;
240 foreach ($options as $key => $value) {
241 $moduleInputs['--'.$key] = is_null($value) ? '' : $value;
244 // Get application global options
245 foreach ($this->getApplication()->getDefinition()->getOptions() as $option) {
246 $optionName = $option->getName();
247 if (array_key_exists($optionName, $chainInlineOptions)) {
248 $optionValue = $chainInlineOptions[$optionName];
249 // Set global option only if is not available in command options
250 if (!isset($moduleInputs['--' . $optionName]) && $optionValue) {
251 $moduleInputs['--' . $optionName] = $optionValue;
256 $application = $this->getApplication();
257 $callCommand = $application->find($command['command']);
263 $this->getIo()->text($command['command']);
264 $this->getIo()->newLine();
266 $input = new ArrayInput($moduleInputs);
267 if (!is_null($interactive)) {
268 $input->setInteractive($interactive);
271 $allowFailure = array_key_exists('allow_failure', $command)?$command['allow_failure']:false;
273 $callCommand->run($input, $this->getIo());
274 } catch (\Exception $e) {
275 if (!$allowFailure) {
276 $this->getIo()->error($e->getMessage());