mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-03-17 20:54:52 +08:00
add build command
This commit is contained in:
parent
c2c5433220
commit
85240c753b
@ -21,12 +21,6 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
result=$(echo "$1" | grep -E "module|build")
|
||||
|
||||
if [ "$result" != "" ]; then
|
||||
executable="$executable -d phar.readonly=off"
|
||||
fi
|
||||
|
||||
if [ -f "$(pwd)/src/entry.php" ]; then
|
||||
$executable "$(pwd)/src/entry.php" $@
|
||||
elif [ -f "$(pwd)/vendor/zhamao/framework/src/entry.php" ]; then
|
||||
|
||||
@ -13,7 +13,7 @@ IF /i "%ZM_CUSTOM_PHP_PATH%" neq "" (
|
||||
echo "* Using system PHP executable"
|
||||
SET executable=php
|
||||
)
|
||||
@REM TODO: Phar write support is missing
|
||||
|
||||
IF exist src/entry.php (
|
||||
@REM Run the PHP entry point
|
||||
%executable% src/entry.php %*
|
||||
|
||||
@ -5,12 +5,10 @@ declare(strict_types=1);
|
||||
namespace ZM\Command;
|
||||
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use ZM\Store\FileSystem;
|
||||
|
||||
#[AsCommand(name: 'build', description: '将项目构建一个phar包')]
|
||||
#[AsCommand(name: 'build', description: '将项目构建一个 Phar 包')]
|
||||
class BuildCommand extends Command
|
||||
{
|
||||
use NonPharLoadModeOnly;
|
||||
@ -20,81 +18,82 @@ class BuildCommand extends Command
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->setHelp('此功能将会把整个项目打包为phar');
|
||||
$this->addOption('target', 'D', InputOption::VALUE_REQUIRED, 'Output Directory | 指定输出目录');
|
||||
// ...
|
||||
$this->setHelp('此功能将会把整个项目打包为 Phar');
|
||||
$this->addOption('target', 'D', InputOption::VALUE_REQUIRED, '指定输出文件位置');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
protected function handle(): int
|
||||
{
|
||||
/* TODO
|
||||
$this->output = $output;
|
||||
$target_dir = $input->getOption('target') ?? WORKING_DIR;
|
||||
if (mb_strpos($target_dir, '../')) {
|
||||
$target_dir = realpath($target_dir);
|
||||
$this->ensurePharWritable();
|
||||
|
||||
$target = $this->input->getOption('target') ?? 'zm.phar';
|
||||
if (FileSystem::isRelativePath($target)) {
|
||||
$target = SOURCE_ROOT_DIR . '/' . $target;
|
||||
}
|
||||
if ($target_dir === false) {
|
||||
$output->writeln(TermColor::color8(31) . zm_internal_errcode('E00039') . 'Error: No such file or directory (' . $target_dir . ')' . TermColor::RESET);
|
||||
return 1;
|
||||
$this->ensureTargetWritable($target);
|
||||
$this->comment("目标文件:{$target}");
|
||||
|
||||
$this->info('正在构建 Phar 包');
|
||||
|
||||
$this->build($target, LOAD_MODE === LOAD_MODE_VENDOR ? 'src/entry.php' : 'vendor/zhamao/framework/src/entry.php');
|
||||
|
||||
$this->info('Phar 包构建完成');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
$output->writeln('Target: ' . $target_dir);
|
||||
if (mb_substr($target_dir, -1, 1) !== '/') {
|
||||
$target_dir .= '/';
|
||||
}
|
||||
if (ini_get('phar.readonly') == 1) {
|
||||
$output->writeln(TermColor::color8(31) . zm_internal_errcode('E00040') . 'You need to set "phar.readonly" to "Off"!');
|
||||
$output->writeln(TermColor::color8(31) . 'See: https://stackoverflow.com/questions/34667606/cant-enable-phar-writing');
|
||||
return 1;
|
||||
}
|
||||
if (!is_dir($target_dir)) {
|
||||
$output->writeln(TermColor::color8(31) . zm_internal_errcode('E00039') . "Error: No such file or directory ({$target_dir})" . TermColor::RESET);
|
||||
return 1;
|
||||
}
|
||||
$filename = 'server.phar';
|
||||
$this->build($target_dir, $filename);
|
||||
*/
|
||||
$output->writeln('<error>Not implemented.</error>');
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
private function build($target_dir, $filename)
|
||||
|
||||
private function ensurePharWritable(): void
|
||||
{
|
||||
@unlink($target_dir . $filename);
|
||||
$phar = new Phar($target_dir . $filename);
|
||||
if (ini_get('phar.readonly') === '1') {
|
||||
if (!function_exists('pcntl_exec')) {
|
||||
$this->error('Phar 处于只读模式,且 pcntl 扩展未加载,无法自动切换到读写模式。');
|
||||
$this->error('请修改 php.ini 中的 phar.readonly 为 0,或执行 php -d phar.readonly=0 ' . $_SERVER['PHP_SELF'] . ' build');
|
||||
exit(1);
|
||||
}
|
||||
// Windows 下无法使用 pcntl_exec
|
||||
if (DIRECTORY_SEPARATOR === '\\') {
|
||||
$this->error('Phar 处于只读模式,且当前运行环境为 Windows,无法自动切换到读写模式。');
|
||||
$this->error('请修改 php.ini 中的 phar.readonly 为 0,或执行 php -d phar.readonly=0 ' . $_SERVER['PHP_SELF'] . ' build');
|
||||
exit(1);
|
||||
}
|
||||
$this->info('Phar 处于只读模式,正在尝试切换到读写模式...');
|
||||
sleep(1);
|
||||
$args = array_merge(['php', '-d', 'phar.readonly=0'], $_SERVER['argv']);
|
||||
if (pcntl_exec('/usr/bin/env', $args) === false) {
|
||||
$this->error('切换到读写模式失败,请检查环境。');
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function ensureTargetWritable(string $target): void
|
||||
{
|
||||
if (file_exists($target) && !is_writable($target)) {
|
||||
$this->error('目标文件不可写:' . $target);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private function build(string $target, string $entry): void
|
||||
{
|
||||
$phar = new \Phar($target, 0, $target);
|
||||
|
||||
$phar->startBuffering();
|
||||
|
||||
$all = DataProvider::scanDirFiles(DataProvider::getSourceRootDir(), true, true);
|
||||
|
||||
$all = array_filter($all, function ($x) {
|
||||
$files = FileSystem::scanDirFiles(SOURCE_ROOT_DIR, true, true);
|
||||
$files = array_filter($files, function ($x) {
|
||||
$dirs = preg_match('/(^(bin|config|resources|src|vendor)\\/|^(composer\\.json|README\\.md)$)/', $x);
|
||||
return !($dirs !== 1);
|
||||
});
|
||||
sort($files);
|
||||
|
||||
sort($all);
|
||||
foreach ($this->progress()->iterate($files) as $file) {
|
||||
$phar->addFile($file, $file);
|
||||
}
|
||||
|
||||
$archive_dir = DataProvider::getSourceRootDir();
|
||||
$map = [];
|
||||
|
||||
if (class_exists('\\League\\CLImate\\CLImate')) {
|
||||
$climate = new CLImate();
|
||||
$progress = $climate->progress()->total(count($all));
|
||||
}
|
||||
foreach ($all as $k => $v) {
|
||||
$map[$v] = $archive_dir . '/' . $v;
|
||||
if (isset($progress)) {
|
||||
$progress->current($k + 1, 'Adding ' . $v);
|
||||
}
|
||||
}
|
||||
$this->output->write('<info>Building...</info>');
|
||||
$phar->buildFromIterator(new ArrayIterator($map));
|
||||
$phar->setStub(
|
||||
"#!/usr/bin/env php\n" .
|
||||
$phar->createDefaultStub(LOAD_MODE == 0 ? 'src/entry.php' : 'vendor/zhamao/framework/src/entry.php')
|
||||
'#!/usr/bin/env php' . PHP_EOL .
|
||||
$phar::createDefaultStub($entry)
|
||||
);
|
||||
$phar->stopBuffering();
|
||||
$this->output->writeln('');
|
||||
$this->output->writeln('Successfully built. Location: ' . $target_dir . "{$filename}");
|
||||
$this->output->writeln('<info>You may use `chmod +x server.phar` to let phar executable with `./` command</info>');
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace ZM\Command;
|
||||
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\ConsoleOutputInterface;
|
||||
use Symfony\Component\Console\Output\ConsoleSectionOutput;
|
||||
@ -151,4 +152,21 @@ abstract class Command extends \Symfony\Component\Console\Command\Command
|
||||
exit(self::FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个进度条实例
|
||||
*
|
||||
* @param int $max 最大进度值,可以稍后再设置
|
||||
*/
|
||||
protected function progress(int $max = 0): ProgressBar
|
||||
{
|
||||
$progress = new ProgressBar($this->output, $max);
|
||||
$progress->setBarCharacter('<fg=green>⚬</>');
|
||||
$progress->setEmptyBarCharacter('<fg=red>⚬</>');
|
||||
$progress->setProgressCharacter('<fg=green>➤</>');
|
||||
$progress->setFormat(
|
||||
"%current%/%max% [%bar%] %percent:3s%%\n🪅 %estimated:-20s% %memory:20s%"
|
||||
);
|
||||
return $progress;
|
||||
}
|
||||
}
|
||||
|
||||
6
zhamao
6
zhamao
@ -21,12 +21,6 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
result=$(echo "$1" | grep -E "module|build")
|
||||
|
||||
if [ "$result" != "" ]; then
|
||||
executable="$executable -d phar.readonly=off"
|
||||
fi
|
||||
|
||||
if [ -f "$(pwd)/src/entry.php" ]; then
|
||||
$executable "$(pwd)/src/entry.php" $@
|
||||
elif [ -f "$(pwd)/vendor/zhamao/framework/src/entry.php" ]; then
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user