123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- <?php
- /**
- * +----------------------------------------------------------------------
- * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
- * +----------------------------------------------------------------------
- * | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
- * +----------------------------------------------------------------------
- * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
- * +----------------------------------------------------------------------
- * | Author: CRMEB Team <admin@crmeb.com>
- * +----------------------------------------------------------------------
- */
- namespace crmeb\utils;
- use think\Response;
- use think\console\Output;
- /**
- * 执行命令
- * Class Terminal
- * @author 等风来
- * @email 136327134@qq.com
- * @date 2023/4/13
- * @package crmeb\utils
- */
- class Terminal
- {
- /**
- * 命令
- * @var \string[][]
- */
- protected $command = [
- 'npm-build' => [
- 'run_root' => '',
- 'command' => 'npm run build',
- ],
- 'npm-install' => [
- 'run_root' => '',
- 'command' => 'npm run install',
- ],
- ];
- /**
- * 执行内容保存地址
- * @var string
- */
- protected $outputFile;
- /**
- * 执行状态
- * @var integer
- */
- protected $procStatus;
- /**
- * 响应内容
- * @var string
- */
- protected $outputContent;
- /**
- * @var
- */
- protected $output;
- /**
- * Terminal constructor.
- */
- public function __construct()
- {
- $this->command['npm-build']['run_root'] = str_replace('DS', DS, config('app.admin_template_path'));
- $this->command['npm-install']['run_root'] = str_replace('DS', DS, config('app.admin_template_path'));
- $outputDir = root_path() . 'runtime' . DIRECTORY_SEPARATOR . 'terminal';
- $this->outputFile = $outputDir . DIRECTORY_SEPARATOR . 'exec.log';
- if (!is_dir($outputDir)) {
- mkdir($outputDir, 0755, true);
- }
- file_put_contents($this->outputFile, '');
- }
- /**
- * @param Output $output
- * @author 等风来
- * @email 136327134@qq.com
- * @date 2023/4/13
- */
- public function setOutput(Output $output)
- {
- $this->output = $output;
- }
- /**
- * @return string
- * @author 等风来
- * @email 136327134@qq.com
- * @date 2023/4/13
- */
- public function adminTemplatePath()
- {
- return $this->command['npm-install']['run_root'];
- }
- /**
- * 执行
- * @param string $name
- * @return string
- * @author 等风来
- * @email 136327134@qq.com
- * @date 2023/4/13
- */
- public function run(string $name)
- {
- if (!function_exists('proc_open')) {
- throw new \RuntimeException('缺少proc_open函数无法运行');
- }
- if (!isset($this->command[$name])) {
- throw new \RuntimeException('运行的命令不存在');
- }
- $command = $this->command[$name];
- $descriptorspec = [0 => ['pipe', 'r'], 1 => ['file', $this->outputFile, 'w'], 2 => ['file', $this->outputFile, 'w']];
- $process = proc_open($command['command'], $descriptorspec, $pipes, $command['run_root'], null, ['suppress_errors' => true]);
- if (is_resource($process)) {
- while ($this->getProcStatus($process)) {
- $contents = file_get_contents($this->outputFile);
- if (strlen($contents) && $this->outputContent != $contents) {
- $newOutput = str_replace($this->outputContent, '', $contents);
- if (preg_match('/\r\n|\r|\n/', $newOutput)) {
- $this->echoOutputFlag($newOutput);
- $this->outputContent = $contents;
- }
- }
- usleep(500000);
- }
- foreach ($pipes as $pipe) {
- fclose($pipe);
- }
- proc_close($process);
- }
- return $this->output('run success');
- }
- /**
- * 判断状态
- * @param $process
- * @return bool
- * @author 等风来
- * @email 136327134@qq.com
- * @date 2023/4/13
- */
- public function getProcStatus($process): bool
- {
- $status = proc_get_status($process);
- if ($status['running']) {
- $this->procStatus = 1;
- return true;
- } elseif ($this->procStatus === 1) {
- $this->procStatus = 0;
- $this->output('exit: ' . $status['exitcode']);
- if ($status['exitcode'] === 0) {
- $this->echoOutputFlag('success');
- } else {
- $this->echoOutputFlag('error');
- }
- return true;
- } else {
- return false;
- }
- }
- /**
- * 直接输入响应
- * @param string $message
- * @author 等风来
- * @email 136327134@qq.com
- * @date 2023/4/13
- */
- public function echoOutputFlag(string $message)
- {
- if ($this->output && $this->output instanceof Output) {
- $this->output->info($message);
- } else {
- echo $this->output($message);
- @ob_flush();
- }
- }
- /**
- * 返回响应内容
- * @param string $data
- * @return string
- * @author 等风来
- * @email 136327134@qq.com
- * @date 2023/4/13
- */
- private function output($data)
- {
- $data = [
- 'message' => $data,
- ];
- return Response::create($data, 'json')->getContent();
- }
- }
|