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 readConfig(string $filename, bool $global=false): ?array { $path = ($global ? getenv("HOME")."/.config/spark" : $this->getConfigDirectory()); $filepath = $path . "/" . $filename; $dirname = dirname($filepath); if (!is_dir($dirname) || !file_exists($filepath)) { return null; } $json = file_get_contents($filepath); return json_decode($json, true); } public function writeConfig(string $filename, $config, bool $global=false) { $path = ($global ? getenv("HOME")."/.config/spark" : $this->getConfigDirectory()); $filepath = $path . "/" . $filename; $dirname = dirname($filepath); if (!is_dir($dirname) && $global) { mkdir($dirname, 0777, true); } $json = json_encode($config, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); file_put_contents($filepath, $json); } 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); } }