mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-03 14:55:39 +08:00
Refactor shell utilities: reorganize namespaces and introduce Shell base class
This commit is contained in:
114
src/SPC/util/shell/UnixShell.php
Normal file
114
src/SPC/util/shell/UnixShell.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\shell;
|
||||
|
||||
use SPC\builder\freebsd\library\BSDLibraryBase;
|
||||
use SPC\builder\linux\library\LinuxLibraryBase;
|
||||
use SPC\builder\macos\library\MacOSLibraryBase;
|
||||
use SPC\exception\SPCInternalException;
|
||||
use ZM\Logger\ConsoleColor;
|
||||
|
||||
/**
|
||||
* Unix-like OS shell command executor.
|
||||
*
|
||||
* This class provides methods to execute shell commands in a Unix-like environment.
|
||||
* It supports setting environment variables and changing the working directory.
|
||||
*/
|
||||
class UnixShell extends Shell
|
||||
{
|
||||
public function __construct(?bool $debug = null)
|
||||
{
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
throw new SPCInternalException('Windows cannot use UnixShell');
|
||||
}
|
||||
parent::__construct($debug);
|
||||
}
|
||||
|
||||
public function exec(string $cmd): static
|
||||
{
|
||||
/* @phpstan-ignore-next-line */
|
||||
logger()->info(ConsoleColor::yellow('[EXEC] ') . ConsoleColor::green($cmd));
|
||||
$original_command = $cmd;
|
||||
$this->logCommandInfo($original_command);
|
||||
$this->last_cmd = $cmd = $this->getExecString($cmd);
|
||||
$this->passthru($cmd, $this->debug, $original_command);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the environment variable that common build will be used.
|
||||
*
|
||||
* @param BSDLibraryBase|LinuxLibraryBase|MacOSLibraryBase $library Library class
|
||||
*/
|
||||
public function initializeEnv(BSDLibraryBase|LinuxLibraryBase|MacOSLibraryBase $library): UnixShell
|
||||
{
|
||||
$this->setEnv([
|
||||
'CFLAGS' => $library->getLibExtraCFlags(),
|
||||
'CXXFLAGS' => $library->getLibExtraCXXFlags(),
|
||||
'LDFLAGS' => $library->getLibExtraLdFlags(),
|
||||
'LIBS' => $library->getLibExtraLibs(),
|
||||
]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function execWithResult(string $cmd, bool $with_log = true): array
|
||||
{
|
||||
if ($with_log) {
|
||||
/* @phpstan-ignore-next-line */
|
||||
logger()->info(ConsoleColor::blue('[EXEC] ') . ConsoleColor::green($cmd));
|
||||
} else {
|
||||
/* @phpstan-ignore-next-line */
|
||||
logger()->debug(ConsoleColor::blue('[EXEC] ') . ConsoleColor::gray($cmd));
|
||||
}
|
||||
$cmd = $this->getExecString($cmd);
|
||||
exec($cmd, $out, $code);
|
||||
return [$code, $out];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns unix-style environment variable string.
|
||||
*/
|
||||
public function getEnvString(): string
|
||||
{
|
||||
$str = '';
|
||||
foreach ($this->env as $k => $v) {
|
||||
$str .= ' ' . $k . '="' . $v . '"';
|
||||
}
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
protected function logCommandInfo(string $cmd): void
|
||||
{
|
||||
// write executed command to log file using fwrite
|
||||
$log_file = fopen(SPC_SHELL_LOG, 'a');
|
||||
fwrite($log_file, "\n>>>>>>>>>>>>>>>>>>>>>>>>>> [" . date('Y-m-d H:i:s') . "]\n");
|
||||
fwrite($log_file, "> Executing command: {$cmd}\n");
|
||||
// get the backtrace to find the file and line number
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
|
||||
if (isset($backtrace[1]['file'], $backtrace[1]['line'])) {
|
||||
$file = $backtrace[1]['file'];
|
||||
$line = $backtrace[1]['line'];
|
||||
fwrite($log_file, "> Called from: {$file} at line {$line}\n");
|
||||
}
|
||||
fwrite($log_file, "> Environment variables: {$this->getEnvString()}\n");
|
||||
if ($this->cd !== null) {
|
||||
fwrite($log_file, "> Working dir: {$this->cd}\n");
|
||||
}
|
||||
fwrite($log_file, "\n");
|
||||
}
|
||||
|
||||
private function getExecString(string $cmd): string
|
||||
{
|
||||
// logger()->debug('Executed at: ' . debug_backtrace()[0]['file'] . ':' . debug_backtrace()[0]['line']);
|
||||
$env_str = $this->getEnvString();
|
||||
if (!empty($env_str)) {
|
||||
$cmd = "{$env_str} {$cmd}";
|
||||
}
|
||||
if ($this->cd !== null) {
|
||||
$cmd = 'cd ' . escapeshellarg($this->cd) . ' && ' . $cmd;
|
||||
}
|
||||
return $cmd;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user