zhamao-framework/src/ZM/Command/BuildCommand.php

105 lines
3.7 KiB
PHP
Raw Normal View History

2020-08-31 10:11:06 +08:00
<?php
declare(strict_types=1);
2020-08-31 10:11:06 +08:00
namespace ZM\Command;
use ArrayIterator;
2021-07-04 15:45:30 +08:00
use League\CLImate\CLImate;
2020-08-31 10:11:06 +08:00
use Phar;
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\Console\TermColor;
2021-06-16 00:17:30 +08:00
use ZM\Utils\DataProvider;
2020-08-31 10:11:06 +08:00
class BuildCommand extends Command
{
// the name of the command (the part after "bin/console")
protected static $defaultName = 'build';
2020-08-31 10:11:06 +08:00
/**
* @var OutputInterface
*/
private $output;
2020-08-31 10:11:06 +08:00
protected function configure()
{
$this->setDescription('Build an ".phar" file | 将项目构建一个phar包');
$this->setHelp('此功能将会把整个项目打包为phar');
$this->addOption('target', 'D', InputOption::VALUE_REQUIRED, 'Output Directory | 指定输出目录');
2020-08-31 10:11:06 +08:00
// ...
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
2020-08-31 10:11:06 +08:00
$this->output = $output;
$target_dir = $input->getOption('target') ?? (WORKING_DIR);
if (mb_strpos($target_dir, '../')) {
$target_dir = realpath($target_dir);
}
2020-08-31 10:11:06 +08:00
if ($target_dir === false) {
$output->writeln(TermColor::color8(31) . zm_internal_errcode('E00039') . 'Error: No such file or directory (' . $target_dir . ')' . TermColor::RESET);
2021-04-06 01:19:56 +08:00
return 1;
2020-08-31 10:11:06 +08:00
}
$output->writeln('Target: ' . $target_dir);
if (mb_substr($target_dir, -1, 1) !== '/') {
$target_dir .= '/';
}
2020-08-31 10:11:06 +08:00
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');
2021-04-06 01:19:56 +08:00
return 1;
2020-08-31 10:11:06 +08:00
}
if (!is_dir($target_dir)) {
$output->writeln(TermColor::color8(31) . zm_internal_errcode('E00039') . "Error: No such file or directory ({$target_dir})" . TermColor::RESET);
2021-04-06 01:19:56 +08:00
return 1;
2020-08-31 10:11:06 +08:00
}
$filename = 'server.phar';
2020-08-31 10:11:06 +08:00
$this->build($target_dir, $filename);
2021-04-06 01:19:56 +08:00
return 0;
2020-08-31 10:11:06 +08:00
}
private function build($target_dir, $filename)
{
2020-08-31 10:11:06 +08:00
@unlink($target_dir . $filename);
$phar = new Phar($target_dir . $filename);
$phar->startBuffering();
2021-06-16 00:17:30 +08:00
2021-07-04 15:45:30 +08:00
$all = DataProvider::scanDirFiles(DataProvider::getSourceRootDir(), true, true);
$all = array_filter($all, function ($x) {
$dirs = preg_match('/(^(bin|config|resources|src|vendor)\\/|^(composer\\.json|README\\.md)$)/', $x);
2021-07-04 15:45:30 +08:00
return !($dirs !== 1);
});
sort($all);
2021-06-16 00:17:30 +08:00
$archive_dir = DataProvider::getSourceRootDir();
$map = [];
if (class_exists('\\League\\CLImate\\CLImate')) {
$climate = new CLImate();
$progress = $climate->progress()->total(count($all));
}
2021-07-04 15:45:30 +08:00
foreach ($all as $k => $v) {
$map[$v] = $archive_dir . '/' . $v;
if (isset($progress)) {
$progress->current($k + 1, 'Adding ' . $v);
}
2021-06-16 00:17:30 +08:00
}
$this->output->write('<info>Building...</info>');
$phar->buildFromIterator(new ArrayIterator($map));
2021-06-16 00:17:30 +08:00
$phar->setStub(
"#!/usr/bin/env php\n" .
$phar->createDefaultStub(LOAD_MODE == 0 ? 'src/entry.php' : 'vendor/zhamao/framework/src/entry.php')
2021-06-16 00:17:30 +08:00
);
2020-08-31 10:11:06 +08:00
$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>');
2020-08-31 10:11:06 +08:00
}
}