Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve ParallelExecutor::generateOptions to manage all types of InputOption #1792

Merged
merged 1 commit into from
Jan 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/Console/Input/Argument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php declare(strict_types=1);
/* (c) Anton Medvedev <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Deployer\Console\Input;

use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;

final class Argument
{
public static function toString(
InputInterface $input,
InputArgument $argument
): string {
return $input->getArgument($argument->getName());
}
}
80 changes: 80 additions & 0 deletions src/Console/Input/Option.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php declare(strict_types=1);
/* (c) Anton Medvedev <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Deployer\Console\Input;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;

final class Option
{
public static function toString(
InputInterface $input,
InputOption $option
): string {
$name = $option->getName();

if (!$option->acceptValue()) {
return \sprintf(
'--%s',
$name
);
}

if (!$option->isArray()) {
return self::generatePartialOption(
$option,
$name,
$input->getOption($name)
);
}

/** @var string[] $outputs */
$outputs = [];
foreach ($input->getOption($name) as $value) {
$value = self::generatePartialOption(
$option,
$name,
$value
);

if ($value === '') {
continue;
}

$outputs[] = $value;
}

return \implode(' ', $outputs);
}

/**
* @param null|string $value
*/
private static function generatePartialOption(
InputOption $option,
string $name,
$value
): string {
if (\null !== $value && \strlen($value) !== 0) {
return \sprintf(
'--%s=%s',
$name,
$value
);
}

if ($option->isValueOptional()) {
return \sprintf(
'--%s',
$name
);
}

return '';
}
}
31 changes: 8 additions & 23 deletions src/Console/Output/VerbosityString.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php
<?php declare(strict_types=1);
/* (c) Anton Medvedev <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
Expand All @@ -16,44 +16,29 @@ class VerbosityString
*/
private $output;

/**
* @param OutputInterface $output
*/
public function __construct(OutputInterface $output)
{
$this->output = $output;
}

/**
* @return string
*/
public function __toString()
public function __toString(): string
{
switch ($this->output->getVerbosity()) {
case OutputInterface::VERBOSITY_NORMAL:
$verbosity = '';
break;

case OutputInterface::VERBOSITY_VERBOSE:
$verbosity = '-v';
break;
return '-v';

case OutputInterface::VERBOSITY_VERY_VERBOSE:
$verbosity = '-vv';
break;
return '-vv';

case OutputInterface::VERBOSITY_DEBUG:
$verbosity = '-vvv';
break;
return '-vvv';

case OutputInterface::VERBOSITY_QUIET:
$verbosity = '-q';
break;
return '-q';

case OutputInterface::VERBOSITY_NORMAL:
default:
$verbosity = '';
return '';
}

return $verbosity;
}
}
38 changes: 18 additions & 20 deletions src/Executor/ParallelExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
namespace Deployer\Executor;

use Deployer\Console\Application;
use Deployer\Console\Input\Argument;
use Deployer\Console\Input\Option;
use Deployer\Console\Output\Informer;
use Deployer\Console\Output\VerbosityString;
use Deployer\Exception\Exception;
Expand All @@ -18,6 +20,7 @@
use Deployer\Task\Context;
use Deployer\Task\Task;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;

Expand Down Expand Up @@ -61,7 +64,7 @@ public function __construct(
public function run(array $tasks, array $hosts)
{
$localhost = new Localhost();
$limit = (int)$this->input->getOption('limit') ?: count($hosts);
$limit = (int) $this->input->getOption('limit') ?: count($hosts);

// We need contexts here for usage inside `on` function. Pass input/output to callback of it.
// This allows to use code like this in parallel mode:
Expand Down Expand Up @@ -154,7 +157,7 @@ private function runTask(array $hosts, Task $task): int
*/
protected function getProcess(Host $host, Task $task): Process
{
$dep = PHP_BINARY . ' ' . DEPLOYER_BIN;
$dep = PHP_BINARY.' '.DEPLOYER_BIN;
$options = $this->generateOptions();
$arguments = $this->generateArguments();
$hostname = $host->getHostname();
Expand All @@ -181,6 +184,7 @@ protected function getProcess(Host $host, Task $task): Process
* Start all of the processes.
*
* @param Process[] $processes
*
* @return void
*/
protected function startProcesses(array $processes)
Expand All @@ -202,13 +206,15 @@ protected function areRunning(array $processes): bool
return true;
}
}

return false;
}

/**
* Gather the output from all of the processes.
*
* @param Process[] $processes
*
* @return void
*/
protected function gatherOutput(array $processes, callable $callback)
Expand Down Expand Up @@ -247,31 +253,23 @@ protected function gatherExitCodes(array $processes): int
*/
private function generateOptions(): string
{
$input = (string)(new VerbosityString($this->output));
/** @var string[] $inputs */
$inputs = [
(string) (new VerbosityString($this->output)),
];

$userDefinition = $this->console->getUserDefinition();
// Get user arguments
foreach ($this->console->getUserDefinition()->getArguments() as $argument) {
$value = $this->input->getArgument($argument->getName());
if (strlen($value) !== 0) {
$input .= " $value";
}
foreach ($userDefinition->getArguments() as $argument) {
$inputs[] = Argument::toString($this->input, $argument);
}

// Get user options
foreach ($this->console->getUserDefinition()->getOptions() as $option) {
$name = $option->getName();
$value = $this->input->getOption($name);

if (null !== $value && strlen($value) !== 0) {
$input .= " --{$name}";

if ($option->acceptValue()) {
$input .= " {$value}";
}
}
foreach ($userDefinition->getOptions() as $option) {
$inputs[] = Option::toString($this->input, $option);
}

return $input;
return implode(' ', $inputs);
}

private function generateArguments(): string
Expand Down
59 changes: 59 additions & 0 deletions test/src/Console/Input/ArgumentTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php declare(strict_types=1);
/* (c) Anton Medvedev <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Deployer\Console\Input;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;

final class ArgumentTest extends TestCase
{
public function toStringProvider(): \Generator
{
foreach ([
['fooBar', 'fooBar'],
['0', '0'],
['1', '1'],
['foo\-%&Bar', 'foo\-%&Bar'],
['\'', '\''],
['ù+ì', 'ù+ì'],
] as list($expectedValue, $inputValue)) {
$input = $this->createMock(InputInterface::class);
$input->expects($this->once())
->method('getArgument')
->willReturn($inputValue);

$argument = $this->createMock(InputArgument::class);
$argument->expects($this->once())
->method('getName')
->willReturn('argumentName');

yield [
$expectedValue,
$input,
$argument,
];
}
}

/**
* @dataProvider toStringProvider
*
* @return void
*/
public function testToString(
string $expectedValue,
InputInterface $input,
InputArgument $argument
) {
$this->assertEquals(
$expectedValue,
Argument::toString($input, $argument)
);
}
}
Loading