mirror of
https://github.com/kmvan/x-prober.git
synced 2026-04-22 01:08:59 +08:00
273 lines
6.7 KiB
PHP
273 lines
6.7 KiB
PHP
<?php
|
|
|
|
namespace InnStudio\Prober\Compiler;
|
|
|
|
class Compiler
|
|
{
|
|
private $ROOT = '';
|
|
private $BASE_DIR = '';
|
|
private $COMPILE_FILE_PATH = '';
|
|
private $COMPONENTS_DIR = '';
|
|
|
|
public function __construct(string $dir)
|
|
{
|
|
$this->ROOT = $dir;
|
|
$this->BASE_DIR = "{$dir}/src";
|
|
$this->COMPONENTS_DIR = "{$this->BASE_DIR}/Components";
|
|
$this->COMPILE_FILE_PATH = "{$dir}/dist/prober.php";
|
|
|
|
// generate config
|
|
new ConfigGeneration([
|
|
'phpConfigPath' => "{$this->COMPONENTS_DIR}/Config/ConfigApi.php",
|
|
'configPath' => "{$this->ROOT}/AppConfig.json",
|
|
]);
|
|
|
|
// generate benchmark
|
|
new ServerBenchmarkGeneration([
|
|
'phpConfigPath' => "{$this->COMPONENTS_DIR}/ServerBenchmark/ServerBenchmarkMarks.php",
|
|
'configPath' => "{$this->ROOT}/AppConfig.json",
|
|
]);
|
|
|
|
// lang
|
|
$this->languageGeneration($dir);
|
|
|
|
echo "Compile starting...\n";
|
|
|
|
$code = '';
|
|
|
|
if ( ! $this->isDev()) {
|
|
foreach ($this->yieldFiles($this->COMPONENTS_DIR) as $filePath) {
|
|
if (\is_dir($filePath) || false === \strpos($filePath, '.php')) {
|
|
continue;
|
|
}
|
|
|
|
$content = $this->getCodeViaFilePath($filePath);
|
|
$code .= $content;
|
|
}
|
|
}
|
|
|
|
$preDefineCode = $this->preDefine([
|
|
$this->getTimerCode(),
|
|
$this->getDevMode(),
|
|
$this->getLangLoaderCode(),
|
|
$this->getVendorCode(),
|
|
]);
|
|
$code = "<?php\n{$preDefineCode}\n{$code}";
|
|
$code .= $this->loader();
|
|
$code = \preg_replace("/(\r|\n)+/", "\n", $code);
|
|
|
|
if (true === $this->writeFile($code)) {
|
|
new ScriptGeneration([
|
|
'scriptFilePath' => "{$this->ROOT}/tmp/app.js",
|
|
'distFilePath' => $this->COMPILE_FILE_PATH,
|
|
]);
|
|
new StyleGeneration([
|
|
'styleFilePath' => "{$this->ROOT}/tmp/app.css",
|
|
'distFilePath' => $this->COMPILE_FILE_PATH,
|
|
]);
|
|
|
|
if ( ! $this->isDev()) {
|
|
$this->writeFile(\php_strip_whitespace($this->COMPILE_FILE_PATH));
|
|
}
|
|
|
|
echo 'Compiled!';
|
|
} else {
|
|
echo 'Failed.';
|
|
}
|
|
}
|
|
|
|
private function languageGeneration(string $dir): void
|
|
{
|
|
echo "Generating I18n language pack...\n";
|
|
|
|
$langGen = new LanguageGeneration("{$dir}/languages");
|
|
$status = $langGen->writeJsonFile("{$this->COMPONENTS_DIR}/I18n/Lang.json");
|
|
|
|
if ( ! $status) {
|
|
die("Error: can not generate languages.\n");
|
|
}
|
|
|
|
echo "Generated I18n...\n";
|
|
}
|
|
|
|
private function getCodeViaFilePath(string $filePath): string
|
|
{
|
|
$code = '';
|
|
|
|
echo "Packing `{$filePath}...";
|
|
|
|
if ($this->isDev()) {
|
|
$code = \file_get_contents($filePath);
|
|
} else {
|
|
$code = \php_strip_whitespace($filePath);
|
|
$lines = \explode("\n", $code);
|
|
$lineCode = [];
|
|
|
|
foreach ($lines as $line) {
|
|
$lineStr = \trim($line);
|
|
|
|
if ($lineStr) {
|
|
$lineCode[] = $lineStr;
|
|
}
|
|
}
|
|
|
|
$code = \implode("\n", $lineCode);
|
|
}
|
|
|
|
$code = \trim($code, "\n");
|
|
|
|
echo "OK\n";
|
|
|
|
return $code ? \substr($code, 5) : $code;
|
|
}
|
|
|
|
private function isDev(): bool
|
|
{
|
|
global $argv;
|
|
|
|
return \in_array('dev', $argv);
|
|
}
|
|
|
|
private function preDefine(array $code): string
|
|
{
|
|
$codeStr = \implode("\n", $code);
|
|
|
|
return <<<PHP
|
|
declare(strict_types=1);
|
|
namespace InnStudio\\Prober\\Components\\PreDefine;
|
|
{$codeStr}
|
|
PHP;
|
|
}
|
|
|
|
private function getDevMode(): string
|
|
{
|
|
$isDev = $this->isDev() ? 'true' : 'false';
|
|
|
|
return <<<PHP
|
|
\\define('XPROBER_IS_DEV', {$isDev});
|
|
PHP;
|
|
}
|
|
|
|
private function getTimerCode(): string
|
|
{
|
|
return <<<'PHP'
|
|
\define('XPROBER_TIMER', \microtime(true));
|
|
PHP;
|
|
}
|
|
|
|
private function getLangLoaderCode(): string
|
|
{
|
|
if ($this->isDev()) {
|
|
return '';
|
|
}
|
|
|
|
$filePath = $this->COMPONENTS_DIR . '/I18n/Lang.json';
|
|
|
|
if ( ! \is_readable($filePath)) {
|
|
die('Language is missing.');
|
|
}
|
|
|
|
$lines = \file($filePath);
|
|
|
|
$lines = \array_map(function (string $line): string {
|
|
return 0 === \strpos(\trim($line), '// ') ? '' : $line;
|
|
}, $lines);
|
|
|
|
$json = \implode('', $lines);
|
|
$json = \json_decode($json, true);
|
|
|
|
if ( ! $json) {
|
|
die('Invalid json format.');
|
|
}
|
|
|
|
$json = \serialize($json);
|
|
|
|
return <<<PHP
|
|
\\define('XPROBER_LANGUAGES', '{$json}');
|
|
PHP;
|
|
}
|
|
|
|
private function loader(): string
|
|
{
|
|
$dirs = \glob($this->COMPONENTS_DIR . '/*');
|
|
|
|
if ( ! $dirs) {
|
|
return '';
|
|
}
|
|
|
|
$files = [];
|
|
|
|
foreach ($dirs as $dir) {
|
|
$basename = \basename($dir);
|
|
$filePath = "{$dir}/{$basename}.php";
|
|
|
|
if ( ! \is_file($filePath)) {
|
|
continue;
|
|
}
|
|
|
|
if ('Bootstrap' === $basename) {
|
|
continue;
|
|
}
|
|
|
|
$files[] = "new \\InnStudio\\Prober\\Components\\{$basename}\\{$basename}();";
|
|
}
|
|
|
|
$files[] = 'new \\InnStudio\\Prober\\Components\\Bootstrap\\Bootstrap();';
|
|
|
|
return \implode("\n", $files);
|
|
}
|
|
|
|
private function getVendorCode(): string
|
|
{
|
|
if ( ! $this->isDev()) {
|
|
return '';
|
|
}
|
|
|
|
return <<<PHP
|
|
include \dirname(__DIR__) . '/vendor/autoload.php';
|
|
PHP;
|
|
}
|
|
|
|
private function yieldFiles(string $dir): \Iterator
|
|
{
|
|
if (\is_dir($dir)) {
|
|
$dh = \opendir($dir);
|
|
|
|
if ( ! $dh) {
|
|
yield false;
|
|
}
|
|
|
|
while (false !== ($file = \readdir($dh))) {
|
|
if ('.' === $file || '..' === $file) {
|
|
continue;
|
|
}
|
|
|
|
$filePath = "{$dir}/{$file}";
|
|
|
|
if (\is_dir($filePath)) {
|
|
foreach (self::yieldFiles($filePath) as $yieldFilepath) {
|
|
yield $yieldFilepath;
|
|
}
|
|
} else {
|
|
yield $filePath;
|
|
}
|
|
}
|
|
|
|
\closedir($dh);
|
|
}
|
|
|
|
yield $dir;
|
|
}
|
|
|
|
private function writeFile(string $data): bool
|
|
{
|
|
$dir = \dirname($this->COMPILE_FILE_PATH);
|
|
|
|
if ( ! \is_dir($dir)) {
|
|
\mkdir($dir, 0755, true);
|
|
}
|
|
|
|
return (bool) \file_put_contents($this->COMPILE_FILE_PATH, $data);
|
|
}
|
|
}
|