kaliop-uk /
ezmigrationbundle
| 1 | <?php |
||||||
| 2 | |||||||
| 3 | namespace Kaliop\eZMigrationBundle\Core\Executor; |
||||||
| 4 | |||||||
| 5 | use Kaliop\eZMigrationBundle\API\Exception\InvalidStepDefinitionException; |
||||||
| 6 | use Kaliop\eZMigrationBundle\API\Exception\MigrationBundleException; |
||||||
| 7 | use Kaliop\eZMigrationBundle\API\ReferenceResolverBagInterface; |
||||||
| 8 | use Kaliop\eZMigrationBundle\API\Value\MigrationStep; |
||||||
| 9 | use Kaliop\eZMigrationBundle\Core\Process\ProcessBuilder; |
||||||
| 10 | use Symfony\Component\Process\Process; |
||||||
| 11 | |||||||
| 12 | /** |
||||||
| 13 | * @property ReferenceResolverBagInterface $referenceResolver |
||||||
| 14 | */ |
||||||
| 15 | class ProcessExecutor extends AbstractExecutor |
||||||
| 16 | { |
||||||
| 17 | use IgnorableStepExecutorTrait; |
||||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||||
| 18 | use ReferenceSetterTrait; |
||||||
| 19 | |||||||
| 20 | protected $supportedStepTypes = array('process'); |
||||||
| 21 | protected $supportedActions = array('run'); |
||||||
| 22 | |||||||
| 23 | protected $defaultTimeout = 86400; |
||||||
| 24 | |||||||
| 25 | /** |
||||||
| 26 | * @param ReferenceResolverBagInterface $referenceResolver |
||||||
| 27 | 149 | */ |
|||||
| 28 | public function __construct(ReferenceResolverBagInterface $referenceResolver) |
||||||
| 29 | 149 | { |
|||||
| 30 | 149 | $this->referenceResolver = $referenceResolver; |
|||||
| 31 | } |
||||||
| 32 | |||||||
| 33 | /** |
||||||
| 34 | * @param MigrationStep $step |
||||||
| 35 | * @return mixed |
||||||
| 36 | * @throws \Exception |
||||||
| 37 | 2 | */ |
|||||
| 38 | public function execute(MigrationStep $step) |
||||||
| 39 | 2 | { |
|||||
| 40 | parent::execute($step); |
||||||
| 41 | 2 | ||||||
| 42 | if (!isset($step->dsl['mode'])) { |
||||||
| 43 | throw new InvalidStepDefinitionException("Invalid step definition: missing 'mode'"); |
||||||
| 44 | } |
||||||
| 45 | 2 | ||||||
| 46 | $action = $step->dsl['mode']; |
||||||
| 47 | 2 | ||||||
| 48 | if (!in_array($action, $this->supportedActions)) { |
||||||
| 49 | throw new InvalidStepDefinitionException("Invalid step definition: value '$action' is not allowed for 'mode'"); |
||||||
| 50 | } |
||||||
| 51 | 2 | ||||||
| 52 | $this->skipStepIfNeeded($step); |
||||||
| 53 | 2 | ||||||
| 54 | return $this->$action($step->dsl, $step->context); |
||||||
| 55 | } |
||||||
| 56 | |||||||
| 57 | /** |
||||||
| 58 | * @param $dsl |
||||||
| 59 | * @param array|null $context |
||||||
| 60 | * @return \Symfony\Component\Process\Process |
||||||
| 61 | * @throws \Exception |
||||||
| 62 | * @todo add more options supported by Sf Process |
||||||
| 63 | 2 | */ |
|||||
| 64 | protected function run($dsl, $context) |
||||||
| 65 | 2 | { |
|||||
| 66 | if (!isset($dsl['command'])) { |
||||||
| 67 | throw new InvalidStepDefinitionException("Can not run process: command missing"); |
||||||
| 68 | } |
||||||
| 69 | 2 | ||||||
| 70 | $builder = new ProcessBuilder(); |
||||||
| 71 | |||||||
| 72 | 2 | // mandatory args and options |
|||||
| 73 | $builderArgs = array($this->resolveReference($dsl['command'])); |
||||||
| 74 | 2 | ||||||
| 75 | 1 | if (isset($dsl['arguments'])) { |
|||||
| 76 | foreach ($dsl['arguments'] as $arg) { |
||||||
| 77 | 1 | /// @todo should this be recursive? |
|||||
| 78 | $builderArgs[] = $this->resolveReference($arg); |
||||||
| 79 | } |
||||||
| 80 | } |
||||||
| 81 | |||||||
| 82 | 2 | $process = $builder |
|||||
| 83 | 2 | ->setArguments($builderArgs) |
|||||
| 84 | ->getProcess(); |
||||||
| 85 | |||||||
| 86 | 2 | // allow long migrations processes by default |
|||||
| 87 | 2 | $timeout = $this->defaultTimeout; |
|||||
| 88 | if (isset($dsl['timeout'])) { |
||||||
| 89 | $timeout = $this->resolveReference($dsl['timeout']); |
||||||
| 90 | 2 | } |
|||||
| 91 | $process->setTimeout($timeout); |
||||||
| 92 | 2 | ||||||
| 93 | 1 | if (isset($dsl['working_directory'])) { |
|||||
| 94 | $process->setWorkingDirectory($this->resolveReference($dsl['working_directory'])); |
||||||
| 95 | } |
||||||
| 96 | |||||||
| 97 | 2 | /// @todo should we support false/true ? |
|||||
| 98 | if (isset($dsl['disable_output'])) { |
||||||
| 99 | $process->disableOutput(); |
||||||
|
0 ignored issues
–
show
The method
disableOutput() does not exist on Kaliop\eZMigrationBundle\Core\Process\Process.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. Loading history...
|
|||||||
| 100 | } |
||||||
| 101 | 2 | ||||||
| 102 | 1 | if (isset($dsl['environment'])) { |
|||||
| 103 | $process->setEnv($this->resolveReference($dsl['environment'])); |
||||||
| 104 | } |
||||||
| 105 | 2 | ||||||
| 106 | $process->run(); |
||||||
| 107 | 2 | ||||||
| 108 | 1 | if (isset($dsl['fail_on_error']) && $this->resolveReference($dsl['fail_on_error'])) { |
|||||
| 109 | 1 | if (($exitCode = $process->getExitCode()) != 0) { |
|||||
|
0 ignored issues
–
show
|
|||||||
| 110 | throw new MigrationBundleException("Process failed with exit code: $exitCode", $exitCode); |
||||||
| 111 | } |
||||||
| 112 | } |
||||||
| 113 | 1 | ||||||
| 114 | $this->setReferences($process, $dsl); |
||||||
| 115 | 1 | ||||||
| 116 | return $process; |
||||||
| 117 | } |
||||||
| 118 | |||||||
| 119 | /** |
||||||
| 120 | * @param Process $process |
||||||
| 121 | * @param $dsl |
||||||
| 122 | * @return bool |
||||||
| 123 | * @throws InvalidStepDefinitionException |
||||||
| 124 | 1 | */ |
|||||
| 125 | protected function setReferences(Process $process, $dsl) |
||||||
| 126 | 1 | { |
|||||
| 127 | if (!array_key_exists('references', $dsl) || !count($dsl['references'])) { |
||||||
| 128 | return false; |
||||||
| 129 | } |
||||||
| 130 | 1 | ||||||
| 131 | 1 | foreach ($dsl['references'] as $key => $reference) { |
|||||
| 132 | 1 | $reference = $this->parseReferenceDefinition($key, $reference); |
|||||
| 133 | 1 | switch ($reference['attribute']) { |
|||||
| 134 | 1 | case 'error_output': |
|||||
| 135 | 1 | $value = rtrim($process->getErrorOutput(), "\r\n"); |
|||||
| 136 | 1 | break; |
|||||
| 137 | 1 | case 'exit_code': |
|||||
| 138 | 1 | $value = $process->getExitCode(); |
|||||
| 139 | 1 | break; |
|||||
| 140 | 1 | case 'output': |
|||||
| 141 | 1 | $value = rtrim($process->getOutput(), "\r\n"); |
|||||
| 142 | break; |
||||||
| 143 | default: |
||||||
| 144 | throw new InvalidStepDefinitionException('Process executor does not support setting references for attribute ' . $reference['attribute']); |
||||||
| 145 | } |
||||||
| 146 | 1 | ||||||
| 147 | 1 | $overwrite = false; |
|||||
| 148 | if (isset($reference['overwrite'])) { |
||||||
| 149 | $overwrite = $reference['overwrite']; |
||||||
| 150 | 1 | } |
|||||
| 151 | $this->addReference($reference['identifier'], $value, $overwrite); |
||||||
| 152 | } |
||||||
| 153 | 1 | ||||||
| 154 | return true; |
||||||
| 155 | } |
||||||
| 156 | } |
||||||
| 157 |