diff --git a/composer.json b/composer.json index c7b9f9f9..ea8e8baf 100644 --- a/composer.json +++ b/composer.json @@ -9,16 +9,15 @@ } ], "require": { - "php": ">= 8.0", - "ext-tokenizer": "*", - "ext-iconv": "*", + "php": ">= 8.1", + "ext-pcntl": "*", + "ext-mbstring": "*", + "laravel/prompts": "dev-main", "symfony/console": "^6 || ^5 || ^4", - "zhamao/logger": "^1.0", - "crazywhalecc/cli-helper": "^0.1.0", - "nunomaduro/collision": "*", - "ext-pcntl": "*" + "zhamao/logger": "^1.0" }, "require-dev": { + "nunomaduro/collision": "*", "friendsofphp/php-cs-fixer": "^3.2 != 3.7.0", "phpstan/phpstan": "^1.1", "captainhook/captainhook": "^5.10", diff --git a/src/SPC/command/DeployCommand.php b/src/SPC/command/DeployCommand.php index 0409f0b0..5dd5ddee 100644 --- a/src/SPC/command/DeployCommand.php +++ b/src/SPC/command/DeployCommand.php @@ -4,14 +4,15 @@ declare(strict_types=1); namespace SPC\command; -use CliHelper\Tools\ArgFixer; -use CliHelper\Tools\DataProvider; -use CliHelper\Tools\SeekableArrayIterator; +use SPC\store\FileSystem; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; +use function Laravel\Prompts\confirm; +use function Laravel\Prompts\text; + #[AsCommand('deploy', 'Deploy static-php-cli self to an .phar application')] class DeployCommand extends BaseCommand { @@ -20,26 +21,51 @@ class DeployCommand extends BaseCommand $this->addArgument('target', InputArgument::OPTIONAL, 'The file or directory to pack.'); $this->addOption('auto-phar-fix', null, InputOption::VALUE_NONE, 'Automatically fix ini option.'); $this->addOption('overwrite', 'W', InputOption::VALUE_NONE, 'Overwrite existing files.'); + $this->addOption('with-no-dev', 'D', InputOption::VALUE_NONE, 'Automatically use non-dev composer dependencies to reduce size'); + $this->addOption('with-dev', 'd', InputOption::VALUE_NONE, 'Automatically use dev composer dependencies'); } public function handle(): int { - // 第一阶段流程:如果没有写path,将会提示输入要打包的path - $prompt = new ArgFixer($this->input, $this->output); + $composer = require ROOT_DIR . '/vendor/composer/installed.php'; + if (($composer['root']['dev'] ?? false) === true) { + if (!$this->getOption('with-no-dev')) { + $this->output->writeln('Current static-php-cli dependencies have installed dev-dependencies'); + $this->output->writeln('If you want to remove, you can choose "Yes" to run command "composer update --no-dev" to remove.'); + $this->output->writeln('Or choose "No", just pack, deploy.'); + $ask = confirm('Do you want to remove dev-dependencies to reduce size of phar file?'); + } elseif (!$this->getOption('with-dev')) { + $ask = true; + } else { + $ask = false; + } + if ($ask) { + [$code] = shell()->execWithResult('composer update --no-dev'); + if ($code !== 0) { + $this->output->writeln('"composer update --no-dev" failed with exit code [' . $code . ']'); + $this->output->writeln('You may need to run this command by your own.'); + return static::FAILURE; + } + $this->output->writeln('Update successfully, you need to re-run deploy command to pack.'); + return static::SUCCESS; + } + } // 首先得确认是不是关闭了readonly模式 if (ini_get('phar.readonly') == 1) { if ($this->getOption('auto-phar-fix')) { $ask = true; } else { - $ask = $prompt->requireBool('pack command needs "phar.readonly" = "Off" !' . PHP_EOL . 'If you want to automatically set it and continue, just Enter', true); + $this->output->writeln('pack command needs "phar.readonly" = "Off" !'); + $ask = confirm('Do you want to automatically set it and continue ?'); + // $ask = $prompt->requireBool('pack command needs "phar.readonly" = "Off" !' . PHP_EOL . 'If you want to automatically set it and continue, just Enter', true); } if ($ask) { global $argv; - $args = array_merge(['-d', 'phar.readonly=0'], $_SERVER['argv']); + $args = array_merge(['-d', 'phar.readonly=0'], $_SERVER['argv'], ['--no-motd']); if (function_exists('pcntl_exec')) { $this->output->writeln('Changing to phar.readonly=0 mode ...'); if (pcntl_exec(PHP_BINARY, $args) === false) { - throw new \PharException('切换到读写模式失败,请检查环境。'); + throw new \PharException('Switching to read write mode failed, please check the environment.'); } } else { $this->output->writeln('Now running command in child process.'); @@ -51,13 +77,19 @@ class DeployCommand extends BaseCommand // 获取路径 $path = WORKING_DIR; // 如果是目录,则将目录下的所有文件打包 - $phar_path = $prompt->requireArgument('target', 'Please input the phar target filename', 'static-php-cli.phar'); + $phar_path = text('Please input the phar target filename', default: '/tmp/static-php-cli.phar'); + // $phar_path = $prompt->requireArgument('target', 'Please input the phar target filename', 'static-php-cli.phar'); - if (DataProvider::isRelativePath($phar_path)) { - $phar_path = '/tmp/' . $phar_path; + if (FileSystem::isRelativePath($phar_path)) { + $phar_path = WORKING_DIR . '/' . $phar_path; } if (file_exists($phar_path)) { - $ask = $this->getOption('overwrite') ? true : $prompt->requireBool('The file "' . $phar_path . '" already exists, do you want to overwrite it?' . PHP_EOL . 'If you want to, just Enter'); + if (!$this->getOption('overwrite')) { + $this->output->writeln('The file "' . $phar_path . '" already exists.'); + $ask = confirm('Do you want to overwrite it?'); + } else { + $ask = true; + } if (!$ask) { $this->output->writeln('User canceled.'); return static::FAILURE; @@ -67,7 +99,7 @@ class DeployCommand extends BaseCommand $phar = new \Phar($phar_path); $phar->startBuffering(); - $all = DataProvider::scanDirFiles($path, true, true); + $all = FileSystem::scanDirFiles($path, true, true); $all = array_filter($all, function ($x) { $dirs = preg_match('/(^(config|src|vendor)\\/|^(composer\\.json|README\\.md|source\\.json|LICENSE|README-en\\.md)$)/', $x); diff --git a/src/SPC/exception/ExceptionHandler.php b/src/SPC/exception/ExceptionHandler.php index 40773da3..0f03efba 100644 --- a/src/SPC/exception/ExceptionHandler.php +++ b/src/SPC/exception/ExceptionHandler.php @@ -47,7 +47,8 @@ class ExceptionHandler logger()->error($e->getTraceAsString()); return; } - $this->whoops->handleException($e); + + logger()->critical('You can report this exception to static-php-cli GitHub repo.'); } } diff --git a/src/SPC/store/FileSystem.php b/src/SPC/store/FileSystem.php index b8439dbe..ab0028ef 100644 --- a/src/SPC/store/FileSystem.php +++ b/src/SPC/store/FileSystem.php @@ -320,28 +320,7 @@ class FileSystem foreach ($files as $v) { $pathinfo = pathinfo($v); if (($pathinfo['extension'] ?? '') == 'php') { - $path = rtrim($dir, '/') . '/' . rtrim($pathinfo['dirname'], './') . '/' . $pathinfo['basename']; - - // 过滤不包含类的文件 - $tokens = token_get_all(self::readFile($path)); - $found = false; - foreach ($tokens as $token) { - if (!is_array($token)) { - continue; - } - if ($token[0] === T_CLASS) { - $found = true; - break; - } - } - if (!$found) { - continue; - } - - if ($rule === null) { // 规则未设置回调时候,使用默认的识别过滤规则 - /*if (substr(file_get_contents($dir . '/' . $v), 6, 6) == '#plain') { - continue; - }*/ + if ($rule === null) { if (file_exists($dir . '/' . $pathinfo['basename'] . '.ignore')) { continue; }