Skip to content

Commit a386f06

Browse files
committed
feat: add tool class for quick build cmd and run
1 parent d173e24 commit a386f06

File tree

4 files changed

+530
-1
lines changed

4 files changed

+530
-1
lines changed

.github/workflows/php.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
strategy:
1616
fail-fast: true
1717
matrix:
18-
php: [7.2, 7.3, 7.4] #
18+
php: [7.2, 7.3, 7.4, 8.0] #
1919
os: [ubuntu-latest, macOS-latest] # windows-latest,
2020

2121
steps:

src/Cmd/AbstractCmdBuilder.php

Lines changed: 358 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,358 @@
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

Comments
 (0)