diff --git a/composer.json b/composer.json index 03983d5..1143fec 100644 --- a/composer.json +++ b/composer.json @@ -5,9 +5,10 @@ "homepage": "https://github.com/clue/graph-composer", "license": "MIT", "require": { - "clue/graph": "0.7.*", + "clue/graph": "~0.9.0", "jms/composer-deps-analyzer": "0.1.*", - "symfony/console": "~2.1" + "symfony/console": "~2.1", + "graphp/graphviz": "~0.2.0" }, "autoload": { "psr-0": {"Clue": "src/"} diff --git a/composer.lock b/composer.lock index e0e2adf..3221900 100644 --- a/composer.lock +++ b/composer.lock @@ -1,34 +1,40 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" ], - "hash": "f590e0cb22eaa5592e69ce65d07c2c21", + "hash": "199750579456226304ddb1b0753ecc23", + "content-hash": "aed5f261fd5bfc20be75ec15a552ca9f", "packages": [ { "name": "clue/graph", - "version": "v0.7.0", + "version": "v0.9.0", "source": { "type": "git", "url": "https://github.com/clue/graph.git", - "reference": "d0d548a21b09099a266eacba8e4098aeae6409f8" + "reference": "0336a4d5229fa61a20ccceaeab25e52ac9542700" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/clue/graph/zipball/d0d548a21b09099a266eacba8e4098aeae6409f8", - "reference": "d0d548a21b09099a266eacba8e4098aeae6409f8", + "url": "https://api.github.com/repos/clue/graph/zipball/0336a4d5229fa61a20ccceaeab25e52ac9542700", + "reference": "0336a4d5229fa61a20ccceaeab25e52ac9542700", "shasum": "" }, "require": { "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "3.7.*" + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "graphp/algorithms": "Common graph algorithms, such as Dijkstra and Moore-Bellman-Ford (shortest path), minimum spanning tree (MST), Kruskal, Prim and many more..", + "graphp/graphviz": "GraphViz graph drawing / DOT output" }, "type": "library", "autoload": { - "psr-0": { - "Fhaculty": "lib/" + "psr-4": { + "Fhaculty\\Graph\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -38,20 +44,105 @@ "description": "A mathematical graph/network library written in PHP", "homepage": "https://github.com/clue/graph", "keywords": [ - "dijkstra", "edge", "graph", - "graphviz", - "kruskal", "mathematical", + "network", + "vertex" + ], + "time": "2015-03-07 18:11:31" + }, + { + "name": "graphp/algorithms", + "version": "v0.8.1", + "source": { + "type": "git", + "url": "https://github.com/graphp/algorithms.git", + "reference": "81db4049c35730767ec8f97fb5c4844234b86cef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/graphp/algorithms/zipball/81db4049c35730767ec8f97fb5c4844234b86cef", + "reference": "81db4049c35730767ec8f97fb5c4844234b86cef", + "shasum": "" + }, + "require": { + "clue/graph": "~0.9.0|~0.8.0", + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Graphp\\Algorithms\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@lueck.tv" + } + ], + "description": "Common mathematical graph algorithms", + "homepage": "https://github.com/graphp/algorithms", + "keywords": [ + "Graph algorithms", + "dijkstra", + "kruskal", "minimum spanning tree", "moore-bellman-ford", - "network", "prim", - "shortest path", - "vertex" + "shortest path" + ], + "time": "2015-03-08 10:12:01" + }, + { + "name": "graphp/graphviz", + "version": "v0.2.1", + "source": { + "type": "git", + "url": "https://github.com/graphp/graphviz.git", + "reference": "2676522dfcd907fd3cb52891ea64a052c4ac4c2a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/graphp/graphviz/zipball/2676522dfcd907fd3cb52891ea64a052c4ac4c2a", + "reference": "2676522dfcd907fd3cb52891ea64a052c4ac4c2a", + "shasum": "" + }, + "require": { + "clue/graph": "~0.9.0|~0.8.0", + "graphp/algorithms": "~0.8.0", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Graphp\\GraphViz\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "GraphViz graph drawing for mathematical graph/network", + "homepage": "https://github.com/graphp/graphviz", + "keywords": [ + "dot output", + "graph drawing", + "graph image", + "graphviz" ], - "time": "2013-09-11 22:52:40" + "time": "2015-03-08 10:30:28" }, { "name": "jms/composer-deps-analyzer", @@ -94,12 +185,12 @@ "target-dir": "Symfony/Component/Console", "source": { "type": "git", - "url": "https://github.com/symfony/Console.git", - "reference": "v2.2.1" + "url": "https://github.com/symfony/console.git", + "reference": "d146fc32a9cf13bc479820e515048298a34cd432" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/v2.2.1", + "url": "https://api.github.com/repos/symfony/console/zipball/d146fc32a9cf13bc479820e515048298a34cd432", "reference": "v2.2.1", "shasum": "" }, @@ -136,20 +227,12 @@ "time": "2013-03-19 20:48:08" } ], - "packages-dev": [ - - ], - "aliases": [ - - ], + "packages-dev": [], + "aliases": [], "minimum-stability": "stable", - "stability-flags": [ - - ], - "platform": [ - - ], - "platform-dev": [ - - ] + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] } diff --git a/src/Clue/GraphComposer.php b/src/Clue/GraphComposer.php index a48ba1b..cb222b0 100644 --- a/src/Clue/GraphComposer.php +++ b/src/Clue/GraphComposer.php @@ -2,8 +2,10 @@ namespace Clue; -use Fhaculty\Graph\GraphViz; use Fhaculty\Graph\Graph; +use Fhaculty\Graph\Attribute\AttributeAware; +use Fhaculty\Graph\Attribute\AttributeBagNamespaced; +use Graphp\GraphViz\GraphViz; class GraphComposer { @@ -13,96 +15,110 @@ class GraphComposer 'shape' => 'box', 'fontcolor' => '#314B5F' ); - + private $layoutVertexRoot = array( 'style' => 'filled, rounded, bold' ); - + private $layoutEdge = array( 'fontcolor' => '#767676', 'fontsize' => 10, 'color' => '#1A2833' ); - + private $layoutEdgeDev = array( 'style' => 'dashed' ); - + private $dependencyGraph; - - private $format = 'svg'; - + + /** + * @var GraphViz + */ + private $graphviz; + /** - * + * * @param string $dir + * @param GraphViz|null $graphviz */ - public function __construct($dir) + public function __construct($dir, GraphViz $graphviz = null) { + if ($graphviz === null) { + $graphviz = new GraphViz(); + } $analyzer = new \JMS\Composer\DependencyAnalyzer(); $this->dependencyGraph = $analyzer->analyze($dir); + $this->graphviz = $graphviz; } - + /** - * + * * @param string $dir * @return \Fhaculty\Graph\Graph */ public function createGraph() { $graph = new Graph(); - + foreach ($this->dependencyGraph->getPackages() as $package) { $name = $package->getName(); $start = $graph->createVertex($name, true); - + $label = $name; if ($package->getVersion() !== null) { $label .= ': ' . $package->getVersion(); } - - $start->setLayout(array('label' => $label) + $this->layoutVertex); - + + $this->setLayout($start, array('label' => $label) + $this->layoutVertex); + foreach ($package->getOutEdges() as $requires) { $targetName = $requires->getDestPackage()->getName(); $target = $graph->createVertex($targetName, true); - + $label = $requires->getVersionConstraint(); - - $edge = $start->createEdgeTo($target)->setLayout(array('label' => $label) + $this->layoutEdge); - + + $edge = $start->createEdgeTo($target); + $this->setLayout($edge, array('label' => $label) + $this->layoutEdge); + if ($requires->isDevDependency()) { - $edge->setLayout($this->layoutEdgeDev); + $this->setLayout($edge, $this->layoutEdgeDev); } } } - $graph->getVertex($this->dependencyGraph->getRootPackage()->getName())->setLayout($this->layoutVertexRoot); - + $root = $graph->getVertex($this->dependencyGraph->getRootPackage()->getName()); + $this->setLayout($root, $this->layoutVertexRoot); + return $graph; } - + + private function setLayout(AttributeAware $entity, array $layout) + { + $bag = new AttributeBagNamespaced($entity->getAttributeBag(), 'graphviz.'); + $bag->setAttributes($layout); + + return $entity; + } + public function displayGraph() { $graph = $this->createGraph(); - - $graphviz = new GraphViz($graph); - $graphviz->setFormat($this->format); - $graphviz->display(); + + $this->graphviz->display($graph); } - + public function getImagePath() { $graph = $this->createGraph(); - - $graphviz = new GraphViz($graph); - $graphviz->setFormat($this->format); - - return $graphviz->createImageFile(); + + return $this->graphviz->createImageFile($graph); } - + public function setFormat($format) { - $this->format = $format; + $this->graphviz->setFormat($format); + return $this; } } diff --git a/tests/GraphComposerTest.php b/tests/GraphComposerTest.php index e7fa486..90d0e22 100644 --- a/tests/GraphComposerTest.php +++ b/tests/GraphComposerTest.php @@ -14,4 +14,41 @@ public function testCreateGraph() $this->assertInstanceOf('Fhaculty\Graph\Graph', $graph); $this->assertTrue(count($graph->getVertices()) > 0); } + + public function testWillDisplayGraph() + { + $dir = __DIR__ . '/../'; + + $graphviz = $this->getMock('Graphp\GraphViz\GraphViz'); + $graphviz->expects($this->once())->method('display'); + + $graphComposer = new Clue\GraphComposer($dir, $graphviz); + $graphComposer->displayGraph(); + } + + public function testWillWriteTemporaryGraph() + { + $dir = __DIR__ . '/../'; + + $graphviz = $this->getMock('Graphp\GraphViz\GraphViz'); + $graphviz->expects($this->once())->method('createImageFile')->will($this->returnValue('test.png')); + + $graphComposer = new Clue\GraphComposer($dir, $graphviz); + $ret = $graphComposer->getImagePath(); + + $this->assertEquals('test.png', $ret); + } + + public function testWillSetFormat() + { + $dir = __DIR__ . '/../'; + + $graphviz = $this->getMock('Graphp\GraphViz\GraphViz'); + $graphviz->expects($this->once())->method('setFormat')->with($this->equalTo('gif')); + + $graphComposer = new Clue\GraphComposer($dir, $graphviz); + $ret = $graphComposer->setFormat('gif'); + + $this->assertEquals($graphComposer, $ret); + } }