1+ <?php declare (strict_types=1 );
2+ /**
3+ * This file is part of toolkit/sys-utils.
4+ *
5+ * @author https://github.com/inhere
6+ * @link https://github.com/php-toolkit/sys-utils
7+ * @license MIT
8+ */
9+
10+ namespace Toolkit \Sys \Cmd ;
11+
12+ use RuntimeException ;
13+ use Toolkit \Sys \Exec ;
14+ use function trim ;
15+
16+ /**
17+ * class AbstractCmdBuilder
18+ */
19+ abstract class AbstractCmdBuilder
20+ {
21+ public const PRINT_CMD = 'printCmd ' ;
22+ public const PRINT_DRY_RUN = 'dryRun ' ;
23+ public const PRINT_ERROR = 'error ' ;
24+
25+ /**
26+ * @var string
27+ */
28+ protected $ command = '' ;
29+
30+ /**
31+ * @var string
32+ */
33+ protected $ workDir ;
34+
35+ /**
36+ * @var int
37+ */
38+ protected $ code = 0 ;
39+
40+ /**
41+ * @var string
42+ */
43+ protected $ error = '' ;
44+
45+ /**
46+ * @var string
47+ */
48+ protected $ output = '' ;
49+
50+ /**
51+ * Dry run all commands
52+ *
53+ * @var bool
54+ */
55+ protected $ dryRun = false ;
56+
57+ /**
58+ * @var bool
59+ */
60+ protected $ printCmd = true ;
61+
62+ /**
63+ * Ignore check prevision return code
64+ *
65+ * @var bool
66+ */
67+ protected $ ignoreError = false ;
68+
69+ /**
70+ * @var bool
71+ */
72+ protected $ printOutput = false ;
73+
74+ /**
75+ * Class constructor.
76+ *
77+ * @param string $command One or multi commands
78+ * @param string $workDir
79+ */
80+ public function __construct (string $ command = '' , string $ workDir = '' )
81+ {
82+ $ this ->command = $ command ;
83+ $ this ->workDir = $ workDir ;
84+ }
85+
86+ /**
87+ * @param string $workDir
88+ *
89+ * @return $this
90+ */
91+ public function chDir (string $ workDir ): self
92+ {
93+ return $ this ->changeDir ($ workDir );
94+ }
95+
96+ /**
97+ * @param string $workDir
98+ *
99+ * @return $this
100+ */
101+ public function changeDir (string $ workDir ): self
102+ {
103+ $ this ->workDir = $ workDir ;
104+ return $ this ;
105+ }
106+
107+ /**
108+ * run and print all output
109+ */
110+ public function runAndPrint (): void
111+ {
112+ $ this ->run (true );
113+ }
114+
115+ /**
116+ * Run command
117+ *
118+ * @param bool $printOutput
119+ *
120+ * @return $this
121+ */
122+ abstract public function run (bool $ printOutput = false ): self ;
123+
124+ /**************************************************************************
125+ * helper methods
126+ *************************************************************************/
127+
128+ /**
129+ * @param string $command
130+ * @param string $workDir
131+ */
132+ protected function innerExecute (string $ command , string $ workDir ): void
133+ {
134+ if (!$ command ) {
135+ throw new RuntimeException ('The execute command cannot be empty ' );
136+ }
137+
138+ if ($ this ->printCmd ) {
139+ // Color::println("> {$command}", 'yellow');
140+ $ this ->printMessage ("> $ command " , self ::PRINT_CMD );
141+ }
142+
143+ if ($ this ->dryRun ) {
144+ $ this ->output = 'DRY-RUN: Command execute success ' ;
145+ // Color::println($output, 'cyan');
146+ $ this ->printMessage ($ this ->output , self ::PRINT_DRY_RUN );
147+ return ;
148+ }
149+
150+ if ($ this ->printOutput ) {
151+ $ this ->execAndPrint ($ command , $ workDir );
152+ } else {
153+ $ this ->execLogReturn ($ command , $ workDir );
154+ }
155+ }
156+
157+ /**
158+ * exec and log outputs.
159+ *
160+ * @param string $command
161+ * @param string $workDir
162+ */
163+ protected function execLogReturn (string $ command , string $ workDir ): void
164+ {
165+ [$ code , $ output , $ error ] = Exec::run ($ command , $ workDir );
166+
167+ // save output
168+ $ this ->code = $ code ;
169+ $ this ->error = trim ($ error );
170+ $ this ->output = trim ($ output );
171+ }
172+
173+ /**
174+ * direct print to stdout, not return outputs.
175+ *
176+ * @param string $command
177+ * @param string $workDir
178+ */
179+ protected function execAndPrint (string $ command , string $ workDir ): void
180+ {
181+ // $lastLine = system($command, $exitCode);
182+ [$ exitCode , $ lastLine ] = Exec::system ($ command , $ workDir );
183+
184+ $ this ->code = $ exitCode ;
185+ $ this ->output = trim ($ lastLine );
186+
187+ if ($ exitCode !== 0 ) {
188+ $ this ->error = $ this ->output ;
189+ $ this ->printMessage ("error code $ exitCode: \n" . $ lastLine , self ::PRINT_ERROR );
190+ } else {
191+ echo "\n" ;
192+ }
193+ }
194+
195+ /**
196+ * @param string $msg
197+ * @param string $scene eg: printCmd, dryRun, error
198+ */
199+ protected function printMessage (string $ msg , string $ scene ): void
200+ {
201+ echo "$ msg \n" ;
202+ }
203+
204+ /**************************************************************************
205+ * getter/setter methods
206+ *************************************************************************/
207+
208+ /**
209+ * @param string $command
210+ *
211+ * @return $this
212+ */
213+ public function setCommand (string $ command ): self
214+ {
215+ $ this ->command = $ command ;
216+ return $ this ;
217+ }
218+
219+ /**
220+ * @return string
221+ */
222+ public function getCommand (): string
223+ {
224+ return $ this ->command ;
225+ }
226+
227+ /**
228+ * @return string
229+ */
230+ public function getWorkDir (): string
231+ {
232+ return $ this ->workDir ;
233+ }
234+
235+ /**
236+ * @param string $workDir
237+ *
238+ * @return $this
239+ */
240+ public function setWorkDir (string $ workDir ): self
241+ {
242+ $ this ->workDir = $ workDir ;
243+ return $ this ;
244+ }
245+
246+ /**
247+ * @return int
248+ */
249+ public function getCode (): int
250+ {
251+ return $ this ->code ;
252+ }
253+
254+ /**
255+ * @return bool
256+ */
257+ public function isFail (): bool
258+ {
259+ return $ this ->code !== 0 ;
260+ }
261+
262+ /**
263+ * @return bool
264+ */
265+ public function isSuccess (): bool
266+ {
267+ return $ this ->code === 0 ;
268+ }
269+
270+ /**
271+ * @param bool $trim
272+ *
273+ * @return string
274+ */
275+ public function getOutput (bool $ trim = false ): string
276+ {
277+ return $ trim ? trim ($ this ->output ) : $ this ->output ;
278+ }
279+
280+ /**
281+ * @return array
282+ */
283+ public function getResult (): array
284+ {
285+ return [
286+ 'code ' => $ this ->code ,
287+ 'output ' => $ this ->output ,
288+ ];
289+ }
290+
291+ /**
292+ * @param bool $printCmd
293+ *
294+ * @return $this
295+ */
296+ public function setPrintCmd (bool $ printCmd ): self
297+ {
298+ $ this ->printCmd = $ printCmd ;
299+ return $ this ;
300+ }
301+
302+ /**
303+ * @param bool $printOutput
304+ *
305+ * @return $this
306+ */
307+ public function setPrintOutput (bool $ printOutput ): self
308+ {
309+ $ this ->printOutput = $ printOutput ;
310+ return $ this ;
311+ }
312+
313+ /**
314+ * @return bool
315+ */
316+ public function isIgnoreError (): bool
317+ {
318+ return $ this ->ignoreError ;
319+ }
320+
321+ /**
322+ * @param bool $ignoreError
323+ *
324+ * @return $this
325+ */
326+ public function setIgnoreError (bool $ ignoreError ): self
327+ {
328+ $ this ->ignoreError = $ ignoreError ;
329+ return $ this ;
330+ }
331+
332+ /**
333+ * @param bool $dryRun
334+ *
335+ * @return $this
336+ */
337+ public function setDryRun (bool $ dryRun ): self
338+ {
339+ $ this ->dryRun = $ dryRun ;
340+ return $ this ;
341+ }
342+
343+ /**
344+ * @return bool
345+ */
346+ public function isDryRun (): bool
347+ {
348+ return $ this ->dryRun ;
349+ }
350+
351+ /**
352+ * @return string
353+ */
354+ public function getError (): string
355+ {
356+ return $ this ->error ;
357+ }
358+ }
0 commit comments