Skip to content

Commit

Permalink
added proper resolving of config dependencies with Resolver class
Browse files Browse the repository at this point in the history
  • Loading branch information
hiqsol committed May 11, 2017
1 parent 8303cb7 commit a0f372d
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ public function buildConfigs($files = null)
if (is_null($files)) {
$files = $this->files;
}
$resolver = new Resolver($files);
$files = $resolver->get();
foreach ($files as $name => $paths) {
$olddefs = get_defined_constants();
$configs = $this->loadConfigs($paths);
Expand Down
8 changes: 4 additions & 4 deletions src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -263,15 +263,15 @@ protected function prepareAliases(PackageInterface $package, $psr, $dev = false)
*/
public function preparePath(PackageInterface $package, $path)
{
if (strncmp($path, '$', 1) === 0) {
return $path;
}

$skippable = strncmp($path, '?', 1) === 0 ? '?' : '';
if ($skippable) {
$path = substr($path, 1);
}

if (strncmp($path, '$', 1) === 0) {
$path = Builder::path(substr($path, 1));
}

if (!$this->getFilesystem()->isAbsolutePath($path)) {
$prefix = $package instanceof RootPackageInterface
? $this->getBaseDir()
Expand Down
100 changes: 100 additions & 0 deletions src/Resolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php
/**
* Composer plugin for config assembling
*
* @link https://github.com/hiqdev/composer-config-plugin
* @package composer-config-plugin
* @license BSD-3-Clause
* @copyright Copyright (c) 2016-2017, HiQDev (http://hiqdev.com/)
*/

namespace hiqdev\composer\config;

use hiqdev\composer\config\exceptions\CircularDependencyException;

/**
* Resolver class.
* Reorders files according to their cross dependencies
* and resolves `$name` pathes.
* @author Andrii Vasyliev <sol@hiqdev.com>
*/
class Resolver
{
protected $order = [];

protected $deps = [];

protected $following = [];

public function __construct(array $files)
{
$this->files = $files;

$this->collectDeps();
foreach (array_keys($this->files) as $name) {
$this->followDeps($name);
}

}

public function get()
{
$result = [];
foreach ($this->order as $name) {
$result[$name] = $this->resolveDeps($this->files[$name]);
}

return $result;
}

protected function resolveDeps(array $paths)
{
foreach ($paths as &$path) {
$dep = $this->isDep($path);
if ($dep) {
$path = Builder::path($dep);
}
}

return $paths;
}

protected function followDeps($name)
{
if (isset($this->order[$name])) {
return;
}
if (isset($this->following[$name])) {
throw new CircularDependencyException($name . ' ' . implode(',', $this->following));
}
$this->following[$name] = $name;
if (isset($this->deps[$name])) {
foreach ($this->deps[$name] as $dep) {
$this->followDeps($dep);
}
}
$this->order[$name] = $name;
unset($this->following[$name]);
}

protected function collectDeps()
{
foreach ($this->files as $name => $paths) {
foreach ($paths as $path) {
$dep = $this->isDep($path);
if ($dep) {
if (!isset($this->deps[$name])) {
$this->deps[$name] = [];
}
$this->deps[$name][$dep] = $dep;
}
}
}
}

protected function isDep($path)
{
return strncmp($path, '$', 1) === 0 ? substr($path, 1) : false;
}

}
19 changes: 19 additions & 0 deletions src/exceptions/CircularDependencyException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
/**
* Composer plugin for config assembling
*
* @link https://github.com/hiqdev/composer-config-plugin
* @package composer-config-plugin
* @license BSD-3-Clause
* @copyright Copyright (c) 2016-2017, HiQDev (http://hiqdev.com/)
*/

namespace hiqdev\composer\config\exceptions;

/**
* Circular dependency exception.
* @author Andrii Vasyliev <sol@hiqdev.com>
*/
class CircularDependencyException extends Exception
{
}

0 comments on commit a0f372d

Please sign in to comment.