diff --git a/box.json b/box.json new file mode 100644 index 000000000..e5f82806e --- /dev/null +++ b/box.json @@ -0,0 +1,18 @@ +{ + "alias": "spc-php.phar", + "banner": false, + "blacklist": [ + ".github" + ], + "directories": [ + "config", + "src", + "vendor/psr", + "vendor/laravel/prompts", + "vendor/symfony", + "vendor/zhamao" + ], + "git-commit-short": "git_commit_short", + "metadata": "ConsoleApplication::VERSION", + "output": "spc.phar" +} diff --git a/composer.json b/composer.json index 14f6189be..706f8d646 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ "captainhook/captainhook": "^5.10", "captainhook/plugin-composer": "^5.3", "friendsofphp/php-cs-fixer": "^3.25", + "humbug/box": "^4.3", "nunomaduro/collision": "^7.8", "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^10.3" @@ -44,7 +45,8 @@ "scripts": { "analyse": "phpstan analyse --memory-limit 300M", "cs-fix": "php-cs-fixer fix", - "test": "vendor/bin/phpunit tests/ --no-coverage" + "test": "vendor/bin/phpunit tests/ --no-coverage", + "build:phar": "vendor/bin/box compile" }, "config": { "allow-plugins": { diff --git a/src/SPC/ConsoleApplication.php b/src/SPC/ConsoleApplication.php index 09c572385..b3e1de8bc 100644 --- a/src/SPC/ConsoleApplication.php +++ b/src/SPC/ConsoleApplication.php @@ -6,7 +6,6 @@ use SPC\command\BuildCliCommand; use SPC\command\BuildLibsCommand; -use SPC\command\DeployCommand; use SPC\command\dev\AllExtCommand; use SPC\command\dev\PhpVerCommand; use SPC\command\dev\SortConfigCommand; @@ -39,7 +38,6 @@ public function __construct() [ new BuildCliCommand(), new BuildLibsCommand(), - new DeployCommand(), new DoctorCommand(), new DownloadCommand(), new DumpLicenseCommand(), diff --git a/src/SPC/command/DeployCommand.php b/src/SPC/command/DeployCommand.php deleted file mode 100644 index 770fc39ce..000000000 --- a/src/SPC/command/DeployCommand.php +++ /dev/null @@ -1,166 +0,0 @@ -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'); - } - - /** - * @throws \PharException - */ - public function handle(): int - { - $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 { - $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'], ['--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('Switching to read write mode failed, please check the environment.'); - } - } else { - $this->output->writeln('Now running command in child process.'); - passthru(PHP_BINARY . ' -d phar.readonly=0 ' . implode(' ', $argv), $retcode); - exit($retcode); - } - } - } - // 获取路径 - $path = WORKING_DIR; - // 如果是目录,则将目录下的所有文件打包 - $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 (FileSystem::isRelativePath($phar_path)) { - $phar_path = WORKING_DIR . '/' . $phar_path; - } - if (file_exists($phar_path)) { - 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; - } - @unlink($phar_path); - } - $phar = new \Phar($phar_path); - $phar->startBuffering(); - - $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); - return !($dirs !== 1); - }); - sort($all); - $map = []; - foreach ($all as $v) { - $map[$v] = $path . '/' . $v; - } - - $this->output->writeln('Start packing files...'); - try { - foreach ($this->progress()->iterate($map) as $file => $origin_file) { - $phar->addFromString($file, php_strip_whitespace($origin_file)); - } - // $phar->buildFromIterator(new SeekableArrayIterator($map, new ProgressBar($output))); - $phar->addFromString( - '.phar-entry.php', - str_replace( - '/../vendor/autoload.php', - '/vendor/autoload.php', - file_get_contents(ROOT_DIR . '/bin/spc') - ) - ); - $stub = '.phar-entry.php'; - $phar->setStub($phar->createDefaultStub($stub)); - } catch (\Throwable $e) { - $this->output->writeln($e); - return static::FAILURE; - } - $phar->addFromString('.prod', 'true'); - $phar->stopBuffering(); - $this->output->writeln(PHP_EOL . 'Done! Phar file is generated at "' . $phar_path . '".'); - if (file_exists(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx')) { - $this->output->writeln('Detected you have already compiled micro binary, I will make executable now for you!'); - file_put_contents( - pathinfo($phar_path, PATHINFO_DIRNAME) . '/spc', - file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx') . - file_get_contents($phar_path) - ); - chmod(pathinfo($phar_path, PATHINFO_DIRNAME) . '/spc', 0755); - $this->output->writeln('Binary Executable: ' . pathinfo($phar_path, PATHINFO_DIRNAME) . '/spc'); - } - chmod($phar_path, 0755); - $this->output->writeln('Phar Executable: ' . $phar_path . ''); - return static::SUCCESS; - } - - private function progress(): ProgressBar - { - $progress = new ProgressBar($this->output, 0); - $progress->setBarCharacter('⚬'); - $progress->setEmptyBarCharacter('⚬'); - $progress->setProgressCharacter('➤'); - $progress->setFormat( - "%current%/%max% [%bar%] %percent:3s%%\n🪅 %estimated:-20s% %memory:20s%" . PHP_EOL - ); - return $progress; - } -}