Passed
Pull Request — master (#6)
by
unknown
02:22
created

ShellCommand::environmentVariablesToString()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 7
rs 10
cc 2
nc 2
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PHPSu\ShellCommandBuilder;
6
7
use PHPSu\ShellCommandBuilder\Exception\ShellBuilderException;
8
9
final class ShellCommand implements ShellInterface
10
{
11
    /** @var string */
12
    private $executable;
13
    /** @var array<ShellWord> */
14
    private $arguments = [];
15
    /** @var array<ShellWord> */
16
    private $environmentVariables = [];
17
    /** @var bool  */
18
    private $isCommandSubstitution = false;
19
    /** @var ShellBuilder|null */
20
    private $parentBuilder;
21
22
    public function __construct(string $name, ShellBuilder $builder = null)
23
    {
24
        $this->executable = $name;
25
        $this->parentBuilder = $builder;
26
    }
27
28
    public function addToBuilder(): ShellBuilder
29
    {
30
        if ($this->parentBuilder === null) {
31
            throw new ShellBuilderException('You need to create a ShellBuilder first before you can use it within a command');
32
        }
33
        return $this->parentBuilder->add($this);
34
    }
35
36
    public function toggleCommandSubstitution(): self
37
    {
38
        $this->isCommandSubstitution = !$this->isCommandSubstitution;
39
        return $this;
40
    }
41
42
    /**
43
     * @param string $option
44
     * @param ShellInterface|string|mixed $value
45
     * @param bool $escapeArgument
46
     * @param bool $withAssignOperator
47
     * @return self
48
     * @throws ShellBuilderException
49
     */
50
    public function addShortOption(string $option, $value = '', bool $escapeArgument = true, bool $withAssignOperator = false): self
51
    {
52
        if (!($value instanceof ShellInterface || is_string($value))) {
53
            throw new ShellBuilderException('Provided the wrong type - only ShellCommand and ShellBuilder allowed');
54
        }
55
        $word = new ShellWord($option, $value);
56
        $word->asShortOption();
57
        return $this->add($word, $escapeArgument, $withAssignOperator);
58
    }
59
60
    /**
61
     * @param string $option
62
     * @param ShellInterface|string|mixed $value
63
     * @param bool $escapeArgument
64
     * @param bool $withAssignOperator
65
     * @return self
66
     * @throws ShellBuilderException
67
     */
68
    public function addOption(string $option, $value = '', bool $escapeArgument = true, bool $withAssignOperator = false): self
69
    {
70
        if (!($value instanceof ShellInterface || is_string($value))) {
71
            throw new ShellBuilderException('Provided the wrong type - only ShellCommand and ShellBuilder allowed');
72
        }
73
        $word = new ShellWord($option, $value);
74
        $word->asOption();
75
        return $this->add($word, $escapeArgument, $withAssignOperator);
76
    }
77
78
    /**
79
     * @param ShellInterface|string|mixed $argument
80
     * @param bool $escapeArgument
81
     * @return self
82
     * @throws ShellBuilderException
83
     */
84
    public function addArgument($argument, bool $escapeArgument = true): self
85
    {
86
        if (!($argument instanceof ShellInterface || is_string($argument))) {
87
            throw new ShellBuilderException('Provided the wrong type - only ShellCommand and ShellBuilder allowed');
88
        }
89
        $word = new ShellWord($argument);
90
        $word->asArgument();
91
        return $this->add($word, $escapeArgument);
92
    }
93
94
    public function addSubCommand(ShellInterface $argument): self
95
    {
96
        $word = new ShellWord($argument);
97
        $word->asSubCommand();
98
        return $this->add($word, true);
99
    }
100
101
    /**
102
     * @param ShellInterface|string|mixed $argument
103
     * @return self
104
     * @throws ShellBuilderException
105
     */
106
    public function addNoSpaceArgument($argument): self
107
    {
108
        if (!($argument instanceof ShellInterface || is_string($argument))) {
109
            throw new ShellBuilderException('Provided the wrong type - only ShellCommand and ShellBuilder allowed');
110
        }
111
        $word = new ShellWord($argument);
112
        $word->asArgument()->setSpaceAfterValue(false);
113
        return $this->add($word, false);
114
    }
115
116
    private function add(ShellWord $word, bool $escapeArgument, bool $withAssignOperator = false): self
117
    {
118
        $word->setEscape($escapeArgument);
119
        $word->setAssignOperator($withAssignOperator);
120
        $this->arguments[] = $word;
121
        return $this;
122
    }
123
124
    public function addEnv(string $name, string $value): self
125
    {
126
        $word = new ShellWord($name, $value);
127
        $word->asEnvironmentVariable();
128
        $word->setAssignOperator(true);
129
        $this->environmentVariables[$name] = $word;
130
        return $this;
131
    }
132
133
    private function argumentsToString(): string
134
    {
135
        $result = [];
136
        foreach ($this->arguments as $part) {
137
            $result[] = $part;
138
        }
139
        return trim(implode('', $result));
140
    }
141
142
    private function environmentVariablesToString(): string
143
    {
144
        $result = [];
145
        foreach ($this->environmentVariables as $part) {
146
            $result[] = $part;
147
        }
148
        return implode('', $result);
149
    }
150
151
    /**
152
     * @return array<string, mixed>
153
     */
154
    public function __toArray(): array
155
    {
156
        $commands = [];
157
        foreach ($this->arguments as $item) {
158
            $commands[] = $item->__toArray();
159
        }
160
        $envs = [];
161
        foreach ($this->environmentVariables as $item) {
162
            $envs[] = $item->__toArray();
163
        }
164
        return [
165
            'executable' => $this->executable,
166
            'arguments' => $commands,
167
            'isCommandSubstitution' => $this->isCommandSubstitution,
168
            'environmentVariables' => $envs,
169
        ];
170
    }
171
172
    public function __toString(): string
173
    {
174
        $result = (sprintf(
175
            '%s%s%s',
176
            empty($this->environmentVariables) ? '' : $this->environmentVariablesToString(),
177
            $this->executable,
178
            empty($this->arguments) ? '' : ' ' . $this->argumentsToString()
179
        ));
180
        if ($this->isCommandSubstitution) {
181
            return sprintf("\$(%s)", $result);
182
        }
183
        return $result;
184
    }
185
}
186