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 runScript(string $name, array $args, InputInterface $input, OutputInterface $output) { $script = $this->config['scripts'][$name]??$name; if (is_string($script)) { $this->execScript($script, $args); } 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 { $this->execScript($c, $a); } } } } private function execScript(string $script, array $args) { // 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; } //echo "# ".$base."/".$script."\n"; include $base . "/" . $script; } else { //echo "$ {$script}\n"; passthru($script); } } public function loadEnvironment() { if ($this->loaded) { return; } if (!array_key_exists('project_dir', $this->config)) { return; } // $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)) { // $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 { fprintf(STDERR, "warning: Could not preload %s\n", $item); //$this->logger->warning("Could not preload {$item}"); } } SparkApplication::$instance->getPluginManager()->initializePlugins(); } public static function createFromDirectory(string|null $directory=null): Environment { $directory = $directory ?? getcwd(); $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; } }