1212use PHPSu \ShellCommandBuilder \Definition \ControlOperator ;
1313use PHPSu \ShellCommandBuilder \Definition \GroupType ;
1414use PHPSu \ShellCommandBuilder \Exception \ShellBuilderException ;
15+ use PHPSu \ShellCommandBuilder \Literal \ShellVariable ;
1516use TypeError ;
1617
1718final class ShellBuilder implements ShellInterface, \JsonSerializable
1819{
19- /** @var array<ShellInterface|CollectionTuple > */
20+ /** @var array<ShellInterface> */
2021 private $ commandList = [];
2122 /** @var int */
2223 private $ groupType ;
@@ -29,6 +30,8 @@ final class ShellBuilder implements ShellInterface, \JsonSerializable
2930 private $ processSubstitution = false ;
3031 /** @var bool */
3132 private $ commandSubstitution = false ;
33+ /** @var array<string, ShellVariable> */
34+ private $ variables = [];
3235
3336 /**
3437 * This is a shortcut for quicker fluid access to the shell builder
@@ -65,6 +68,34 @@ public function runAsynchronously(bool $isAsync = true, string $name = ''): self
6568 return $ this ;
6669 }
6770
71+ /**
72+ * @param string $variable
73+ * @param string|ShellInterface $value
74+ * @param bool $useBackticks
75+ * @param bool $escape is the value instance of ShellInterface, then this variable is automatically false
76+ * @return $this
77+ * @throws ShellBuilderException
78+ */
79+ public function addVariable (string $ variable , $ value , bool $ useBackticks = false , bool $ escape = true ): self
80+ {
81+ if (isset ($ this ->variables [$ variable ])) {
82+ throw new ShellBuilderException ('Variable has already been declared. ' );
83+ }
84+ $ shellVariable = new ShellVariable ($ variable , $ value );
85+ $ shellVariable ->wrapWithBackticks ($ useBackticks );
86+ if (is_string ($ value )) {
87+ $ shellVariable ->setEscape ($ escape );
88+ }
89+ $ this ->variables [$ variable ] = $ shellVariable ;
90+ return $ this ;
91+ }
92+
93+ public function removeVariable (string $ variable ): self
94+ {
95+ unset($ this ->variables [$ variable ]);
96+ return $ this ;
97+ }
98+
6899 /**
69100 * @param string|ShellInterface $command
70101 * @return $this
@@ -274,6 +305,18 @@ private function validateCommand(ShellInterface $command, bool $allowEmpty): voi
274305 }
275306 }
276307
308+ private function variablesToString (): string
309+ {
310+ $ variableString = '' ;
311+ foreach ($ this ->variables as $ variable ) {
312+ $ variableString .= $ variable . '; ' ;
313+ }
314+ if ($ variableString !== '' ) {
315+ $ variableString .= ' ' ;
316+ }
317+ return $ variableString ;
318+ }
319+
277320 public function jsonSerialize (): array
278321 {
279322 return $ this ->__toArray ();
@@ -286,7 +329,7 @@ public function __toArray(): array
286329 {
287330 $ commands = [];
288331 foreach ($ this ->commandList as $ item ) {
289- $ commands [] = $ item instanceof ShellInterface ? $ item ->__toArray () : $ item ;
332+ $ commands [] = $ item ->__toArray ();
290333 }
291334 return $ commands ;
292335 }
@@ -324,6 +367,6 @@ public function __toString(): string
324367 ControlOperator::BLOCK_DEFINITON_CLOSE
325368 );
326369 }
327- return rtrim ($ result );
370+ return rtrim (sprintf ( ' %s%s ' , $ this -> variablesToString (), $ result) );
328371 }
329372}
0 commit comments