php-spark/src/Environment/Environment.php

183 lines
5.8 KiB
PHP

<?php
namespace Spark\Environment;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Spark\SparkApplication;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Dotenv\Dotenv;
class Environment
{
private bool $loaded = false;
private array $config;
public function __construct(array $config)
{
$this->config = $config;
}
public function getProjectDirectory(): string
{
return $this->config['project_dir'];
}
public function getConfigDirectory(): string
{
return $this->config['config_dir'];
}
public function getDefinedScripts(): array
{
return array_keys($this->config['scripts']??[]);
}
public function getScriptRunner(): ScriptRunner
{
$runner = new ScriptRunner();
$runner->setDirectory($this->getProjectDirectory());
foreach ((array)$this->config['scripts'] as $name => $script) {
$runner->defineScript($name, $script);
}
return $runner;
}
public function loadEnvironment()
{
if ($this->loaded) {
return;
}
if (!array_key_exists('project_dir', $this->config)) {
return;
}
chdir($this->config['project_dir']);
$envfile = $this->config['project_dir']."/.env";
if (file_exists($envfile)) {
$dotenv = new Dotenv();
$dotenv->load($envfile);
}
$blacklistFile = $this->config['config_dir']."/blacklist";
if (file_exists($blacklistFile)) {
$blacklist = json_decode(file_get_contents($blacklistFile), true);
}
if (empty($this->config['preload'])) {
fprintf(STDERR, "Error: Missing or malformed spark.json file.\n");
exit(1);
}
// $this->logger->info("Loading environment...");
$preloads = [];
$root = $this->config['project_dir'];
foreach ((array)$this->config['preload']??[] as $preload) {
if (str_contains($preload,'*')) {
array_push($preloads, ...glob($root."/".$preload));
} else {
array_push($preloads, $preload);
}
}
foreach ($preloads as $item) {
if (!str_starts_with($item, "/")) {
$item = $this->getProjectDirectory() . "/" . $item;
}
if (is_file($item) && fnmatch("*.php", $item)) {
// $this->logger->debug("Preloading file {$item}");
try {
include_once($item);
} catch (\Throwable $t) {
fprintf(STDERR, "warning: Error preloading %s: %s in %s on line %d\n", $item, $t->getMessage(), $t->getFile(), $t->getLine());
//$this->logger->error("Error preloading {$item}: {$t->getMessage()} in {$t->getFile()} on line {$t->getLine()}");
}
} elseif (is_dir($item) && file_exists($item."/sparkplug.php")) {
//$this->logger->debug("Preloading plugin {$item}");
try {
include_once($item."/sparkplug.php");
} catch (\Throwable $t) {
fprintf(STDERR, "warning: Error preloading plugin %s: %s in %s on line %d\n", $item, $t->getMessage(), $t->getFile(), $t->getLine());
//$this->logger->error("Error preloading plugin {$item}: {$t->getMessage()} in {$t->getFile()} on line {$t->getLine()}");
}
} else {
// fprintf(STDERR, "warning: Could not preload %s\n", $item);
// $this->logger->warning("Could not preload {$item}");
}
}
SparkApplication::$instance->getPluginManager()->initializePlugins();
$this->loadResources();
}
private function loadResources()
{
$resourceFile = $this->getConfigDirectory() . "/resources.json";
if (!file_exists($resourceFile)) {
return;
}
$json = json_decode(
file_get_contents($resourceFile),
true
);
foreach ($json['resources'] as $name=>$uri) {
[$type, $uri] = explode("+", $uri, 2);
create_resource($name, $type, uri:$uri);
}
}
public static function createFromDirectory(string|null $directory=null, bool $parents=false): ?Environment
{
$directory = realpath($directory) ?? getcwd();
if ($parents) {
$check = $directory;
while (!glob("{$check}/.spark*")) {
$p = dirname($check);
if ($p == $check) break;
$check = $p;
}
if (strlen($directory) > 1) {
$directory = $check;
}
}
$candidates = [ $directory . "/.spark.json", $directory . "/spark.json", $directory . "/.spark/spark.json" ];
$config = [];
while ($candidate = array_shift($candidates)) {
if (!file_exists($candidate)) { continue; }
$json = file_get_contents($candidate);
if (!$json || json_last_error()) {
throw new \RuntimeException("Error parsing {$candidate}: ".json_last_error_msg());
}
$config = json_decode($json, true);
$config['project_dir'] = realpath($directory);
$config['config_dir'] = realpath($directory)."/.spark";
$config['config_file'] = $candidate;
break;
}
if (!$config) {
return null;
}
$env = new Environment($config);
return $env;
}
public function expandString(string $input): string
{
return preg_replace_callback('/([\%\$]\{(.+?)\}/', function ($v) {
print_r($v);
}, $input);
}
}