Skip to content

Commit 8b74e0c

Browse files
committed
Merge branch 'release/3.5.22'
2 parents d454f2b + e4e0487 commit 8b74e0c

30 files changed

+493
-94
lines changed

Changelog.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Changelog
22

3+
## 3.5.22 / 2020-10-18
4+
===================
5+
6+
### Fixed:
7+
* Fix error in scaffolder which prevented to ask for the project name
8+
* Try to prevent timeouts when using k8s
9+
* Set tty flag for new shells
10+
11+
### Changed:
12+
* Refactor how scripts and scaffolders handle callbacks
13+
* Enhance argument parsing, updated test-coverage
14+
* Allow `inheritsFrom` with absolute file names
15+
* Update vuepress
16+
* Refactor how options are passed to the shell-provider.
17+
318
## 3.5.21 / 2020-10-11
419

520
### Fixed:

src/Command/BaseCommand.php

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Phabalicious\Exception\ValidationFailedException;
1414
use Phabalicious\Exception\MissingHostConfigException;
1515
use Phabalicious\ShellCompletion\FishShellCompletionContext;
16+
use Phabalicious\ShellProvider\ShellOptions;
1617
use Phabalicious\ShellProvider\ShellProviderInterface;
1718
use Phabalicious\Utilities\ParallelExecutor;
1819
use Phabalicious\Utilities\Utilities;
@@ -201,18 +202,31 @@ public function runCommand(string $command, array $args, InputInterface $origina
201202
return $cmd->run($input, $output);
202203
}
203204

