Passed
Branch master (44cb95)
by Marc
05:51
created

AbstractAnsibleCommand::getProcessCommandline()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 13
rs 10
c 0
b 0
f 0
1
<?php
2
/*
3
 * This file is part of the php-ansible package.
4
 *
5
 * (c) Marc Aschmann <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Asm\Ansible\Command;
12
13
use Asm\Ansible\Process\ProcessBuilderInterface;
14
use Psr\Log\LoggerAwareTrait;
15
use Psr\Log\LoggerInterface;
16
use Psr\Log\NullLogger;
17
use Symfony\Component\Process\Process;
18
19
/**
20
 * Class AbstractAnsibleCommand
21
 *
22
 * @package Asm\Ansible\Command
23
 * @author Marc Aschmann <[email protected]>
24
 */
25
abstract class AbstractAnsibleCommand
26
{
27
    /**
28
     * Adds a local $logger instance and the setter.
29
     */
30
    use LoggerAwareTrait;
31
    /**
32
     * @var ProcessBuilderInterface
33
     */
34
    protected $processBuilder;
35
36
    /**
37
     * @var Option[]
38
     */
39
    private $options;
40
41
    /**
42
     * @var array
43
     */
44
    private $parameters;
45
46
    /**
47
     * @var array
48
     */
49
    private $baseOptions;
50
51
    /**
52
     * @param ProcessBuilderInterface $processBuilder
53
     * @param LoggerInterface|null         $logger
54
     */
55
    public function __construct(ProcessBuilderInterface $processBuilder, LoggerInterface $logger = null)
56
    {
57
        $this->processBuilder = $processBuilder;
58
        $this->options = [];
59
        $this->parameters = [];
60
        $this->baseOptions = [];
61
        $this->setLogger($logger ?? new NullLogger());
62
    }
63
64
    /**
65
     * Get parameter string which will be used to call ansible.
66
     *
67
     * @param bool $asArray
68
     * @return string|array
69
     */
70
    protected function prepareArguments(bool $asArray = true)
71
    {
72
        $arguments = array_merge(
73
            [$this->getBaseOptions()],
74
            $this->getOptions(),
75
            $this->getParameters()
76
        );
77
78
        if (false === $asArray) {
79
            $arguments = implode(' ', $arguments);
80
        }
81
82
        return $arguments;
83
    }
84
85
    /**
86
     * Add an Option.
87
     *
88
     * @param string $name
89
     * @param string $value
90
     */
91
    protected function addOption(string $name, string $value): void
92
    {
93
        $this->options[] = new Option($name, $value);
94
    }
95
96
    /**
97
     * Add a parameter.
98
     *
99
     * @param string $name
100
     */
101
    protected function addParameter(string $name): void
102
    {
103
        $this->parameters[] = $name;
104
    }
105
106
    /**
107
     * Get all options as array.
108
     *
109
     * @return array
110
     */
111
    protected function getOptions(): array
112
    {
113
        $options = [];
114
115
        foreach ($this->options as $option) {
116
            $options[] = $option->toString();
117
        }
118
119
        return $options;
120
    }
121
122
    /**
123
     * Get all parameters as array.
124
     *
125
     * @return array
126
     */
127
    protected function getParameters(): array
128
    {
129
        return $this->parameters;
130
    }
131
132
133
    /**
134
     * Add base options to internal storage.
135
     *
136
     * @param string $baseOption
137
     * @return $this
138
     */
139
    protected function addBaseOption(string $baseOption)
140
    {
141
        $this->baseOptions[] = $baseOption;
142
143
        return $this;
144
    }
145
146
    /**
147
     * Generate base options string.
148
     *
149
     * @return string
150
     */
151
    protected function getBaseOptions(): string
152
    {
153
        return implode(' ', $this->baseOptions);
154
    }
155
156
    /**
157
     * Check if param is array or string and implode with glue if necessary.
158
     *
159
     * @param string|array $param
160
     * @param string $glue
161
     * @return string
162
     */
163
    protected function checkParam($param, string $glue = ' '): string
164
    {
165
        if (is_array($param)) {
166
            $param = implode($glue, $param);
167
        }
168
169
        return $param;
170
    }
171
172
    /**
173
     * Creates process with processBuilder builder and executes it.
174
     *
175
     * @param callable|null $callback
176
     * @return int|string
177
     */
178
    protected function runProcess($callback = null)
179
    {
180
        $process = $this->processBuilder
181
            ->setArguments(
182
                $this->prepareArguments()
183
            )
184
            ->getProcess();
185
186
        // Logging the command
187
        $this->logger->debug('Executing: ' . $this->getProcessCommandline($process));
188
189
        // exit code
190
        $result = $process->run($callback);
191
192
        // text-mode
193
        if (null === $callback) {
194
            $result = $process->getOutput();
195
196
            if (false === $process->isSuccessful()) {
197
                $process->getErrorOutput();
198
            }
199
        }
200
201
        return $result;
202
    }
203
204
    /**
205
     * Builds the complete commandline inclusive of the environment variables.
206
     * @param Process $process The process instance.
207
     * @return string
208
     */
209
    protected function getProcessCommandline(Process $process): string
210
    {
211
        $commandline = $process->getCommandLine();
212
        if (count($process->getEnv()) === 0)
213
            return $commandline;
214
215
        // Here: we also need to dump the environment variables
216
        $vars = [];
217
        foreach ($process->getEnv() as $var => $value) {
218
            $vars[] = sprintf('%s=\'%s\'', $var, $value);
219
        }
220
221
        return sprintf('%s %s', implode(' ', $vars), $commandline);
222
    }
223
}
224