X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fdrush%2Fdrush%2Fsrc%2FConfig%2FConfigLocator.php;fp=vendor%2Fdrush%2Fdrush%2Fsrc%2FConfig%2FConfigLocator.php;h=c9948103822bc00335b200e02493322ce218dfa6;hp=0000000000000000000000000000000000000000;hb=af6d1fb995500ae68849458ee10d66abbdcfb252;hpb=680c79a86e3ed402f263faeac92e89fb6d9edcc0 diff --git a/vendor/drush/drush/src/Config/ConfigLocator.php b/vendor/drush/drush/src/Config/ConfigLocator.php new file mode 100644 index 000000000..c99481038 --- /dev/null +++ b/vendor/drush/drush/src/Config/ConfigLocator.php @@ -0,0 +1,548 @@ +configFileVariant = $configFileVariant; + $this->config = new DrushConfig(); + + // Add placeholders to establish priority. We add + // contexts from lowest to highest priority. + $this->config->addPlaceholder(self::DRUSH_CONTEXT); + if (!empty($envPrefix)) { + $envConfig = new EnvConfig($envPrefix); + $this->config->addContext(self::ENV_CONTEXT, $envConfig); + } + $this->config->addPlaceholder(self::USER_CONTEXT); + $this->config->addPlaceholder(self::DRUPAL_CONTEXT); + $this->config->addPlaceholder(self::SITE_CONTEXT); // not implemented yet (multisite) + $this->config->addPlaceholder(self::ALIAS_CONTEXT); + $this->config->addPlaceholder(self::PREFLIGHT_CONTEXT); + $this->config->addPlaceholder(self::ENVIRONMENT_CONTEXT); + + $this->isLocal = false; + + $this->configFilePaths = []; + } + + /** + * Put the config locator into 'local 'mode. + * + * @param bool $isLocal + */ + public function setLocal($isLocal) + { + $this->isLocal = $isLocal; + } + + /** + * Keep track of the source that every config item originally came from. + * Potentially useful in debugging. If collectSources(true) is called, + * then the sources will be accumulated as config files are loaded. Otherwise, + * this information will not be saved. + * + * @param bool $collect + * @return $this + */ + public function collectSources($collect = true) + { + $this->sources = $collect ? [] : false; + return $this; + } + + /** + * Return all of the sources for every configuration item. The key + * is the address of the configuration item, and the value is the + * configuration file it was loaded from. Note that this method will + * return just an empty array unless collectSources(true) is called + * prior to loading configuration files. + * + * @return array + */ + public function sources() + { + return $this->sources; + } + + /** + * Return a list of all configuration files that were loaded. + * + * @return string[] + */ + public function configFilePaths() + { + return $this->configFilePaths; + } + + /** + * Accumulate the sources provided by the configuration loader. + */ + protected function addToSources(array $sources) + { + if (!is_array($this->sources)) { + return; + } + $this->sources = array_merge_recursive($this->sources, $sources); + } + + /** + * Return the configuration object. Create it and load it with + * all identified configuration if necessary. + * + * @return Config + */ + public function config() + { + return $this->config; + } + + /** + * Exports all of the information stored in the environment, and adds + * it to the configuration. The Environment object itself is only + * available during preflight; the information exported here may be + * obtained by commands et. al. as needed. @see Environment::exportConfigData() + * + * @param Environment $environent + * @return $this + */ + public function addEnvironment(Environment $environment) + { + $this->config->getContext(self::ENVIRONMENT_CONTEXT)->import($environment->exportConfigData()); + return $this; + } + + /** + * Add config paths defined in preflight configuration. + * + * @param array $paths + * @return $this + */ + public function addPreflightConfigFiles($filepaths) + { + $this->addConfigPaths(self::PREFLIGHT_CONTEXT, (array) $filepaths); + return $this; + } + + /** + * Take any configuration from the active alias record, and add it + * to our configuratino. + * @return $this + */ + public function addAliasConfig($aliasConfig) + { + $this->config->addContext(self::ALIAS_CONTEXT, $aliasConfig); + return $this; + } + + + /** + * Given the path provided via --config and the user's home directory, + * add all of the user configuration paths. + * + * In 'local' mode, only the --config location is used. + * @return $this + */ + public function addUserConfig($configPaths, $systemConfigPath, $userConfigDir) + { + $paths = $configPaths; + if (!$this->isLocal) { + $paths = array_merge($paths, [ $systemConfigPath, $userConfigDir ]); + } + $this->addConfigPaths(self::USER_CONTEXT, $paths); + return $this; + } + + /** + * Add the Drush project directory as a configuration search location. + * + * @param $drushProjectDir path to the drush project directory + * @return $this + */ + public function addDrushConfig($drushProjectDir) + { + if (!$this->isLocal) { + $this->addConfigPaths(self::DRUSH_CONTEXT, [ $drushProjectDir ]); + } + return $this; + } + + /** + * Add any configuration files found around the Drupal root of the + * selected site. + * + * @param Path to the selected Drupal site + * @return $this + */ + public function addSitewideConfig($siteRoot) + { + // There might not be a site. + if (!is_dir($siteRoot)) { + return; + } + + // We might have already processed this root. + $siteRoot = realpath($siteRoot); + if (in_array($siteRoot, $this->siteRoots)) { + return; + } + + // Remember that we've seen this location. + $this->siteRoots[] = $siteRoot; + + $this->addConfigPaths(self::DRUPAL_CONTEXT, [ dirname($siteRoot) . '/drush', "$siteRoot/drush", "$siteRoot/sites/all/drush" ]); + return $this; + } + + /** + * Add any configuration file found at any of the provided paths. Both the + * provided location, and the directory `config` inside each provided location + * is searched for a drush.yml file. + * + * @param string $contextName Which context to put all configuration files in. + * @param string[] $paths List of paths to search for configuration. + * @return $this + */ + public function addConfigPaths($contextName, $paths) + { + $loader = new YamlConfigLoader(); + // Make all of the config values parsed so far available in evaluations. + $reference = $this->config()->export(); + $processor = new ConfigProcessor(); + $context = $this->config->getContext($contextName); + $processor->add($context->export()); + + $candidates = [ + 'drush.yml', + ]; + if ($this->configFileVariant) { + $candidates[] = "drush{$this->configFileVariant}.yml"; + } + $candidates = $this->expandCandidates($candidates, 'config/'); + $config_files = $this->findConfigFiles($paths, $candidates); + $this->addConfigFiles($processor, $loader, $config_files); + + // Complete config import. + $this->addToSources($processor->sources()); + $context->import($processor->export($reference)); + $this->config->addContext($contextName, $context); + $this->processedConfigPaths = array_merge($this->processedConfigPaths, $paths); + + // Recursive case. + if ($context->has('drush.paths.config')) { + $new_config_paths = array_diff((array) $context->get('drush.paths.config'), $this->processedConfigPaths); + if ($new_config_paths) { + $this->addConfigPaths($contextName, $new_config_paths); + } + } + + return $this; + } + + /** + * Adds $configFiles config files. + * + * @param ConfigProcessor $processor + * @param ConfigLoaderInterface $loader + * @param array $configFiles + */ + protected function addConfigFiles(ConfigProcessor $processor, ConfigLoaderInterface $loader, array $configFiles) + { + foreach ($configFiles as $configFile) { + $processor->extend($loader->load($configFile)); + $this->configFilePaths[] = $configFile; + } + } + + /** + * Given a list of paths, and candidates that might exist at each path, + * return all of the candidates that can be found. Candidates may be + * either directories or files. + * + * @param string[] $paths + * @param string[] $candidates + * @return string[] paths + */ + protected function identifyCandidates($paths, $candidates) + { + $configFiles = []; + foreach ($paths as $path) { + $configFiles = array_merge($configFiles, $this->identifyCandidatesAtPath($path, $candidates)); + } + return $configFiles; + } + + /** + * Search for all matching candidate locations at a single path. + * Candidate locations may be either directories or files. + * + * @param string $path + * @param string[] $candidates + * @return string[] + */ + protected function identifyCandidatesAtPath($path, $candidates) + { + if (!is_dir($path)) { + return []; + } + + $result = []; + foreach ($candidates as $candidate) { + $configFile = empty($candidate) ? $path : "$path/$candidate"; + if (file_exists($configFile)) { + $result[] = $configFile; + } + } + return $result; + } + + /** + * Get the site aliases according to preflight arguments and environment. + * + * @param $preflightArgs + * @param Environment $environment + * + * @return array + */ + public function getSiteAliasPaths($paths, Environment $environment) + { + // In addition to the paths passed in to us (from --alias-paths + // commandline options), add some site-local locations. + $base_dirs = array_filter(array_merge($this->siteRoots, [$this->composerRoot])); + $site_local_paths = array_map( + function ($item) { + return "$item/drush/sites"; + }, + $base_dirs + ); + $paths = array_merge($paths, $site_local_paths); + + return $paths; + } + + /** + * Get the commandfile paths according to preflight arguments. + * + * @param $preflightArgs + * + * @return array + */ + public function getCommandFilePaths($commandPaths, $root) + { + $builtin = $this->getBuiltinCommandFilePaths(); + $included = $this->getIncludedCommandFilePaths($commandPaths); + $site = $this->getSiteCommandFilePaths(["$root/drush", dirname($root) . '/drush']); + + return array_merge( + $builtin, + $included, + $site + ); + } + + /** + * Return all of the built-in commandfile locations + */ + protected function getBuiltinCommandFilePaths() + { + return [ + dirname(__DIR__), + ]; + } + + /** + * Return all of the commandfile locations specified via + * an 'include' option. + */ + protected function getIncludedCommandFilePaths($commandPaths) + { + $searchpath = []; + // Commands specified by 'include' option + foreach ($commandPaths as $commandPath) { + if (is_dir($commandPath)) { + $searchpath[] = $commandPath; + } + } + return $searchpath; + } + + /** + * Return all of the commandfile paths in any '$root/drush' or + * 'dirname($root)/drush' directory that contains a composer.json + * file or a 'Commands' or 'src/Commands' directory. + */ + protected function getSiteCommandFilePaths($directories) + { + $result = []; + + $directories = array_filter($directories, 'is_dir'); + + if (empty($directories)) { + return $result; + } + + // Find projects + $finder = new Finder(); + $finder->files() + ->ignoreUnreadableDirs() + ->path('#composer.json$|^src/Commands|^Commands#') + ->in($directories) + ->depth('<= 3'); + + foreach ($finder as $file) { + $result[] = dirname($file->getRealPath()); + } + + return $result; + } + + /** + * Sets the composer root. + * + * @param $selectedComposerRoot + */ + public function setComposerRoot($selectedComposerRoot) + { + $this->composerRoot = $selectedComposerRoot; + } + + /** + * Double the candidates, adding '$prefix' before each existing one. + */ + public function expandCandidates($candidates, $prefix) + { + $additional = array_map( + function ($item) use ($prefix) { + return $prefix . $item; + }, + $candidates + ); + return array_merge($candidates, $additional); + } + + /** + * Given an array of paths, separates files and directories. + * + * @param array $paths + * An array of config paths. These may be config files or paths to dirs + * containing config files. + * @param array $candidates + * An array filenames that are considered config files. + * + * @return array + * An array. The first row is an array of files, the second row is an + * array of dirs. + */ + protected function findConfigFiles($paths, $candidates) + { + $files = []; + $dirs = []; + foreach ($paths as $path) { + if (file_exists($path)) { + if (is_dir($path)) { + $dirs[] = realpath($path); + } else { + $files[] = realpath($path); + } + } + } + + // Search directories for config file candidates. + $discovered_config_files = $this->identifyCandidates($dirs, $candidates); + + // Merge discoverd candidates with explicitly specified config files. + $config_files = array_merge($discovered_config_files, $files); + + return $config_files; + } +}