205+
/**
206+
* @param OutputInterface $output
207+
* @return ShellOptions
208+
*/
209+
protected function getSuitableShellOptions(OutputInterface $output): ShellOptions
210+
{
211+
$options = new ShellOptions();
212+
$options
213+
->setUseTty($output->isDecorated())
214+
->setQuiet($output->isQuiet());
215+
return $options;
216+
}
217+
204218
/**
205219
* @param SymfonyStyle $io
206220
* @param ShellProviderInterface $shell
207221
* @param array $command
208-
* @param bool $use_tty
222+
* @param ShellOptions|null $options
209223
* @return Process
210224
*/
211225
protected function startInteractiveShell(
212226
SymfonyStyle $io,
213227
ShellProviderInterface $shell,
214228
array $command = [],
215-
$use_tty = true
229+
ShellOptions $options = null
216230
) {
217231
$fn = function ($type, $buffer) use ($io) {
218232
if ($type == Process::ERR) {
@@ -221,20 +235,22 @@ protected function startInteractiveShell(
221235
$io->write($buffer);
222236
}
223237
};
238+
if (!$options) {
239+
$options = new ShellOptions();
240+
}
224241

225-
$options = ['tty' => $use_tty];
226242
/** @var Process $process */
227243
if (!empty($command)) {
228-
$options['shell_provided'] = true;
244+
$options->setShellExecutableProvided(true);
229245
$command = $shell->wrapCommandInLoginShell($command);
230246
}
231247
$process = $shell->createShellProcess($command, $options);
232-
if ($use_tty) {
248+
if ($options->useTty()) {
233249
$stdin = fopen('php://stdin', 'r');
234250
$process->setInput($stdin);
235251
}
236252
$process->setTimeout(0);
237-
$process->setTty($use_tty);
253+
$process->setTty($options->useTty());
238254
$process->start($fn);
239255
$process->wait($fn);
240256
if ($process->isTerminated() && !$process->isSuccessful()) {

src/Command/DrupalConsoleCommand.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
6060

6161
$output->writeln('<info>Starting drupal-console on `' . $host_config['configName'] . '`');
6262

63-
$process = $this->startInteractiveShell($context->io(), $shell, $command, $output->isDecorated());
63+
$options = $this->getSuitableShellOptions($output);
64+
$process = $this->startInteractiveShell($context->io(), $shell, $command, $options);
6465

6566
return $process->getExitCode();
6667
}

src/Command/DrushCommand.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Phabalicious\Command;
44

55
use Phabalicious\Method\TaskContext;
6+
use Phabalicious\ShellProvider\ShellOptions;
67
use Symfony\Component\Console\Input\InputArgument;
78
use Symfony\Component\Console\Input\InputInterface;
89
use Symfony\Component\Console\Output\OutputInterface;
@@ -59,7 +60,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
5960

6061
$output->writeln('<info>Starting drush on `' . $host_config['configName'] . '`');
6162

62-
$process = $this->startInteractiveShell($context->io(), $shell, $command, $output->isDecorated());
63+
$options = $this->getSuitableShellOptions($output);
64+
$process = $this->startInteractiveShell($context->io(), $shell, $command, $options);
6365
return $process->getExitCode();
6466
}
6567
}

src/Command/ScaffoldBaseCommand.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ abstract class ScaffoldBaseCommand extends BaseOptionsCommand
4343
{
4444

4545
protected $dynamicOptions = [];
46-
46+
4747
protected $scaffolder;
48-
48+
4949
public function __construct(ConfigurationService $configuration, MethodFactory $method_factory, $name = null)
5050
{
5151
parent::__construct($configuration, $method_factory, $name);
@@ -93,14 +93,14 @@ public function hasOption($name)
9393
* @param $root_folder
9494
* @param TaskContextInterface $context
9595
* @param array $tokens
96-
* @param callable|null $plugin_registration_callback
96+
* @param Options $options
9797
* @return CommandResult
9898
* @throws FabfileNotReadableException
9999
* @throws FailedShellCommandException
100100
* @throws MismatchedVersionException
101101
* @throws MissingScriptCallbackImplementation
102-
* @throws ValidationFailedException
103102
* @throws UnknownReplacementPatternException
103+
* @throws ValidationFailedException
104104
*/
105105
protected function scaffold(
106106
$url,

src/Command/ShellCommand.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Phabalicious\Exception\ShellProviderNotFoundException;
1414
use Phabalicious\Exception\TaskNotFoundInMethodException;
1515
use Phabalicious\Method\TaskContext;
16+
use Phabalicious\ShellProvider\ShellOptions;
1617
use Symfony\Component\Console\Input\InputInterface;
1718
use Symfony\Component\Console\Input\InputOption;
1819
use Symfony\Component\Console\Output\OutputInterface;
@@ -60,7 +61,9 @@ protected function execute(InputInterface $input, OutputInterface $output)
6061

6162
$output->writeln('<info>Starting shell on `' . $host_config['configName'] . '`');
6263

63-
$process = $this->startInteractiveShell($context->io(), $shell);
64+
$options = new ShellOptions();
65+
$options->setUseTty(true);
66+
$process = $this->startInteractiveShell($context->io(), $shell, [], $options);
6467
return $process->getExitCode();
6568
}
6669
}

src/Command/ShellCommandCommand.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
5353

5454
/** @var ShellProviderInterface $shell */
5555
$shell = $context->getResult('shell', $host_config->shell());
56-
$ssh_command = $context->getResult('ssh_command', $shell->getShellCommand([], ['tty' => true]));
56+
$options = $this->getSuitableShellOptions($output);
57+
$ssh_command = $context->getResult('ssh_command', $shell->getShellCommand([], $options));
5758

5859
$context->io()->text('$ ' . implode(' ', $ssh_command));
5960

src/Configuration/ConfigurationService.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ public function resolveInheritance(array $data, $lookup, $root_folder = false, $
345345
if ($add_data) {
346346
$this->checkRequires($add_data, $resource);
347347
}
348+
} elseif (file_exists($resource)) {
349+
$add_data = $this->readFile($resource);
350+
if ($add_data) {
351+
$this->checkRequires($add_data, $resource);
352+
}
348353
} elseif (file_exists($root_folder . '/' . $resource)) {
349354
$add_data = $this->readFile($root_folder . '/' . $resource);
350355
} else {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Phabalicious\Exception;
4+
5+
class ArgumentParsingException extends \Exception
6+
{
7+
}

src/Method/AlterableDataInterface.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
namespace Phabalicious\Method;
3+
4+
interface AlterableDataInterface
5+
{
6+
7+
}

src/Method/MethodFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ public function getSubset(array $needs)
272272
}, $needs);
273273
}
274274

