From 83ac0627639265ca0cd86a49b9cc6ac1f8425ba7 Mon Sep 17 00:00:00 2001 From: jubianchi Date: Sat, 6 Aug 2016 14:20:20 +0200 Subject: [PATCH] Display extended services --- CHANGELOG.md | 1 + README.md | 9 +++++++++ resources/extends.png | Bin 0 -> 15145 bytes src/application.php | 2 +- src/functions.php | 41 +++++++++++++++++++++++++++++++---------- 5 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 resources/extends.png diff --git a/CHANGELOG.md b/CHANGELOG.md index e67cfa3..0d1d68b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # `1.0.0` (unreleased) +* Display extended services as components with inverted arrows * Display services as components * Display volumes as folders * Display ports as circles diff --git a/README.md b/README.md index 76f21fc..39389b9 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,15 @@ Ports (from `services..ports`) are displayed as circle and are linked t If we look at the link between port `2480` and `orientdb`, it reads as follow: "traffic coming to host port `2480` will be routed to port `2480` of `orientdb`." If we look at the link between port `2580` and `elk`, it reads as follow: "traffix coming to host port `2580` will be routed to port `80` of `elk`." +### Extends + +Extended services (from `services..extends`) are displayed as components (just like normal services). The link between them and the extending services are +displayed as inverted arrows: + +![ports](resources/extends.png) + +If we look at the link between `mysql` and `db`, it reads as follow: "`mysql` extends service `db`". + ## Examples ### `dot` renderer diff --git a/resources/extends.png b/resources/extends.png new file mode 100644 index 0000000000000000000000000000000000000000..16579169b95a0e4e870a09e1ff4670c500f16917 GIT binary patch literal 15145 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 g_yRR^^l1dUKZwvze2l_dLEdT%j literal 0 HcmV?d00001 diff --git a/src/application.php b/src/application.php index 3a61d69..754c6f8 100644 --- a/src/application.php +++ b/src/application.php @@ -66,7 +66,7 @@ $application->register('render') } $graph = applyGraphvizStyle( - createGraph($services, $volumes, $networks, $input->getOption('no-volumes') === false), + createGraph($services, $volumes, $networks, $input->getOption('no-volumes') === false, $inputFile), $input->getOption('horizontal') ); diff --git a/src/functions.php b/src/functions.php index 02c72da..e4f32fa 100644 --- a/src/functions.php +++ b/src/functions.php @@ -79,16 +79,17 @@ function fetchNetworks(array $configuration) : array /** * @public * - * @param array $services Docker compose service definitions - * @param array $volumes Docker compose volume definitions - * @param array $networks Docker compose network definitions - * @param bool $withVolumes Create vertices and edges for volumes + * @param array $services Docker compose service definitions + * @param array $volumes Docker compose volume definitions + * @param array $networks Docker compose network definitions + * @param bool $withVolumes Create vertices and edges for volumes + * @param string $path Path of the current docker-compose configuration file * * @return Graph The complete graph for the given list of services */ -function createGraph(array $services, array $volumes, array $networks, bool $withVolumes = true) : Graph +function createGraph(array $services, array $volumes, array $networks, bool $withVolumes, string $path) : Graph { - return makeVerticesAndEdges(new Graph(), $services, $volumes, $networks, $withVolumes); + return makeVerticesAndEdges(new Graph(), $services, $volumes, $networks, $withVolumes, $path); } /** @@ -103,6 +104,7 @@ function applyGraphvizStyle(Graph $graph, bool $horizontal) : Graph { $graph = $graph->createGraphClone(); $graph->setAttribute('graphviz.graph.pad', '0.5'); + $graph->setAttribute('graphviz.graph.ratio', 'fill'); if ($horizontal === true) { $graph->setAttribute('graphviz.graph.rankdir', 'LR'); @@ -162,6 +164,12 @@ function applyGraphvizStyle(Graph $graph, bool $horizontal) : Graph case 'depends_on': $edge->setAttribute('graphviz.style', 'dotted'); break; + + case 'extends': + $edge->setAttribute('graphviz.dir', 'both'); + $edge->setAttribute('graphviz.arrowhead', 'inv'); + $edge->setAttribute('graphviz.arrowtail', 'dot'); + break; } if (($alias = $edge->getAttribute('docker_compose.alias')) !== null) { @@ -187,10 +195,8 @@ function applyGraphvizStyle(Graph $graph, bool $horizontal) : Graph * * @return Graph A copy of the input graph with vertices and edges for services */ -function makeVerticesAndEdges(Graph $graph, array $services, array $volumes, array $networks, bool $withVolumes) : Graph +function makeVerticesAndEdges(Graph $graph, array $services, array $volumes, array $networks, bool $withVolumes, $path) : Graph { - $graph = $graph->createGraphClone(); - if ($withVolumes === true) { foreach (array_keys($volumes) as $volume) { addVolume($graph, 'named: '.$volume); @@ -205,7 +211,22 @@ function makeVerticesAndEdges(Graph $graph, array $services, array $volumes, arr } foreach ($services as $service => $definition) { - $vertices[$service] = addService($graph, $service); + addService($graph, $service); + + if (isset($definition['extends'])) { + $configuration = readConfiguration(dirname($path).DIRECTORY_SEPARATOR.$definition['extends']['file']); + $extendedServices = fetchServices($configuration); + $extendedVolumes = fetchVolumes($configuration); + $extendedNetworks = fetchVolumes($configuration); + + $graph = makeVerticesAndEdges($graph, $extendedServices, $extendedVolumes, $extendedNetworks, $withVolumes, dirname($path).DIRECTORY_SEPARATOR.$definition['extends']['file']); + + addRelation( + addService($graph, $definition['extends']['service']), + $graph->getVertex($service), + 'extends' + ); + } foreach ($definition['links'] ?? [] as $link) { list($target, $alias) = explodeMapping($link);