From b85299b19a7b0e7bf0b97363a983b5aac31c5310 Mon Sep 17 00:00:00 2001 From: Andrii Vasyliev Date: Sun, 25 Dec 2016 15:35:01 +0000 Subject: [PATCH] basically finished splitting out Builder --- src/Builder.php | 132 +++++++++++++++++++++++++++++++++--- src/Plugin.php | 177 +++++++++++++++--------------------------------- 2 files changed, 179 insertions(+), 130 deletions(-) diff --git a/src/Builder.php b/src/Builder.php index f5e302c..2c2915d 100644 --- a/src/Builder.php +++ b/src/Builder.php @@ -11,6 +11,8 @@ namespace hiqdev\composer\config; +use Composer\IO\IOInterface; + /** * Builder assembles config files. * @@ -19,27 +21,96 @@ class Builder { /** - * @var array list of configs to build: name => array of pathes + * @var string path to output assembled configs + */ + protected $outputDir; + + /** + * @var array files to process: config name => list of files */ - public $configs = []; + protected $files = []; + /** + * @var array collected variables + */ + protected $vars = []; const BASE_DIR_SAMPLE = ''; + const FILES_FILENAME = '__files'; - protected function assembleFile($name, array $configs) + public function __construct($outputDir, array $files = []) { - $this->data[$name] = call_user_func_array(['\\hiqdev\\composer\\config\\Helper', 'mergeConfig'], $configs); - $this->writeFile($name, (array) $this->data[$name]); + $this->files = $files; + $this->outputDir = $outputDir; + } + + public function loadFiles() + { + $this->files = $this->readConfig(static::FILES_FILENAME); + } + + public function saveFiles() + { + $this->writeConfig(static::FILES_FILENAME, $this->files); + } + + public function buildConfigs($files = null) + { + if (is_null($files)) { + $files = $this->files; + } + foreach ($files as $name => $pathes) { + $configs = []; + foreach ($pathes as $path) { + $configs[] = $this->readFile($path); + } + $this->buildConfig($name, $configs); + } + } + + /** + * Merges given configs and writes at given name. + * @param mixed $name + * @param array $configs + */ + public function buildConfig($name, array $configs) + { + if (!$this->isSpecialConfig($name)) { + array_push($configs, [ + 'params' => $this->vars['params'], + ]); + } + $this->vars[$name] = call_user_func_array([Helper::className(), 'mergeConfig'], $configs); + $this->writeConfig($name, (array) $this->vars[$name]); + } + + protected function isSpecialConfig($name) + { + return in_array($name, ['defines', 'params'], true); } /** - * Writes config file. + * Writes config file by name. + * @param string $name + * @param array $data + */ + public function writeConfig($name, array $data) + { + static::writeFile($this->getOutputPath($name), $data); + } + + public function getOutputPath($name) + { + return $this->outputDir . DIRECTORY_SEPARATOR . $name . '.php'; + } + + /** + * Writes config file by full path. * @param string $path * @param array $data */ - protected function writeFile($path, array $data) + public static function writeFile($path, array $data) { - $path = $this->buildOutputPath($path); if (!file_exists(dirname($path))) { mkdir(dirname($path), 0777, true); } @@ -47,4 +118,49 @@ protected function writeFile($path, array $data) file_put_contents($path, "vars); + + return (array) require $__path; + } + + if (empty($__skippable)) { + $this->writeError('Non existent config file ' . $__path); + } + + return []; + } + + /** + * @var IOInterface + */ + protected $io; + + public function setIo(IOInterface $io) + { + $this->io = $io; + } + + protected function writeError($text) + { + if (isset($this->io)) { + $this->io->writeError($text); + } else { + echo $text . "\n"; + } + } + } diff --git a/src/Plugin.php b/src/Plugin.php index b9b3520..d0ea046 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -29,11 +29,9 @@ */ class Plugin implements PluginInterface, EventSubscriberInterface { - const OUTPUT_DIR = 'output'; - - const PACKAGE_TYPE = 'yii2-extension'; + const OUTPUT_DIR = 'config'; + const YII2_PACKAGE_TYPE = 'yii2-extension'; const EXTRA_OPTION_NAME = 'config-plugin'; - const VENDOR_DIR_SAMPLE = '/vendor'; /** * @var PackageInterface[] the array of active composer packages @@ -56,17 +54,16 @@ class Plugin implements PluginInterface, EventSubscriberInterface protected $filesystem; /** - * @var array assembled config data + * @var array config name => list of files */ - protected $data = [ - 'aliases' => [], - 'extensions' => [], + protected $files = [ + 'defines' => [], + 'params' => [], ]; - /** - * @var array raw collected data - */ - protected $raw = []; + protected $aliases = []; + + protected $extensions = []; /** * @var array array of not yet merged params @@ -114,139 +111,69 @@ public static function getSubscribedEvents() public function onPostAutoloadDump(Event $event) { $this->io->writeError('Assembling config files'); - $this->io->writeError('Assembling config files'); + $this->scanPackages(); + + $builder = new Builder(static::getOutputDir(), $this->files); + $builder->setIo($this->io); + $builder->saveFiles(); + $builder->writeConfig('aliases', $this->aliases); + $builder->writeConfig('extensions', $this->extensions); + $builder->buildConfigs(); + } + + public static function rebuild() + { + $builder = new Builder(static::getOutputDir()); + $builder->loadFiles(); + $builder->buildConfigs(); + } - /// scan packages + protected function scanPackages() + { foreach ($this->getPackages() as $package) { if ($package instanceof CompletePackageInterface) { $this->processPackage($package); } } - $this->processPackage($this->composer->getPackage()); - - var_dump($this->raw);die('sfdasfsa'); - - $this->assembleParams(); - $this->assembleConfigs(); } /** * Scans the given package and collects extensions data. * @param PackageInterface $package */ - public function processPackage(PackageInterface $package) + protected function processPackage(PackageInterface $package) { $extra = $package->getExtra(); $files = isset($extra[self::EXTRA_OPTION_NAME]) ? $extra[self::EXTRA_OPTION_NAME] : null; - if ($package->getType() !== self::PACKAGE_TYPE && is_null($files)) { + + if ($package->getType() !== self::YII2_PACKAGE_TYPE && is_null($files)) { return; } - $extension = [ - 'name' => $package->getPrettyName(), - 'version' => $package->getVersion(), - ]; - if ($package->getVersion() === '9999999-dev') { - $reference = $package->getSourceReference() ?: $package->getDistReference(); - if ($reference) { - $extension['reference'] = $reference; + foreach ($files as $name => $pathes) { + foreach ((array) $pathes as $path) { + if (!isset($this->files[$name])) { + $this->files[$name] = []; + } + array_push($this->files[$name], $this->preparePath($package, $path)); } } - $aliases = array_merge( + $this->aliases = array_merge( + $this->aliases, $this->prepareAliases($package, 'psr-0'), $this->prepareAliases($package, 'psr-4') ); - if (isset($files['defines'])) { - foreach ((array) $files['defines'] as $file) { - $this->readConfigFile($package, $file); - } - unset($files['defines']); - } - - if (isset($files['params'])) { - foreach ((array) $files['params'] as $file) { - $this->rawParams[] = $this->readConfigFile($package, $file); - } - unset($files['params']); - } - - $this->raw[$package->getPrettyName()] = [ - 'package' => $package, - 'extension' => $extension, - 'aliases' => $aliases, - 'files' => (array) $files, - ]; - } - - public function assembleParams() - { - $this->assembleFile('params', $this->rawParams); - } - - public function assembleConfigs() - { - $rawConfigs = [ - 'aliases' => [], - 'extensions' => [], - ]; - - foreach ($this->raw as $name => $info) { - $rawConfigs['extensions'][] = [ - $name => $info['extension'], - ]; - - $aliases = $info['aliases']; - $rawConfigs['aliases'][] = $aliases; - - foreach ($info['files'] as $name => $pathes) { - foreach ((array) $pathes as $path) { - $rawConfigs[$name][] = $this->readConfigFile($info['package'], $path); - } - } - } - - foreach ($rawConfigs as $name => $configs) { - if (!in_array($name, ['params', 'aliases', 'extensions'], true)) { - $configs[] = [ - 'params' => $this->data['params'], - 'aliases' => $this->data['aliases'], - ]; - } - $this->assembleFile($name, $configs); - } - } - - /** - * Reads extra config. - * @param PackageInterface $__package - * @param string $__file - * @return array - */ - protected function readConfigFile(PackageInterface $__package, $__file) - { - $__skippable = false; - if (strncmp($__file, '?', 1) === 0) { - $__skippable = true; - $__file = substr($__file, 1); - } - $__path = $this->preparePath($__package, $__file); - if (!file_exists($__path)) { - if ($__skippable) { - return []; - } else { - $this->io->writeError('Non existent config file ' . $__file . ' in ' . $__package->getPrettyName()); - } - } - extract($this->data); - - return (array) require $__path; + $this->extensions[$package->getPrettyName()] = array_filter([ + 'name' => $package->getPrettyName(), + 'version' => $package->getVersion(), + 'reference' => $package->getSourceReference() ?: $package->getDistReference(), + ]); } /** * Prepare aliases. - * * @param PackageInterface $package * @param string 'psr-0' or 'psr-4' * @return array @@ -267,7 +194,7 @@ protected function prepareAliases(PackageInterface $package, $psr) } $name = str_replace('\\', '/', trim($name, '\\')); $path = $this->preparePath($package, $path); - $path = $this->substitutePath($path, $this->getBaseDir(), self::BASE_DIR_SAMPLE); + $path = $this->substitutePath($path, $this->getBaseDir(), Builder::BASE_DIR_SAMPLE); if ('psr-0' === $psr) { $path .= '/' . $name; } @@ -284,7 +211,7 @@ protected function prepareAliases(PackageInterface $package, $psr) * @param string $alias * @return string */ - public function substitutePath($path, $dir, $alias) + protected function substitutePath($path, $dir, $alias) { return (substr($path, 0, strlen($dir) + 1) === $dir . '/') ? $alias . substr($path, strlen($dir)) : $path; } @@ -297,6 +224,11 @@ public function substitutePath($path, $dir, $alias) */ public function preparePath(PackageInterface $package, $path) { + $skippable = false; + if (strncmp($path, '?', 1) === 0) { + $skippable = true; + $path = substr($path, 1); + } if (!$this->getFilesystem()->isAbsolutePath($path)) { $prefix = $package instanceof RootPackageInterface ? $this->getBaseDir() @@ -305,16 +237,16 @@ public function preparePath(PackageInterface $package, $path) $path = $prefix . '/' . $path; } - return $this->getFilesystem()->normalizePath($path); + return ($skippable ? '?' : '') . $this->getFilesystem()->normalizePath($path); } /** * Get output dir. * @return string */ - public function getOutputDir() + public static function getOutputDir() { - return dirname(__DIR__) . DIRECTORY_SEPARATOR . static::OUTPUT_DIR; + return dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . static::OUTPUT_DIR; } /** @@ -377,7 +309,8 @@ public function findPackages() $this->iteratePackage($root, true); if ($this->io->isVerbose()) { - $packages = implode("\n", $this->orderedList); + $indent = ' - '; + $packages = $indent . implode("\n$indent", $this->orderedList); $this->io->writeError($packages); } $res = [];