Compare commits

..

10 Commits

Author SHA1 Message Date
crazywhalecc
a00f8945ba add glfw support for macOS 2023-08-19 00:27:20 +08:00
crazywhalecc
2bc02bdaac add glfw support for macOS 2023-08-19 00:27:20 +08:00
Chuong
b97327d6d7 mongodb source.json change from tgz to zip
since ver https://github.com/mongodb/mongo-php-driver/releases/tag/1.16.2

they don't support tgz anymore.
2023-08-18 17:57:08 +08:00
crazywhalecc
61d1507a4d add redis-session support 2023-08-09 11:01:36 +08:00
crazywhalecc
a6f07051c3 update readme about version and dependencies 2023-08-08 20:35:25 +08:00
crazywhalecc
75417d15b7 change laravel/prompts version 2023-08-08 20:30:06 +08:00
crazywhalecc
4bab7ecfab add laravel/prompts support, and change deploy commands and exception handlers 2023-08-08 20:30:06 +08:00
crazywhalecc
7298e2441b remove list-ext command, use all-ext and alias to support its function 2023-08-08 19:24:11 +08:00
Jerry Ma
1ed104d2f6 Update README-en.md 2023-08-07 11:38:22 +08:00
Jerry Ma
cf6125b9cc Update README.md 2023-08-07 11:38:12 +08:00
16 changed files with 172 additions and 89 deletions

View File

