2021-12-07 17:26:34 +01:00
|
|
|
<?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;
|
2021-12-11 01:44:01 +01:00
|
|
|
use Symfony\Component\Dotenv\Dotenv;
|
2021-12-07 17:26:34 +01:00
|
|
|
|
|
|
|
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']??[]);
|
|
|
|
}
|
|
|
|
|
2021-12-11 01:44:01 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2021-12-07 17:26:34 +01:00
|
|
|
public function runScript(string $name, array $args, InputInterface $input, OutputInterface $output)
|
|
|
|
{
|
2021-12-08 04:05:55 +01:00
|
|
|
$script = $this->config['scripts'][$name]??$name;
|
2021-12-07 17:26:34 +01:00
|
|
|
|
|
|
|
if (is_string($script)) {
|
2021-12-11 01:44:01 +01:00
|
|
|
$this->execScript($script, $args, $output);
|
2021-12-08 04:05:55 +01:00
|
|
|
} elseif (is_array($script)) {
|
|
|
|
foreach ($script as $row) {
|
|
|
|
$a = str_getcsv($row, ' ', "'");
|
|
|
|
$c = array_shift($a);
|
|
|
|
if (str_starts_with($c, '@')) {
|
|
|
|
$c = ($this->config['scripts'][substr($c,1)])??$c;
|
|
|
|
$this->runScript($c, $a, $input, $output);
|
|
|
|
} else {
|
2021-12-11 01:44:01 +01:00
|
|
|
$this->execScript($c, $a, $output);
|
2021-12-08 04:05:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-11 01:44:01 +01:00
|
|
|
private function execScript(string $script, array $args, OutputInterface $output)
|
2021-12-08 04:05:55 +01:00
|
|
|
{
|
2021-12-07 17:26:34 +01:00
|
|
|
// call script directly
|
|
|
|
if (str_ends_with($script, '.php')) {
|
|
|
|
$GLOBALS['args'] = $args;
|
|
|
|
$GLOBALS['output'] = $output;
|
|
|
|
$base = $this->getProjectDirectory();
|
|
|
|
if (!file_exists($base ."/". $script)) {
|
|
|
|
fprintf(STDERR, "error: Could not find script file %s\n", $base."/".$script);
|
|
|
|
return;
|
|
|
|
}
|
2021-12-08 04:05:55 +01:00
|
|
|
//echo "# ".$base."/".$script."\n";
|
2021-12-07 17:26:34 +01:00
|
|
|
include $base . "/" . $script;
|
|
|
|
} else {
|
2021-12-08 04:05:55 +01:00
|
|
|
//echo "$ {$script}\n";
|
2021-12-07 17:26:34 +01:00
|
|
|
passthru($script);
|
|
|
|
}
|
|
|
|
}
|
2021-12-11 01:44:01 +01:00
|
|
|
*/
|
2021-12-07 17:26:34 +01:00
|
|
|
|
|
|
|
public function loadEnvironment()
|
|
|
|
{
|
|
|
|
if ($this->loaded) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!array_key_exists('project_dir', $this->config)) {
|
|
|
|
return;
|
|
|
|
}
|
2021-12-09 00:58:28 +01:00
|
|
|
chdir($this->config['project_dir']);
|
|
|
|
|
2021-12-11 01:44:01 +01:00
|
|
|
$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);
|
|
|
|
}
|
|
|
|
|
2021-12-07 17:26:34 +01:00
|
|
|
// $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;
|
|
|
|
}
|
2021-12-11 01:44:01 +01:00
|
|
|
if (is_file($item) && fnmatch("*.php", $item)) {
|
2021-12-07 17:26:34 +01:00
|
|
|
// $this->logger->debug("Preloading file {$item}");
|
|
|
|
try {
|
|
|
|
include_once($item);
|
|
|
|
} catch (\Throwable $t) {
|
|
|
|
fprintf(STDERR, "error: 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, "error: 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 {
|
2021-12-11 01:44:01 +01:00
|
|
|
// fprintf(STDERR, "warning: Could not preload %s\n", $item);
|
|
|
|
// $this->logger->warning("Could not preload {$item}");
|
2021-12-07 17:26:34 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SparkApplication::$instance->getPluginManager()->initializePlugins();
|
|
|
|
}
|
|
|
|
|
2021-12-08 22:19:20 +01:00
|
|
|
public static function createFromDirectory(string|null $directory=null, bool $parents=false): Environment
|
2021-12-07 17:26:34 +01:00
|
|
|
{
|
|
|
|
$directory = $directory ?? getcwd();
|
2021-12-08 22:19:20 +01:00
|
|
|
|
|
|
|
if ($parents) {
|
|
|
|
$check = $directory;
|
|
|
|
while (!glob("{$check}/.spark*")) {
|
|
|
|
$p = dirname($check);
|
|
|
|
if ($p == $check) break;
|
|
|
|
$check = $p;
|
|
|
|
}
|
|
|
|
if (strlen($directory) > 1) {
|
|
|
|
$directory = $check;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-07 17:26:34 +01:00
|
|
|
$candidates = [ $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;
|
|
|
|
}
|
|
|
|
|
|
|
|
$env = new Environment($config);
|
|
|
|
|
|
|
|
return $env;
|
|
|
|
}
|
|
|
|
|
2021-12-11 01:44:01 +01:00
|
|
|
public function expandString(string $input): string
|
|
|
|
{
|
|
|
|
return preg_replace_callback('/([\%\$]\{(.+?)\}/', function ($v) {
|
|
|
|
print_r($v);
|
|
|
|
}, $input);
|
|
|
|
}
|
2021-12-07 17:26:34 +01:00
|
|
|
|
|
|
|
}
|