mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-02 14:25:41 +08:00
152 lines
5.3 KiB
PHP
152 lines
5.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace StaticPHP\Config;
|
|
|
|
use StaticPHP\Exception\WrongUsageException;
|
|
use StaticPHP\Registry\Registry;
|
|
use StaticPHP\Runtime\SystemTarget;
|
|
use StaticPHP\Util\FileSystem;
|
|
use Symfony\Component\Yaml\Yaml;
|
|
|
|
class PackageConfig
|
|
{
|
|
private static array $package_configs = [];
|
|
|
|
/**
|
|
* Load package configurations from a specified directory.
|
|
* It will look for files matching the pattern 'pkg.*.json' and 'pkg.json'.
|
|
*/
|
|
public static function loadFromDir(string $dir, string $registry_name): array
|
|
{
|
|
if (!is_dir($dir)) {
|
|
throw new WrongUsageException("Directory {$dir} does not exist, cannot load pkg.json config.");
|
|
}
|
|
$dir = rtrim($dir, '/');
|
|
$loaded = [];
|
|
$files = FileSystem::scanDirFiles($dir, false);
|
|
if (is_array($files)) {
|
|
foreach ($files as $file) {
|
|
self::loadFromFile($file, $registry_name);
|
|
$loaded[] = $file;
|
|
}
|
|
}
|
|
if (file_exists("{$dir}/pkg.json")) {
|
|
self::loadFromFile("{$dir}/pkg.json", $registry_name);
|
|
$loaded[] = "{$dir}/pkg.json";
|
|
}
|
|
return $loaded;
|
|
}
|
|
|
|
/**
|
|
* Load package configurations from a specified JSON file.
|
|
*
|
|
* @param string $file the path to the json package configuration file
|
|
*/
|
|
public static function loadFromFile(string $file, string $registry_name): string
|
|
{
|
|
$content = @file_get_contents($file);
|
|
if ($content === false) {
|
|
throw new WrongUsageException("Failed to read package config file: {$file}");
|
|
}
|
|
// judge extension — use cache to skip redundant parsing
|
|
$data = ConfigCache::get($content);
|
|
if ($data !== null) {
|
|
logger()->debug("Config cache hit: {$file}");
|
|
} else {
|
|
$data = match (pathinfo($file, PATHINFO_EXTENSION)) {
|
|
'json' => json_decode($content, true),
|
|
'yml', 'yaml' => extension_loaded('yaml') ? yaml_parse($content) : Yaml::parse($content),
|
|
default => throw new WrongUsageException("Unsupported package config file format: {$file}"),
|
|
};
|
|
if (is_array($data)) {
|
|
ConfigCache::set($content, $data);
|
|
}
|
|
}
|
|
ConfigValidator::validateAndLintPackages(basename($file), $data);
|
|
foreach ($data as $pkg_name => $config) {
|
|
self::$package_configs[$pkg_name] = $config;
|
|
Registry::_bindPackageConfigFile($pkg_name, $registry_name, $file);
|
|
|
|
// Register inline artifact if present
|
|
if (isset($config['artifact']) && is_array($config['artifact'])) {
|
|
ArtifactConfig::registerInlineArtifact(
|
|
$pkg_name,
|
|
$config['artifact'],
|
|
$registry_name,
|
|
"inline in {$file}"
|
|
);
|
|
}
|
|
}
|
|
return $file;
|
|
}
|
|
|
|
public static function loadFromArray(array $data, string $registry_name): void
|
|
{
|
|
ConfigValidator::validateAndLintPackages('array_input', $data);
|
|
foreach ($data as $pkg_name => $config) {
|
|
self::$package_configs[$pkg_name] = $config;
|
|
Registry::_bindPackageConfigFile($pkg_name, $registry_name, 'array_input');
|
|
|
|
// Register inline artifact if present
|
|
if (isset($config['artifact']) && is_array($config['artifact'])) {
|
|
ArtifactConfig::registerInlineArtifact(
|
|
$pkg_name,
|
|
$config['artifact'],
|
|
$registry_name,
|
|
'inline in array_input'
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if a package configuration exists.
|
|
*/
|
|
public static function isPackageExists(string $pkg_name): bool
|
|
{
|
|
return isset(self::$package_configs[$pkg_name]);
|
|
}
|
|
|
|
public static function getAll(): array
|
|
{
|
|
return self::$package_configs;
|
|
}
|
|
|
|
/**
|
|
* Get a specific field from a package configuration.
|
|
*
|
|
* @param string $pkg_name Package name
|
|
* @param null|string $field_name Package config field name
|
|
* @param null|mixed $default Default value if field not found
|
|
* @return mixed The value of the specified field or the default value
|
|
*/
|
|
public static function get(string $pkg_name, ?string $field_name = null, mixed $default = null): mixed
|
|
{
|
|
if (!self::isPackageExists($pkg_name)) {
|
|
return $default;
|
|
}
|
|
// use suffixes to find field
|
|
$suffixes = match (SystemTarget::getTargetOS()) {
|
|
'Windows' => ['@windows', ''],
|
|
'Darwin' => ['@macos', '@unix', ''],
|
|
'Linux' => ['@linux', '@unix', ''],
|
|
'BSD' => ['@freebsd', '@bsd', '@unix', ''],
|
|
};
|
|
if ($field_name === null) {
|
|
return self::$package_configs[$pkg_name];
|
|
}
|
|
if (in_array($field_name, ConfigValidator::SUFFIX_ALLOWED_FIELDS)) {
|
|
foreach ($suffixes as $suffix) {
|
|
$suffixed_field = $field_name . $suffix;
|
|
if (isset(self::$package_configs[$pkg_name][$suffixed_field])) {
|
|
return self::$package_configs[$pkg_name][$suffixed_field];
|
|
}
|
|
}
|
|
return $default;
|
|
}
|
|
return self::$package_configs[$pkg_name][$field_name] ?? $default;
|
|
}
|
|
}
|