@@ -11,7 +11,7 @@ This feature is provided by [dixyes/phpmicro](https://github.com/dixyes/phpmicro
<img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png"> <img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
[![Version](https://img.shields.io/badge/Version-2.0--rc3-pink.svg?style=flat-square)]() [![Version](https://img.shields.io/badge/Version-2.0--rc4-pink.svg?style=flat-square)]()
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)]() [![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)]()
[![](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/build-linux-x86_64.yml?branch=refactor&label=Linux%20Build&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml) [![](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/build-linux-x86_64.yml?branch=refactor&label=Linux%20Build&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
[![](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/build-macos-x86_64.yml?branch=refactor&label=macOS%20Build&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml) [![](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/build-macos-x86_64.yml?branch=refactor&label=macOS%20Build&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
@@ -24,7 +24,7 @@ This feature is provided by [dixyes/phpmicro](https://github.com/dixyes/phpmicro
## Compilation Requirements ## Compilation Requirements
Yes, this project is written in PHP, pretty funny. Yes, this project is written in PHP, pretty funny.
But static-php-cli runtime only requires an environment above PHP 8.0 and `tokenizer`, `iconv` extension. But static-php-cli runtime only requires an environment above PHP 8.1 and `mbstring`, `pcntl` extension.
Here is the architecture support status, where `CI` represents support for GitHub Action builds, Here is the architecture support status, where `CI` represents support for GitHub Action builds,
`Local` represents support for local builds, and blank represents not currently supported. `Local` represents support for local builds, and blank represents not currently supported.

View File

@@ -12,7 +12,7 @@ Compile A Statically Linked PHP With Swoole and other Extensions.
<img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png"> <img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
[![Version](https://img.shields.io/badge/Version-2.0--rc3-pink.svg?style=flat-square)]() [![Version](https://img.shields.io/badge/Version-2.0--rc4-pink.svg?style=flat-square)]()
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)]() [![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)]()
[![](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/build-linux-x86_64.yml?branch=refactor&label=Linux%20Build&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml) [![](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/build-linux-x86_64.yml?branch=refactor&label=Linux%20Build&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
[![](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/build-macos-x86_64.yml?branch=refactor&label=macOS%20Build&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml) [![](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/build-macos-x86_64.yml?branch=refactor&label=macOS%20Build&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
@@ -24,7 +24,7 @@ Compile A Statically Linked PHP With Swoole and other Extensions.
## 编译环境需求 ## 编译环境需求
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。 是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含 tokenizer 扩展和 PHP 版本大于等于 8.0 即可。 但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含 mbstring、pcntl 扩展和 PHP 版本大于等于 8.1 即可。
下面是架构支持情况,`CI` 代表支持 GitHub Action 构建,`Local` 代表支持本地构建,空 代表暂不支持。 下面是架构支持情况,`CI` 代表支持 GitHub Action 构建,`Local` 代表支持本地构建,空 代表暂不支持。

View File

@@ -9,16 +9,15 @@
} }
], ],
"require": { "require": {
"php": ">= 8.0", "php": ">= 8.1",
"ext-tokenizer": "*", "ext-mbstring": "*",
"ext-iconv": "*", "ext-pcntl": "*",
"laravel/prompts": "^0.1.3",
"symfony/console": "^6 || ^5 || ^4", "symfony/console": "^6 || ^5 || ^4",
"zhamao/logger": "^1.0", "zhamao/logger": "^1.0"
"crazywhalecc/cli-helper": "^0.1.0",
"nunomaduro/collision": "*",
"ext-pcntl": "*"
}, },
"require-dev": { "require-dev": {
"nunomaduro/collision": "*",
"friendsofphp/php-cs-fixer": "^3.2 != 3.7.0", "friendsofphp/php-cs-fixer": "^3.2 != 3.7.0",
"phpstan/phpstan": "^1.1", "phpstan/phpstan": "^1.1",
"captainhook/captainhook": "^5.10", "captainhook/captainhook": "^5.10",

View File

@@ -135,6 +135,14 @@
"imagemagick" "imagemagick"
] ]
}, },
"glfw": {
"type": "external",
"arg-type": "custom",
"source": "ext-glfw",
"lib-depends": [
"glfw"
]
},
"imap": { "imap": {
"type": "builtin", "type": "builtin",
"arg-type": "with", "arg-type": "with",
@@ -298,7 +306,10 @@
"redis": { "redis": {
"type": "external", "type": "external",
"source": "redis", "source": "redis",
"arg-type": "custom" "arg-type": "custom",
"ext-suggests": [
"session"
]
}, },
"session": { "session": {
"type": "builtin" "type": "builtin"

View File

@@ -15,6 +15,18 @@
"brotli" "brotli"
] ]
}, },
"glfw": {
"source": "ext-glfw",
"static-libs-unix": [
"libglfw3.a"
],
"frameworks": [
"CoreVideo",
"OpenGL",
"Cocoa",
"IOKit"
]
},
"bzip2": { "bzip2": {
"source": "bzip2", "source": "bzip2",
"static-libs-unix": [ "static-libs-unix": [

View File

@@ -6,6 +6,15 @@
"path": "LICENSE" "path": "LICENSE"
} }
}, },
"ext-glfw": {
"type": "git",
"url": "https://github.com/mario-deluna/php-glfw",
"rev": "master",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"apcu": { "apcu": {
"type": "url", "type": "url",
"url": "https://pecl.php.net/get/APCu", "url": "https://pecl.php.net/get/APCu",
@@ -295,7 +304,7 @@
"type": "ghrel", "type": "ghrel",
"repo": "mongodb/mongo-php-driver", "repo": "mongodb/mongo-php-driver",
"path": "php-src/ext/mongodb", "path": "php-src/ext/mongodb",
"match": "mongodb.+\\.tgz", "match": "mongodb.+\\.zip",
"license": { "license": {
"type": "file", "type": "file",
"path": "LICENSE" "path": "LICENSE"
@@ -467,4 +476,4 @@
"path": "LICENSE" "path": "LICENSE"
} }
} }
} }

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace SPC; namespace SPC;
use SPC\command\DeployCommand;
use SPC\store\FileSystem; use SPC\store\FileSystem;
use Symfony\Component\Console\Application; use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\HelpCommand; use Symfony\Component\Console\Command\HelpCommand;
@@ -32,13 +31,19 @@ class ConsoleApplication extends Application
// 通过扫描目录 src/static-php-cli/command/ 添加子命令 // 通过扫描目录 src/static-php-cli/command/ 添加子命令
$commands = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/command', 'SPC\\command'); $commands = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/command', 'SPC\\command');
$this->addCommands(array_map(function ($x) { return new $x(); }, array_filter($commands, function ($y) { $phar = class_exists('\\Phar') && \Phar::running() || !class_exists('\\Phar');
if (is_a($y, DeployCommand::class, true) && (class_exists('\\Phar') && \Phar::running() || !class_exists('\\Phar'))) { $commands = array_filter($commands, function ($y) use ($phar) {
$archive_blacklist = [
'SPC\command\dev\SortConfigCommand',
'SPC\command\DeployCommand',
];
if ($phar && in_array($y, $archive_blacklist)) {
return false; return false;
} }
$reflection = new \ReflectionClass($y); $reflection = new \ReflectionClass($y);
return !$reflection->isAbstract() && !$reflection->isInterface(); return !$reflection->isAbstract() && !$reflection->isInterface();
}))); });
$this->addCommands(array_map(function ($x) { return new $x(); }, $commands));
} }
/** /**

View File

@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('glfw')]
class glfw extends Extension
{
public function patchBeforeBuildconf(): bool
{
FileSystem::copyDir(SOURCE_PATH . '/ext-glfw', SOURCE_PATH . '/php-src/ext/glfw');
return true;
}
public function getUnixConfigureArg(): string
{
return '--enable-glfw --with-glfw-dir=' . BUILD_ROOT_PATH;
}
}

View File

@@ -12,7 +12,12 @@ class redis extends Extension
{ {
public function getUnixConfigureArg(): string public function getUnixConfigureArg(): string
{ {
$arg = '--enable-redis --disable-redis-session'; $arg = '--enable-redis';
if (!$this->builder->getExt('session')) {
$arg .= ' --disable-redis-session';
} else {
$arg .= ' --enable-redis-session';
}
if ($this->builder->getLib('zstd')) { if ($this->builder->getLib('zstd')) {
$arg .= ' --enable-redis-zstd --with-libzstd="' . BUILD_ROOT_PATH . '"'; $arg .= ' --enable-redis-zstd --with-libzstd="' . BUILD_ROOT_PATH . '"';
} }

View File

@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class glfw extends MacOSLibraryBase
{
public const NAME = 'glfw';
protected function build()
{
// compile
shell()->cd(SOURCE_PATH . '/ext-glfw/vendor/glfw')
->exec("{$this->builder->configure_env} cmake . {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF -DGLFW_BUILD_EXAMPLES=OFF -DGLFW_BUILD_TESTS=OFF")
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
// patch pkgconf
$this->patchPkgconfPrefix(['glfw3.pc']);
}
}

View File

@@ -4,14 +4,15 @@ declare(strict_types=1);
namespace SPC\command; namespace SPC\command;
use CliHelper\Tools\ArgFixer; use SPC\store\FileSystem;
use CliHelper\Tools\DataProvider;
use CliHelper\Tools\SeekableArrayIterator;
use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption; 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')] #[AsCommand('deploy', 'Deploy static-php-cli self to an .phar application')]
class DeployCommand extends BaseCommand class DeployCommand extends BaseCommand
{ {
@@ -20,26 +21,51 @@ class DeployCommand extends BaseCommand
$this->addArgument('target', InputArgument::OPTIONAL, 'The file or directory to pack.'); $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('auto-phar-fix', null, InputOption::VALUE_NONE, 'Automatically fix ini option.');
$this->addOption('overwrite', 'W', InputOption::VALUE_NONE, 'Overwrite existing files.'); $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 public function handle(): int
{ {
// 第一阶段流程如果没有写path将会提示输入要打包的path $composer = require ROOT_DIR . '/vendor/composer/installed.php';
$prompt = new ArgFixer($this->input, $this->output); if (($composer['root']['dev'] ?? false) === true) {
if (!$this->getOption('with-no-dev')) {
$this->output->writeln('<comment>Current static-php-cli dependencies have installed dev-dependencies</comment>');
$this->output->writeln('<comment>If you want to remove, you can choose "Yes" to run command "composer update --no-dev" to remove.</comment>');
$this->output->writeln('<comment>Or choose "No", just pack, deploy.</comment>');
$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('<error>"composer update --no-dev" failed with exit code [' . $code . ']</error>');
$this->output->writeln('<error>You may need to run this command by your own.</error>');
return static::FAILURE;
}
$this->output->writeln('<info>Update successfully, you need to re-run deploy command to pack.</info>');
return static::SUCCESS;
}
}
// 首先得确认是不是关闭了readonly模式 // 首先得确认是不是关闭了readonly模式
if (ini_get('phar.readonly') == 1) { if (ini_get('phar.readonly') == 1) {
if ($this->getOption('auto-phar-fix')) { if ($this->getOption('auto-phar-fix')) {
$ask = true; $ask = true;
} else { } else {
$ask = $prompt->requireBool('<comment>pack command needs "phar.readonly" = "Off" !</comment>' . PHP_EOL . 'If you want to automatically set it and continue, just Enter', true); $this->output->writeln('<comment>pack command needs "phar.readonly" = "Off" !</comment>');
$ask = confirm('Do you want to automatically set it and continue ?');
// $ask = $prompt->requireBool('<comment>pack command needs "phar.readonly" = "Off" !</comment>' . PHP_EOL . 'If you want to automatically set it and continue, just Enter', true);
} }
if ($ask) { if ($ask) {
global $argv; 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')) { if (function_exists('pcntl_exec')) {
$this->output->writeln('<info>Changing to phar.readonly=0 mode ...</info>'); $this->output->writeln('<info>Changing to phar.readonly=0 mode ...</info>');
if (pcntl_exec(PHP_BINARY, $args) === false) { if (pcntl_exec(PHP_BINARY, $args) === false) {
throw new \PharException('切换到读写模式失败,请检查环境。'); throw new \PharException('Switching to read write mode failed, please check the environment.');
} }
} else { } else {
$this->output->writeln('<info>Now running command in child process.</info>'); $this->output->writeln('<info>Now running command in child process.</info>');
@@ -51,13 +77,19 @@ class DeployCommand extends BaseCommand
// 获取路径 // 获取路径
$path = WORKING_DIR; $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)) { if (FileSystem::isRelativePath($phar_path)) {
$phar_path = '/tmp/' . $phar_path; $phar_path = WORKING_DIR . '/' . $phar_path;
} }
if (file_exists($phar_path)) { if (file_exists($phar_path)) {
$ask = $this->getOption('overwrite') ? true : $prompt->requireBool('<comment>The file "' . $phar_path . '" already exists, do you want to overwrite it?</comment>' . PHP_EOL . 'If you want to, just Enter'); if (!$this->getOption('overwrite')) {
$this->output->writeln('<comment>The file "' . $phar_path . '" already exists.</comment>');
$ask = confirm('Do you want to overwrite it?');
} else {
$ask = true;
}
if (!$ask) { if (!$ask) {
$this->output->writeln('<comment>User canceled.</comment>'); $this->output->writeln('<comment>User canceled.</comment>');
return static::FAILURE; return static::FAILURE;
@@ -67,7 +99,7 @@ class DeployCommand extends BaseCommand
$phar = new \Phar($phar_path); $phar = new \Phar($phar_path);
$phar->startBuffering(); $phar->startBuffering();
$all = DataProvider::scanDirFiles($path, true, true); $all = FileSystem::scanDirFiles($path, true, true);
$all = array_filter($all, function ($x) { $all = array_filter($all, function ($x) {
$dirs = preg_match('/(^(config|src|vendor)\\/|^(composer\\.json|README\\.md|source\\.json|LICENSE|README-en\\.md)$)/', $x); $dirs = preg_match('/(^(config|src|vendor)\\/|^(composer\\.json|README\\.md|source\\.json|LICENSE|README-en\\.md)$)/', $x);

View File

@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\command;
use SPC\exception\FileSystemException;
use SPC\store\Config;
use Symfony\Component\Console\Attribute\AsCommand;
#[AsCommand('list-ext', 'List supported extensions')]
class ListExtCommand extends BaseCommand
{
protected bool $no_motd = true;
/**
* @throws FileSystemException
*/
public function handle(): int
{
foreach (Config::getExts() as $ext => $meta) {
echo $ext . PHP_EOL;
}
return static::SUCCESS;
}
}

View File

@@ -8,16 +8,17 @@ use SPC\command\BaseCommand;
use SPC\store\Config; use SPC\store\Config;
use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Attribute\AsCommand;
#[AsCommand('dev:ext-all', 'Dev command')] #[AsCommand('dev:ext-all', 'Dev command', ['list-ext'])]
class AllExtCommand extends BaseCommand class AllExtCommand extends BaseCommand
{ {
public function configure() public function configure()
{ {
$this->addOption('line', 'l', null, 'Show with separate lines');
} }
public function handle(): int public function handle(): int
{ {
$this->output->writeln(implode(',', array_keys(Config::getExts()))); $this->output->writeln(implode($this->input->getOption('line') ? PHP_EOL : ',', array_keys(Config::getExts())));
return static::SUCCESS; return static::SUCCESS;
} }
} }

View File

@@ -2,8 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace SPC\command; namespace SPC\command\dev;
use SPC\command\BaseCommand;
use SPC\exception\FileSystemException; use SPC\exception\FileSystemException;
use SPC\exception\ValidationException; use SPC\exception\ValidationException;
use SPC\store\FileSystem; use SPC\store\FileSystem;
@@ -12,9 +13,9 @@ use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
/** /**
* 修改 config 后对其 kv 进行排序的操作 * Modify config file: sort lib, ext, source by name.
*/ */
#[AsCommand('sort-config', 'After config edited, sort it by alphabet')] #[AsCommand('dev:sort-config', 'After config edited, sort it by alphabet', ['sort-config'])]
class SortConfigCommand extends BaseCommand class SortConfigCommand extends BaseCommand
{ {
public function configure() public function configure()
@@ -33,19 +34,28 @@ class SortConfigCommand extends BaseCommand
$file = json_decode(FileSystem::readFile(ROOT_DIR . '/config/lib.json'), true); $file = json_decode(FileSystem::readFile(ROOT_DIR . '/config/lib.json'), true);
ConfigValidator::validateLibs($file); ConfigValidator::validateLibs($file);
ksort($file); ksort($file);
file_put_contents(ROOT_DIR . '/config/lib.json', json_encode($file, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); if (!file_put_contents(ROOT_DIR . '/config/lib.json', json_encode($file, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE))) {
$this->output->writeln('<error>Write file lib.json failed!</error>');
return static::FAILURE;
}
break; break;
case 'source': case 'source':
$file = json_decode(FileSystem::readFile(ROOT_DIR . '/config/source.json'), true); $file = json_decode(FileSystem::readFile(ROOT_DIR . '/config/source.json'), true);
ConfigValidator::validateSource($file); ConfigValidator::validateSource($file);
uksort($file, fn ($a, $b) => $a === 'php-src' ? -1 : ($b === 'php-src' ? 1 : ($a < $b ? -1 : 1))); uksort($file, fn ($a, $b) => $a === 'php-src' ? -1 : ($b === 'php-src' ? 1 : ($a < $b ? -1 : 1)));
file_put_contents(ROOT_DIR . '/config/source.json', json_encode($file, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); if (!file_put_contents(ROOT_DIR . '/config/source.json', json_encode($file, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE))) {
$this->output->writeln('<error>Write file source.json failed!</error>');
return static::FAILURE;
}
break; break;
case 'ext': case 'ext':
$file = json_decode(FileSystem::readFile(ROOT_DIR . '/config/ext.json'), true); $file = json_decode(FileSystem::readFile(ROOT_DIR . '/config/ext.json'), true);
ConfigValidator::validateExts($file); ConfigValidator::validateExts($file);
ksort($file); ksort($file);
file_put_contents(ROOT_DIR . '/config/ext.json', json_encode($file, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); if (!file_put_contents(ROOT_DIR . '/config/ext.json', json_encode($file, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE))) {
$this->output->writeln('<error>Write file ext.json failed!</error>');
return static::FAILURE;
}
break; break;
default: default:
$this->output->writeln("<error>invalid config name: {$name}</error>"); $this->output->writeln("<error>invalid config name: {$name}</error>");

View File

@@ -47,7 +47,8 @@ class ExceptionHandler
logger()->error($e->getTraceAsString()); logger()->error($e->getTraceAsString());
return; return;
} }
$this->whoops->handleException($e); $this->whoops->handleException($e);
logger()->critical('You can report this exception to static-php-cli GitHub repo.');
} }
} }

View File

@@ -320,28 +320,7 @@ class FileSystem
foreach ($files as $v) { foreach ($files as $v) {
$pathinfo = pathinfo($v); $pathinfo = pathinfo($v);
if (($pathinfo['extension'] ?? '') == 'php') { if (($pathinfo['extension'] ?? '') == 'php') {
$path = rtrim($dir, '/') . '/' . rtrim($pathinfo['dirname'], './') . '/' . $pathinfo['basename']; if ($rule === null) {
// 过滤不包含类的文件
$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 (file_exists($dir . '/' . $pathinfo['basename'] . '.ignore')) { if (file_exists($dir . '/' . $pathinfo['basename'] . '.ignore')) {
continue; continue;
} }