mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-17 20:34:51 +08:00
Add dependency map generator and related docs
This commit is contained in:
parent
077da6f6a4
commit
73654e5984
2
.github/workflows/vitepress-deploy.yml
vendored
2
.github/workflows/vitepress-deploy.yml
vendored
@ -58,6 +58,8 @@ jobs:
|
|||||||
- name: "Generate Extension Support List"
|
- name: "Generate Extension Support List"
|
||||||
run: |
|
run: |
|
||||||
bin/spc dev:gen-ext-docs > docs/extensions.md
|
bin/spc dev:gen-ext-docs > docs/extensions.md
|
||||||
|
bin/spc dev:gen-ext-dep-docs > docs/deps-map-ext.md
|
||||||
|
bin/spc dev:gen-lib-dep-docs > docs/deps-map-lib.md
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: yarn docs:build
|
run: yarn docs:build
|
||||||
|
|||||||
@ -10,6 +10,7 @@ export default {
|
|||||||
{text: 'Extension Notes', link: '/en/guide/extension-notes'},
|
{text: 'Extension Notes', link: '/en/guide/extension-notes'},
|
||||||
{text: 'Command Generator', link: '/en/guide/cli-generator'},
|
{text: 'Command Generator', link: '/en/guide/cli-generator'},
|
||||||
{text: 'Environment Variables', link: '/en/guide/env-vars', collapsed: true,},
|
{text: 'Environment Variables', link: '/en/guide/env-vars', collapsed: true,},
|
||||||
|
{text: 'Dependency Table', link: '/en/guide/deps-map'},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,6 +10,7 @@ export default {
|
|||||||
{text: '扩展注意事项', link: '/zh/guide/extension-notes'},
|
{text: '扩展注意事项', link: '/zh/guide/extension-notes'},
|
||||||
{text: '编译命令生成器', link: '/zh/guide/cli-generator'},
|
{text: '编译命令生成器', link: '/zh/guide/cli-generator'},
|
||||||
{text: '环境变量列表', link: '/zh/guide/env-vars'},
|
{text: '环境变量列表', link: '/zh/guide/env-vars'},
|
||||||
|
{text: '依赖关系图表', link: '/zh/guide/deps-map'},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
0
docs/deps-map-ext.md
Normal file
0
docs/deps-map-ext.md
Normal file
0
docs/deps-map-lib.md
Normal file
0
docs/deps-map-lib.md
Normal file
26
docs/en/guide/deps-map.md
Normal file
26
docs/en/guide/deps-map.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
outline: 'deep'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Dependency Table
|
||||||
|
|
||||||
|
When compiling PHP, each extension and library has dependencies, which may be required or optional.
|
||||||
|
You can choose whether to include these optional dependencies.
|
||||||
|
|
||||||
|
For example, when compiling the `gd` extension under Linux,
|
||||||
|
the `zlib,libpng` libraries and the `zlib` extension are forced to be compiled,
|
||||||
|
while the `libavif,libwebp,libjpeg,freetype` libraries are optional libraries and will not be compiled by default
|
||||||
|
unless specified by the `--with-libs=avif,webp,jpeg,freetype` option.
|
||||||
|
|
||||||
|
- For optional extensions (optional features of extensions), you need to specify them manually at compile time, for example, to enable igbinary support for Redis: `bin/spc build redis,igbinary`.
|
||||||
|
- For optional libraries, you need to compile and specify them through the `--with-libs=XXX` option.
|
||||||
|
- If you want to enable all optional extensions, you can use `bin/spc build redis --with-suggested-exts`.
|
||||||
|
- If you want to enable all optional libraries, you can use `--with-suggested-libs`.
|
||||||
|
|
||||||
|
## Extension Dependency Table
|
||||||
|
|
||||||
|
<!--@include: ../../deps-map-ext.md-->
|
||||||
|
|
||||||
|
## Library Dependency Table
|
||||||
|
|
||||||
|
<!--@include: ../../deps-map-lib.md-->
|
||||||
@ -14,14 +14,6 @@ Some extensions or libraries that the extension depends on will have some option
|
|||||||
For example, the gd library optionally supports libwebp, freetype, etc.
|
For example, the gd library optionally supports libwebp, freetype, etc.
|
||||||
If you only use `bin/spc build gd --build-cli` they will not be included (static-php-cli defaults to the minimum dependency principle).
|
If you only use `bin/spc build gd --build-cli` they will not be included (static-php-cli defaults to the minimum dependency principle).
|
||||||
|
|
||||||
You can use `--with-libs=` to add these libraries when compiling.
|
For more information about optional libraries, see [Extensions, Library Dependency Map](./deps-map).
|
||||||
When the dependent libraries of this compilation include them, gd will automatically use them to enable these features.
|
For optional libraries, you can also select an extension from the [Command Generator](./cli-generator) and then select optional libraries.
|
||||||
(For example: `bin/spc build gd --with-libs=libwebp,freetype --build-cli`)
|
|
||||||
|
|
||||||
Alternatively you can use `--with-suggested-exts` and `--with-suggested-libs` to enable all optional dependencies of these extensions and libraries.
|
|
||||||
(For example: `bin/spc build gd --with-suggested-libs --build-cli`)
|
|
||||||
|
|
||||||
If you don't know whether an extension has optional features,
|
|
||||||
you can check the [spc configuration file](https://github.com/crazywhalecc/static-php-cli/tree/main/config)
|
|
||||||
or use the command `bin/spc dev:extensions` (library dependency is `lib-suggests`, extension dependency is `ext-suggests`).
|
|
||||||
:::
|
:::
|
||||||
|
|||||||
22
docs/zh/guide/deps-map.md
Normal file
22
docs/zh/guide/deps-map.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
outline: 'deep'
|
||||||
|
---
|
||||||
|
|
||||||
|
# 依赖关系图表
|
||||||
|
|
||||||
|
在编译 PHP 时,每个扩展、库都有依赖关系,这些依赖关系可能是必需的,也可能是可选的。在编译 PHP 时,可以选择是否包含这些可选的依赖关系。
|
||||||
|
|
||||||
|
例如,在 Linux 下编译 `gd` 扩展时,会强制编译 `zlib,libpng` 库和 `zlib` 扩展,而 `libavif,libwebp,libjpeg,freetype` 库都是可选的库,默认不会编译,除非通过 `--with-libs=avif,webp,jpeg,freetype` 选项指定。
|
||||||
|
|
||||||
|
- 对于可选扩展(扩展的可选特性),需手动在编译时指定,例如启用 Redis 的 igbinary 支持:`bin/spc build redis,igbinary`。
|
||||||
|
- 对于可选库,需通过 `--with-libs=XXX` 选项编译指定。
|
||||||
|
- 如果想启用所有的可选扩展,可以使用 `bin/spc build redis --with-suggested-exts` 参数。
|
||||||
|
- 如果想启用所有的可选库,可以使用 `--with-suggested-libs` 参数。
|
||||||
|
|
||||||
|
## 扩展的依赖图
|
||||||
|
|
||||||
|
<!--@include: ../../deps-map-ext.md-->
|
||||||
|
|
||||||
|
## 库的依赖表
|
||||||
|
|
||||||
|
<!--@include: ../../deps-map-lib.md-->
|
||||||
@ -132,7 +132,7 @@ event 扩展在 macOS 系统下编译后暂无法使用 `openpty` 特性。相
|
|||||||
|
|
||||||
parallel 扩展只支持 PHP 8.0 及以上版本,并只支持 ZTS 构建(`--enable-zts`)。
|
parallel 扩展只支持 PHP 8.0 及以上版本,并只支持 ZTS 构建(`--enable-zts`)。
|
||||||
|
|
||||||
# spx
|
## spx
|
||||||
|
|
||||||
1. [SPX 扩展](https://github.com/NoiseByNorthwest/php-spx) 只支持非线程模式。
|
1. [SPX 扩展](https://github.com/NoiseByNorthwest/php-spx) 只支持非线程模式。
|
||||||
2. SPX 目前不支持 Windows,且官方仓库也不支持静态编译,static-php-cli 使用了 [修改版本](https://github.com/static-php/php-spx)。
|
2. SPX 目前不支持 Windows,且官方仓库也不支持静态编译,static-php-cli 使用了 [修改版本](https://github.com/static-php/php-spx)。
|
||||||
|
|||||||
@ -13,12 +13,5 @@
|
|||||||
有些扩展或扩展依赖的库会有一些可选的特性,例如 gd 库可选支持 libwebp、freetype 等。
|
有些扩展或扩展依赖的库会有一些可选的特性,例如 gd 库可选支持 libwebp、freetype 等。
|
||||||
如果你只使用 `bin/spc build gd --build-cli` 是不会包含它们(static-php-cli 默认为最小依赖原则)。
|
如果你只使用 `bin/spc build gd --build-cli` 是不会包含它们(static-php-cli 默认为最小依赖原则)。
|
||||||
|
|
||||||
你可以在编译时使用 `--with-libs=` 加入这些库,当本次编译的依赖库中包含它们,gd 会自动依赖它们启用这些特性。
|
有关编译可选库,请参考 [扩展、库的依赖关系图表](./deps-map)。对于可选的库,你也可以从 [编译命令生成器](./cli-generator) 中选择扩展后展开选择可选库。
|
||||||
(如:`bin/spc build gd --with-libs=libwebp,freetype --build-cli`)
|
|
||||||
|
|
||||||
或者你也可以使用 `--with-suggested-exts` 和 `--with-suggested-libs` 启用这些扩展和库所有可选的依赖。
|
|
||||||
(如:`bin/spc build gd --with-suggested-libs --build-cli`)
|
|
||||||
|
|
||||||
如果你不知道某个扩展是否有可选特性,可以通过查看 [spc 配置文件](https://github.com/crazywhalecc/static-php-cli/tree/main/config)
|
|
||||||
或使用命令 `bin/spc dev:extensions` 查看(库依赖为 `lib-suggests`,扩展依赖为 `ext-suggests`)。
|
|
||||||
:::
|
:::
|
||||||
|
|||||||
@ -9,7 +9,9 @@ use SPC\command\BuildLibsCommand;
|
|||||||
use SPC\command\DeleteDownloadCommand;
|
use SPC\command\DeleteDownloadCommand;
|
||||||
use SPC\command\dev\AllExtCommand;
|
use SPC\command\dev\AllExtCommand;
|
||||||
use SPC\command\dev\ExtVerCommand;
|
use SPC\command\dev\ExtVerCommand;
|
||||||
|
use SPC\command\dev\GenerateExtDepDocsCommand;
|
||||||
use SPC\command\dev\GenerateExtDocCommand;
|
use SPC\command\dev\GenerateExtDocCommand;
|
||||||
|
use SPC\command\dev\GenerateLibDepDocsCommand;
|
||||||
use SPC\command\dev\LibVerCommand;
|
use SPC\command\dev\LibVerCommand;
|
||||||
use SPC\command\dev\PackLibCommand;
|
use SPC\command\dev\PackLibCommand;
|
||||||
use SPC\command\dev\PhpVerCommand;
|
use SPC\command\dev\PhpVerCommand;
|
||||||
@ -55,6 +57,8 @@ final class ConsoleApplication extends Application
|
|||||||
new ExtVerCommand(),
|
new ExtVerCommand(),
|
||||||
new SortConfigCommand(),
|
new SortConfigCommand(),
|
||||||
new GenerateExtDocCommand(),
|
new GenerateExtDocCommand(),
|
||||||
|
new GenerateExtDepDocsCommand(),
|
||||||
|
new GenerateLibDepDocsCommand(),
|
||||||
new PackLibCommand(),
|
new PackLibCommand(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|||||||
166
src/SPC/command/dev/GenerateExtDepDocsCommand.php
Normal file
166
src/SPC/command/dev/GenerateExtDepDocsCommand.php
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\command\dev;
|
||||||
|
|
||||||
|
use SPC\command\BaseCommand;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\util\ConfigValidator;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
|
||||||
|
#[AsCommand('dev:gen-ext-dep-docs', 'Generate ext dependency map markdown', [], true)]
|
||||||
|
class GenerateExtDepDocsCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
protected bool $no_motd = true;
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
// Get ext.json
|
||||||
|
$exts = json_decode(FileSystem::readFile(ROOT_DIR . '/config/ext.json'), true);
|
||||||
|
ConfigValidator::validateExts($exts);
|
||||||
|
|
||||||
|
// Markdown table needs format, we need to calculate the max length of each column
|
||||||
|
$content = '';
|
||||||
|
|
||||||
|
// Calculate table column max length
|
||||||
|
$max_linux = [0, 20, 19, 20, 19];
|
||||||
|
$max_macos = [0, 20, 19, 20, 19];
|
||||||
|
$max_windows = [0, 20, 19, 20, 19];
|
||||||
|
$max_freebsd = [0, 20, 19, 20, 19];
|
||||||
|
|
||||||
|
$md_lines_linux = [];
|
||||||
|
$md_lines_macos = [];
|
||||||
|
$md_lines_windows = [];
|
||||||
|
$md_lines_freebsd = [];
|
||||||
|
|
||||||
|
foreach ($exts as $ext_name => $ext) {
|
||||||
|
$line_linux = [
|
||||||
|
"<b>{$ext_name}</b>",
|
||||||
|
implode('<br>', $ext['ext-depends-linux'] ?? $ext['ext-depends-unix'] ?? $ext['ext-depends'] ?? []),
|
||||||
|
implode('<br>', $ext['ext-suggests-linux'] ?? $ext['ext-suggests-unix'] ?? $ext['ext-suggests'] ?? []),
|
||||||
|
implode('<br>', $ext['lib-depends-linux'] ?? $ext['lib-depends-unix'] ?? $ext['lib-depends'] ?? []),
|
||||||
|
implode('<br>', $ext['lib-suggests-linux'] ?? $ext['lib-suggests-unix'] ?? $ext['lib-suggests'] ?? []),
|
||||||
|
];
|
||||||
|
$this->applyMaxLen($max_linux, $line_linux);
|
||||||
|
if ($this->isSupported($ext, 'Linux') && !$this->isEmptyLine($line_linux)) {
|
||||||
|
$md_lines_linux[] = $line_linux;
|
||||||
|
}
|
||||||
|
$line_macos = [
|
||||||
|
"<b>{$ext_name}</b>",
|
||||||
|
implode('<br>', $ext['ext-depends-macos'] ?? $ext['ext-depends-unix'] ?? $ext['ext-depends'] ?? []),
|
||||||
|
implode('<br>', $ext['ext-suggests-macos'] ?? $ext['ext-suggests-unix'] ?? $ext['ext-suggests'] ?? []),
|
||||||
|
implode('<br>', $ext['lib-depends-macos'] ?? $ext['lib-depends-unix'] ?? $ext['lib-depends'] ?? []),
|
||||||
|
implode('<br>', $ext['lib-suggests-macos'] ?? $ext['lib-suggests-unix'] ?? $ext['lib-suggests'] ?? []),
|
||||||
|
];
|
||||||
|
$this->applyMaxLen($max_macos, $line_macos);
|
||||||
|
if ($this->isSupported($ext, 'macOS') && !$this->isEmptyLine($line_macos)) {
|
||||||
|
$md_lines_macos[] = $line_macos;
|
||||||
|
}
|
||||||
|
$line_windows = [
|
||||||
|
"<b>{$ext_name}</b>",
|
||||||
|
implode('<br>', $ext['ext-depends-windows'] ?? $ext['ext-depends-win'] ?? $ext['ext-depends'] ?? []),
|
||||||
|
implode('<br>', $ext['ext-suggests-windows'] ?? $ext['ext-suggests-win'] ?? $ext['ext-suggests'] ?? []),
|
||||||
|
implode('<br>', $ext['lib-depends-windows'] ?? $ext['lib-depends-win'] ?? $ext['lib-depends'] ?? []),
|
||||||
|
implode('<br>', $ext['lib-suggests-windows'] ?? $ext['lib-suggests-win'] ?? $ext['lib-suggests'] ?? []),
|
||||||
|
];
|
||||||
|
$this->applyMaxLen($max_windows, $line_windows);
|
||||||
|
if ($this->isSupported($ext, 'Windows') && !$this->isEmptyLine($line_windows)) {
|
||||||
|
$md_lines_windows[] = $line_windows;
|
||||||
|
}
|
||||||
|
$line_freebsd = [
|
||||||
|
"<b>{$ext_name}</b>",
|
||||||
|
implode('<br>', $ext['ext-depends-freebsd'] ?? $ext['ext-depends-bsd'] ?? $ext['ext-depends-unix'] ?? $ext['ext-depends'] ?? []),
|
||||||
|
implode('<br>', $ext['ext-suggests-freebsd'] ?? $ext['ext-suggests-bsd'] ?? $ext['ext-suggests-unix'] ?? $ext['ext-suggests'] ?? []),
|
||||||
|
implode('<br>', $ext['lib-depends-freebsd'] ?? $ext['lib-depends-bsd'] ?? $ext['lib-depends-unix'] ?? $ext['lib-depends'] ?? []),
|
||||||
|
implode('<br>', $ext['lib-suggests-freebsd'] ?? $ext['lib-suggests-bsd'] ?? $ext['lib-suggests-unix'] ?? $ext['lib-suggests'] ?? []),
|
||||||
|
];
|
||||||
|
$this->applyMaxLen($max_freebsd, $line_freebsd);
|
||||||
|
if ($this->isSupported($ext, 'BSD') && !$this->isEmptyLine($line_freebsd)) {
|
||||||
|
$md_lines_freebsd[] = $line_freebsd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate markdown
|
||||||
|
if (!empty($md_lines_linux)) {
|
||||||
|
$content .= "### Linux\n\n";
|
||||||
|
$content .= '| ';
|
||||||
|
$pads = ['Extension Name', 'Required Extensions', 'Suggested Extensions', 'Required Libraries', 'Suggested Libraries'];
|
||||||
|
// 生成首行
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_linux[$i]), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
// 生成第二行表格分割符 | --- | --- | --- | --- | --- |
|
||||||
|
$content .= '| ';
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_linux[$i], '-'), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
foreach ($md_lines_linux as $line) {
|
||||||
|
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_linux[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($md_lines_macos)) {
|
||||||
|
$content .= "\n\n### macOS\n\n";
|
||||||
|
$content .= '| ';
|
||||||
|
$pads = ['Extension Name', 'Required Extensions', 'Suggested Extensions', 'Required Libraries', 'Suggested Libraries'];
|
||||||
|
// 生成首行
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_macos[$i]), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
// 生成第二行表格分割符 | --- | --- | --- | --- | --- |
|
||||||
|
$content .= '| ';
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_macos[$i], '-'), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
foreach ($md_lines_macos as $line) {
|
||||||
|
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_macos[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($md_lines_windows)) {
|
||||||
|
$content .= "\n\n### Windows\n\n";
|
||||||
|
$content .= '| ';
|
||||||
|
$pads = ['Extension Name', 'Required Extensions', 'Suggested Extensions', 'Required Libraries', 'Suggested Libraries'];
|
||||||
|
// 生成首行
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_windows[$i]), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
// 生成第二行表格分割符 | --- | --- | --- | --- | --- |
|
||||||
|
$content .= '| ';
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_windows[$i], '-'), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
foreach ($md_lines_windows as $line) {
|
||||||
|
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_windows[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($md_lines_freebsd)) {
|
||||||
|
$content .= "\n\n### FreeBSD\n\n";
|
||||||
|
$content .= '| ';
|
||||||
|
$pads = ['Extension Name', 'Required Extensions', 'Suggested Extensions', 'Required Libraries', 'Suggested Libraries'];
|
||||||
|
// 生成首行
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_freebsd[$i]), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
// 生成第二行表格分割符 | --- | --- | --- | --- | --- |
|
||||||
|
$content .= '| ';
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_freebsd[$i], '-'), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
foreach ($md_lines_freebsd as $line) {
|
||||||
|
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_freebsd[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->output->writeln($content);
|
||||||
|
return static::SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function applyMaxLen(array &$max, array $lines): void
|
||||||
|
{
|
||||||
|
foreach ($max as $k => $v) {
|
||||||
|
$max[$k] = max($v, strlen($lines[$k]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isSupported(array $ext, string $os): bool
|
||||||
|
{
|
||||||
|
return !in_array($ext['support'][$os] ?? 'yes', ['no', 'wip']);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isEmptyLine(array $line): bool
|
||||||
|
{
|
||||||
|
return $line[1] === '' && $line[2] === '' && $line[3] === '' && $line[4] === '';
|
||||||
|
}
|
||||||
|
}
|
||||||
172
src/SPC/command/dev/GenerateLibDepDocsCommand.php
Normal file
172
src/SPC/command/dev/GenerateLibDepDocsCommand.php
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\command\dev;
|
||||||
|
|
||||||
|
use SPC\command\BaseCommand;
|
||||||
|
use SPC\store\Config;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\util\ConfigValidator;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
|
||||||
|
#[AsCommand('dev:gen-lib-dep-docs', 'Generate lib dependency map markdown', [], true)]
|
||||||
|
class GenerateLibDepDocsCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
protected bool $no_motd = true;
|
||||||
|
|
||||||
|
protected array $support_lib_list = [];
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
foreach (['linux', 'macos', 'windows', 'freebsd'] as $os) {
|
||||||
|
$this->support_lib_list[$os] = [];
|
||||||
|
$classes = FileSystem::getClassesPsr4(
|
||||||
|
FileSystem::convertPath(ROOT_DIR . '/src/SPC/builder/' . $os . '/library'),
|
||||||
|
'SPC\builder\\' . $os . '\library'
|
||||||
|
);
|
||||||
|
foreach ($classes as $class) {
|
||||||
|
if (defined($class . '::NAME') && $class::NAME !== 'unknown' && Config::getLib($class::NAME) !== null) {
|
||||||
|
$this->support_lib_list[$os][$class::NAME] = $class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get lib.json
|
||||||
|
$libs = json_decode(FileSystem::readFile(ROOT_DIR . '/config/lib.json'), true);
|
||||||
|
ConfigValidator::validateLibs($libs);
|
||||||
|
|
||||||
|
// Markdown table needs format, we need to calculate the max length of each column
|
||||||
|
$content = '';
|
||||||
|
|
||||||
|
// Calculate table column max length
|
||||||
|
$max_linux = [0, 20, 19];
|
||||||
|
$max_macos = [0, 20, 19];
|
||||||
|
$max_windows = [0, 20, 19];
|
||||||
|
$max_freebsd = [0, 20, 19];
|
||||||
|
|
||||||
|
$md_lines_linux = [];
|
||||||
|
$md_lines_macos = [];
|
||||||
|
$md_lines_windows = [];
|
||||||
|
$md_lines_freebsd = [];
|
||||||
|
|
||||||
|
foreach ($libs as $lib_name => $lib) {
|
||||||
|
$line_linux = [
|
||||||
|
"<b>{$lib_name}</b>",
|
||||||
|
implode('<br>', $lib['lib-depends-linux'] ?? $lib['lib-depends-unix'] ?? $lib['lib-depends'] ?? []),
|
||||||
|
implode('<br>', $lib['lib-suggests-linux'] ?? $lib['lib-suggests-unix'] ?? $lib['lib-suggests'] ?? []),
|
||||||
|
];
|
||||||
|
$this->applyMaxLen($max_linux, $line_linux);
|
||||||
|
if ($this->isSupported($lib_name, 'linux') && !$this->isEmptyLine($line_linux)) {
|
||||||
|
$md_lines_linux[] = $line_linux;
|
||||||
|
}
|
||||||
|
$line_macos = [
|
||||||
|
"<b>{$lib_name}</b>",
|
||||||
|
implode('<br>', $lib['lib-depends-macos'] ?? $lib['lib-depends-unix'] ?? $lib['lib-depends'] ?? []),
|
||||||
|
implode('<br>', $lib['lib-suggests-macos'] ?? $lib['lib-suggests-unix'] ?? $lib['lib-suggests'] ?? []),
|
||||||
|
];
|
||||||
|
$this->applyMaxLen($max_macos, $line_macos);
|
||||||
|
if ($this->isSupported($lib_name, 'macos') && !$this->isEmptyLine($line_macos)) {
|
||||||
|
$md_lines_macos[] = $line_macos;
|
||||||
|
}
|
||||||
|
$line_windows = [
|
||||||
|
"<b>{$lib_name}</b>",
|
||||||
|
implode('<br>', $lib['lib-depends-windows'] ?? $lib['lib-depends-win'] ?? $lib['lib-depends'] ?? []),
|
||||||
|
implode('<br>', $lib['lib-suggests-windows'] ?? $lib['lib-suggests-win'] ?? $lib['lib-suggests'] ?? []),
|
||||||
|
];
|
||||||
|
$this->applyMaxLen($max_windows, $line_windows);
|
||||||
|
if ($this->isSupported($lib_name, 'windows') && !$this->isEmptyLine($line_windows)) {
|
||||||
|
$md_lines_windows[] = $line_windows;
|
||||||
|
}
|
||||||
|
$line_freebsd = [
|
||||||
|
"<b>{$lib_name}</b>",
|
||||||
|
implode('<br>', $lib['lib-depends-freebsd'] ?? $lib['lib-depends-bsd'] ?? $lib['lib-depends-unix'] ?? $lib['lib-depends'] ?? []),
|
||||||
|
implode('<br>', $lib['lib-suggests-freebsd'] ?? $lib['lib-suggests-bsd'] ?? $lib['lib-suggests-unix'] ?? $lib['lib-suggests'] ?? []),
|
||||||
|
];
|
||||||
|
$this->applyMaxLen($max_freebsd, $line_freebsd);
|
||||||
|
if ($this->isSupported($lib_name, 'freebsd') && !$this->isEmptyLine($line_freebsd)) {
|
||||||
|
$md_lines_freebsd[] = $line_freebsd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate markdown
|
||||||
|
if (!empty($md_lines_linux)) {
|
||||||
|
$content .= "### Linux\n\n";
|
||||||
|
$content .= '| ';
|
||||||
|
$pads = ['Library Name', 'Required Libraries', 'Suggested Libraries'];
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_linux[$i]), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
$content .= '| ';
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_linux[$i], '-'), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
foreach ($md_lines_linux as $line) {
|
||||||
|
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_linux[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($md_lines_macos)) {
|
||||||
|
$content .= "### macOS\n\n";
|
||||||
|
$content .= '| ';
|
||||||
|
$pads = ['Library Name', 'Required Libraries', 'Suggested Libraries'];
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_macos[$i]), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
$content .= '| ';
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_macos[$i], '-'), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
foreach ($md_lines_macos as $line) {
|
||||||
|
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_macos[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($md_lines_windows)) {
|
||||||
|
$content .= "### Windows\n\n";
|
||||||
|
$content .= '| ';
|
||||||
|
$pads = ['Library Name', 'Required Libraries', 'Suggested Libraries'];
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_windows[$i]), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
$content .= '| ';
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_windows[$i], '-'), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
foreach ($md_lines_windows as $line) {
|
||||||
|
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_windows[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($md_lines_freebsd)) {
|
||||||
|
$content .= "### FreeBSD\n\n";
|
||||||
|
$content .= '| ';
|
||||||
|
$pads = ['Library Name', 'Required Libraries', 'Suggested Libraries'];
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_freebsd[$i]), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
$content .= '| ';
|
||||||
|
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_freebsd[$i], '-'), array_keys($pads), $pads));
|
||||||
|
$content .= ' |' . PHP_EOL;
|
||||||
|
foreach ($md_lines_freebsd as $line) {
|
||||||
|
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_freebsd[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->output->writeln($content);
|
||||||
|
return static::SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function applyMaxLen(array &$max, array $lines): void
|
||||||
|
{
|
||||||
|
foreach ($max as $k => $v) {
|
||||||
|
$max[$k] = max($v, strlen($lines[$k]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isSupported(string $ext_name, string $os): bool
|
||||||
|
{
|
||||||
|
if (!in_array($os, ['linux', 'macos', 'freebsd', 'windows'])) {
|
||||||
|
throw new \InvalidArgumentException('Invalid os: ' . $os);
|
||||||
|
}
|
||||||
|
return isset($this->support_lib_list[$os][$ext_name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isEmptyLine(array $line): bool
|
||||||
|
{
|
||||||
|
return $line[1] === '' && $line[2] === '';
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user