275-
public function alter(array $needs, $func_name, &$data)
275+
public function alter(array $needs, $func_name, AlterableDataInterface $data)
276276
{
277277
$fn = 'alter' . ucwords($func_name);
278278
foreach ($this->getSubset($needs) as $method) {

src/Method/ScriptMethod.php

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44

55
use Phabalicious\Configuration\ConfigurationService;
66
use Phabalicious\Configuration\HostConfig;
7+
use Phabalicious\Scaffolder\CallbackOptions;
8+
use Phabalicious\Scaffolder\Callbacks\AssertNonZeroCallback;
9+
use Phabalicious\Scaffolder\Callbacks\AssertZeroCallback;
710
use Phabalicious\Scaffolder\Callbacks\ConfirmCallback;
811
use Phabalicious\Scaffolder\Callbacks\LogMessageCallback;
12+
use Phabalicious\Scaffolder\Options;
913
use Phabalicious\ShellProvider\CommandResult;
1014
use Phabalicious\Utilities\QuestionFactory;
1115
use Phabalicious\Utilities\Utilities;
@@ -76,16 +80,25 @@ public function runScript(HostConfig $host_config, TaskContextInterface $context
7680
$callbacks = $context->get('callbacks', []);
7781
$callbacks = Utilities::mergeData($this->callbacks, $callbacks);
7882

83+
$options = new CallbackOptions();
84+
$options->addDefaultCallbacks();
85+
$options
86+
->addCallback('execute', [$this, 'handleExecuteCallback'])
87+
->addCallback('fail_on_error', [$this, 'handleFailOnErrorDeprecatedCallback'])
88+
->addCallback('breakOnFirstError', [$this, 'handleFailOnErrorCallback'])
89+
->addCallback('fail_on_missing_directory', [$this, 'handleFailOnMissingDirectoryCallback']);
7990

8091
// Allow other methods to add their callbacks.
8192
if (!empty($host_config['needs'])) {
8293
$context->getConfigurationService()->getMethodFactory()->alter(
8394
$host_config['needs'],
8495
'scriptCallbacks',
85-
$callbacks
96+
$options
8697
);
8798
}
8899

100+
$callbacks = Utilities::mergeData($options->getCallbacks(), $callbacks);
101+
89102
$environment = $context->get('environment', []);
90103
if (!$context->getShell()) {
91104
$context->setShell($host_config->shell());
@@ -121,15 +134,6 @@ public function runScript(HostConfig $host_config, TaskContextInterface $context
121134
$commands = Utilities::expandStrings($commands, $replacements);
122135
$environment = Utilities::expandStrings($environment, $replacements);
123136

124-
$callbacks['execute'] = [$this, 'handleExecuteCallback'];
125-
$callbacks[ConfirmCallback::getName()] = [new ConfirmCallback(), 'handle'];
126-
$callbacks[LogMessageCallback::getName()] = [new LogMessageCallback(), 'handle'];
127-
$callbacks['fail_on_error'] = [$this, 'handleFailOnErrorDeprecatedCallback'];
128-
$callbacks['breakOnFirstError'] = [$this, 'handleFailOnErrorCallback'];
129-
$callbacks['fail_on_missing_directory'] = [
130-
$this,
131-
'handleFailOnMissingDirectoryCallback'
132-
];
133137

134138
$context->set('host_config', $host_config);
135139

@@ -455,9 +459,11 @@ private function resolveComputedValues(TaskContextInterface $context)
455459
$computed_values = $context->get(self::SCRIPT_COMPUTED_VALUES, []);
456460
foreach ($computed_values as $key => $cmd) {
457461
$cmd_result = $shell->run($cmd, true);
462+
$output = '';
458463
if ($cmd_result->succeeded()) {
459-
$result[$key] = trim(implode("\n", $cmd_result->getOutput()));
464+
$output = trim(implode("\n", $cmd_result->getOutput()));
460465
}
466+
$result[$key] = $output == "" ? $cmd_result->getExitCode() : $output;
461467
}
462468

463469
return $result;

src/Method/WebhookMethod.php

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Monolog\Handler\Curl\Util;
99
use Phabalicious\Configuration\ConfigurationService;
1010
use Phabalicious\Configuration\HostConfig;
11+
use Phabalicious\Scaffolder\CallbackOptions;
1112
use Phabalicious\Utilities\Utilities;
1213
use Phabalicious\Validation\ValidationErrorBagInterface;
1314
use Phabalicious\Validation\ValidationService;
@@ -144,7 +145,7 @@ public function postflightTask(string $task, HostConfig $config, TaskContextInte
144145
unset($this->handletaskSpecificWebhooks[$t]);
145146
}
146147
}
147-
148+
148149
public function webhook(HostConfig $host_config, TaskContextInterface $context)
149150
{
150151
$webhook_name = $context->get('webhook_name');
@@ -165,9 +166,9 @@ public function runWebhook($webhook_name, HostConfig $config, TaskContextInterfa
165166

166167
$defaults = $context->getConfigurationService()->getSetting('webhooks.defaults', []);
167168
$webhook = Utilities::mergeData($defaults, $webhook);
168-
169169

170-
170+
171+
171172
if (!empty($webhook['payload'])) {
172173
$payload = $webhook['payload'];
173174
$variables = Utilities::buildVariablesFrom($config, $context);
@@ -180,22 +181,22 @@ public function runWebhook($webhook_name, HostConfig $config, TaskContextInterfa
180181
$webhook['options'][$format] = $payload;
181182
}
182183
}
183-
184+
184185
$this->logger->info(sprintf(
185186
'Invoking webhook at `%s`, method `%s` and format `%s`',
186187
$webhook['url'],
187188
$webhook['method'],
188189
$webhook['format']
189190
));
190191
$this->logger->debug('guzzle options: ' . print_r($webhook['options'], true));
191-
192+
192193
$client = new Client();
193194
$response = $client->request(
194195
$webhook['method'],
195196
$webhook['url'],
196197
$webhook['options']
197198
);
198-
199+
199200
$this->logger->debug(sprintf(
200201
'Response status code: %d, body: `%s`',
201202
$response->getStatusCode(),
@@ -208,12 +209,14 @@ public function runWebhook($webhook_name, HostConfig $config, TaskContextInterfa
208209

209210
/**
210211
* Implements alter hook script callbacks
212+
*
213+
* @param CallbackOptions $options
211214
*/
212-
public function alterScriptCallbacks(&$callbacks)
215+
public function alterScriptCallbacks(CallbackOptions &$options)
213216
{
214-
$callbacks['webhook'] = [$this, 'webhookScriptCallback'];
217+
$options->addCallback('webhook', [$this, 'webhookScriptCallback']);
215218
}
216-
219+
217220
public function webhookScriptCallback(TaskContextInterface $context, $webhook_name, ...$args)
218221
{
219222
$cloned_context = clone $context;

src/Scaffolder/CallbackOptions.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
4+
namespace Phabalicious\Scaffolder;
5+
6+
use Phabalicious\Method\AlterableDataInterface;
7+
use Phabalicious\Scaffolder\Callbacks\AlterJsonFileCallback;
8+
use Phabalicious\Scaffolder\Callbacks\AssertContainsCallback;
9+
use Phabalicious\Scaffolder\Callbacks\AssertFileCallback;
10+
use Phabalicious\Scaffolder\Callbacks\AssertNonZeroCallback;
11+
use Phabalicious\Scaffolder\Callbacks\AssertZeroCallback;
12+
use Phabalicious\Scaffolder\Callbacks\ConfirmCallback;
13+
use Phabalicious\Scaffolder\Callbacks\LogMessageCallback;
14+
15+
class CallbackOptions implements AlterableDataInterface
16+
{
17+
protected $callbacks = [];
18+
19+
public function addDefaultCallbacks(): CallbackOptions
20+
{
21+
$this
22+
->addCallback(ConfirmCallback::getName(), [new ConfirmCallback(), 'handle'])
23+
->addCallback(LogMessageCallback::getName(), [new LogMessageCallback(), 'handle'])
24+
->addCallback(AssertNonZeroCallback::getName(), [new AssertNonZeroCallback(), 'handle'])
25+
->addCallback(AssertZeroCallback::getName(), [new AssertZeroCallback(), 'handle'])
26+
->addCallback(AssertFileCallback::getName(), [new AssertFileCallback(), 'handle'])
27+
->addCallback(AssertContainsCallback::getName(), [new AssertContainsCallback(), 'handle'])
28+
->addCallback(AlterJsonFileCallback::getName(), [new AlterJsonFileCallback(), 'handle']);
29+
30+
return $this;
31+
}
32+
33+
public function addCallback($name, $callable): CallbackOptions
34+
{
35+
$this->callbacks[$name] = $callable;
36+
return $this;
37+
}
38+
39+
public function getCallbacks(): array
40+
{
41+
return $this->callbacks;
42+
}
43+
}

0 commit comments

Comments
 (0)