Compare commits

..

No commits in common. "e1dfdc65f26776952316bcefe68a50998778f8a6" and "6ab4ce942b467a684ec46071b0b386847fa069f7" have entirely different histories.

12 changed files with 150 additions and 211 deletions

View file

@ -1,30 +0,0 @@
name: Deploy
on:
push:
branches:
- master
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
with:
path: vendor
key: ${{ runner.os }}-node-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-node-
- name: Build and push Docker images
uses: docker/build-push-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
repository: pmsipilot/docker-compose-viz
tag_with_ref: true

View file

@ -1,43 +0,0 @@
name: Test
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Validate composer.json
run: composer validate --ansi --strict
- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
with:
path: vendor
key: ${{ runner.os }}-node-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
if: steps.composer-cache.outputs.cache-hit != 'true'
run: composer install --prefer-dist --no-progress --no-suggest
- name: Unit tests
run: composer run ut
- name: Coding style
run: composer run cst
- name: Build and push Docker images
uses: docker/build-push-action@v1
with:
push: false

11
.php_cs
View file

@ -1,18 +1,15 @@
<?php <?php
$finder = PhpCsFixer\Finder::create() use PhpCsFixer as CS;
$finder = CS\Finder::create()
->in(__DIR__.DIRECTORY_SEPARATOR.'src') ->in(__DIR__.DIRECTORY_SEPARATOR.'src')
->in(__DIR__.DIRECTORY_SEPARATOR.'spec') ->in(__DIR__.DIRECTORY_SEPARATOR.'spec')
; ;
return (new PhpCsFixer\Config()) return CS\Config::create()
->setRules([ ->setRules([
'@PSR2' => true,
'@Symfony' => true, '@Symfony' => true,
'array_syntax' => ['syntax' => 'short'],
'no_useless_else' => true,
'no_useless_return' => true,
'ordered_class_elements' => true,
]) ])
->setFinder($finder) ->setFinder($finder)
; ;

54
.travis.yml Normal file
View file

@ -0,0 +1,54 @@
language: php
sudo: required
services:
- docker
php:
- 7.0
- 7.1
- 7.2
- nightly
env:
matrix:
- COMPOSERFLAGS=
- COMPOSERFLAGS=--prefer-lowest
- COMPOSERFLAGS=--prefer-stable
global:
# DOCKER_EMAIL
- secure: JAbpFtQJovMT1IqHJmSlVI3xQpLUoqDlbYXUgExK99dH7+GH78Rd6CgjCo5fDAw5KW4zBoTJut7BWv+qdF1j9qpUEXlxB6dEwKdLHCCM8M9p+BddkaZUWF9kG+4pC1h6AeDeWi7Q77TzrOX7VAP1UubFOPItRNayF99zCJH6ioh8qnHNi2XHedIagMW4PGLp6HmTuyhzdF6RVEXcCos2fpkx5wzcjALb/ffN8A0dqtfELRvs6bjaQZ1ktmNjd3fSnQOtGO14VOei8E58e4roZNdDHMoIxzeqaM+bphsTZvHne4DAZEn3wU2iguzXLZMCAgF336Inu+t2Rjv4UDLcPeppMrYA+02Ww0kbCXcIQx4Og0Un54SY5qdIHZtnTXA+SAFr+5r+T80p29Tlp9cUfxaHWFynDEEDWx7minAATweSQU50ipPnAkge1WY/ADSN1EARqM2GYVQYLvddIaTSIbnq37MnlncWL+jkcQ0cL83xidYd7JnQ7/gZJf9MzeZzMVXrY+2VYL1WOrv1uwmVi30bpQss1D7IVVtN5iBlB2ciph+iHdvkhv6f8ji9xZmWkotfDzsRoZg7csDAVgliz55QkJYKeWDoiW7kb1i+pIsgmrdEonPMg7NHjSqIIkrwI89016Tsx4LH1t2sRRYW8Z7wuVhW3VcJD+CnkhAWvLc=
# DOCKER_USER
- secure: "bdD/Sg7IvpY/qLBK8KiaMBihGx00sj+K3+qHnHoqzqqzF6NjZFgfeJfhvVRLz84JPxTqDOcISwAfCvrV/cmtQkFVI7UP5Xg2GniTH8VGJxhBQxCmqLGd1tOLR9PPGtEh4HcjybGcOcIE3zn0xHhTwgS6jLxrrwPeapDAc+BYJcbbyrT1tjy5mv+wR3HmB2p5oiRhUL3P6u1+ND/j2oDZDoSllNRs+5jTiSXToIlXjICr6f8bey5DfOpGEAnopMXqSQmcf92C9dixfWprk0KE2MvELbE4hWtuu44FPLJcXbrMunKpFOiN1IfIxU2CXjlYpG9vcroJe3hZWpXG9ZY9nn5KDv+6H48zu+CQgZx0uobBaNmVFOXxiqDElb/kjjF6+Xx55JxGuRpcsGNdsbqU6qwTJmgeBv1UPLGste3BHY5dQkf10QbxXJmHgF1GQihS5mjpf1cobNMra0JxIFDUfpedB3cnFoM+masxKY6fexu9hXb3d5Yi7DKsHA2JUGayVCaGjcJEYYBzNLlNs9NbMcQHqfQ6a90HM1yH11DKMPWEGkvp7+M1ixjOUpTYng5yrOhgl624LDsNu/NwadtKTrk3wO9liyOJgojTUvbpVlB9potFf8vtX8JhKqGyOcMgaOx8VZt+gIL1W25hHtmEYglsfkEze3fOwWW8o4CBI2E="
# DOCKER_PASS
- secure: "BqpmNofWU38cV3eUT9Hm9wxiiRlp1LKl1JQBxvsYng/dk4L7ONiBVsrG6T7nYhkTktWc/II4ZAoQ7AGHN42W1quzSmc6d0fszQ7uTwNobfFQu2JzFNkhyP9D6b0v8uXhT8n6TPqOGgoJUcguStvasG3TuZwn7+PhwjyVfnzf+DhyaXjCljMatg7ekL0JDPGdAz/SQhuBiwk2xlZtxtEokNy7IVr9VcMi2O0nG3LMhCl1sQjo3JKBxPsalQi78dShDUHcazAE68T7M1FjAZCJYia902FMDWiIuujLamq+NpDgEKB3aLCLwF/o3j8z3ekPrk2v9Zokz+t36cQ2BmPpwqFfhvPdUv9tj9bi7Qv2R4NKreX8TWB8KB5afSVWiKfufWV5hp5KfwEmcLBc/hQdjRIwzDqVPK/fyy/GJ5fT4X5kz+YYLQEFxeWPtxL+OpQUXx2P5iDhx5qz173lO4h1WX4vEQ3p4aFbfnNREUDPGYsMJo6flm5Azq8F0qh065sxPldKunr9H4fAXrFzqMJnTepReEGPNJRn35TLl08RI7GTp0hKxlaycsu+c2Qz0/GcKbODWf5w24d/pxrOMM9KmJpDZTBm9bWiZlRbbZm1OnK0PiaRi9ft44Em5NYTFVvuWL2M2tIyGObI3kquKTkANvrSuPTofJ0JawXg2YBKOH8="
matrix:
exclude:
- php: 7.0
env: COMPOSERFLAGS=
- php: 7.1
env: COMPOSERFLAGS=--prefer-lowest
- php: 7.2
env: COMPOSERFLAGS=--prefer-lowest
- php: nightly
env: COMPOSERFLAGS=--prefer-lowest
allow_failures:
- php: nightly
script:
- make test
deploy:
- provider: script
script: ci/deploy.sh
on:
php: 7.1
all_branches: master
- provider: script
script: ci/deploy.sh
on:
php: 7.1
tags: true

View file

@ -1,16 +1,4 @@
FROM php:7.4-alpine as builder FROM php:7.1-alpine
COPY composer.json /dcv/composer.json
COPY composer.lock /dcv/composer.lock
WORKDIR /dcv
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
php composer-setup.php && \
php -r "unlink('composer-setup.php');" && \
php composer.phar install --prefer-dist
FROM php:7.4-alpine
RUN apk update && \ RUN apk update && \
apk add graphviz ttf-dejavu && \ apk add graphviz ttf-dejavu && \
@ -20,7 +8,7 @@ RUN apk update && \
COPY bin/ /dcv/bin COPY bin/ /dcv/bin
COPY src/ /dcv/src COPY src/ /dcv/src
COPY --from=builder /dcv/vendor /dcv/vendor COPY vendor/ /dcv/vendor
RUN chmod +x /dcv/bin/dcv RUN chmod +x /dcv/bin/dcv

View file

@ -1,5 +1,5 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2020 PMSIpilot Copyright (c) 2016 PMSIpilot
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the documentation files (the "Software"), to deal in the Software without restriction, including without limitation the

View file

@ -12,23 +12,29 @@ docker: docker.lock
test: vendor unit cs test: vendor unit cs
unit: vendor unit: vendor
$(COMPOSER) run ut $(PHP) bin/kahlan --pattern='*.php' --reporter=verbose --persistent=false --cc=true
cs: cs:
$(COMPOSER) run cst $(PHP) bin/php-cs-fixer fix --dry-run
fix-cs: fix-cs:
$(COMPOSER) run cs $(PHP) bin/php-cs-fixer fix
clean: clean:
rm -rf vendor/ rm -rf vendor/
docker.lock: Dockerfile bin/entrypoint.sh vendor src/application.php src/functions.php docker.lock: Dockerfile bin/entrypoint.sh vendor src/application.php src/functions.php
$(COMPOSER) dump-autoload --classmap-authoritative
$(DOCKER) build -t $(DCV_IMAGE_NAME) . $(DOCKER) build -t $(DCV_IMAGE_NAME) .
touch docker.lock touch docker.lock
ifndef COMPOSERFLAGS
vendor: composer.lock vendor: composer.lock
$(COMPOSER) install --prefer-dist $(COMPOSER) install --prefer-dist
else
vendor: composer.lock
$(COMPOSER) update $(COMPOSERFLAGS)
endif
composer.lock: composer.json composer.lock: composer.json
$(COMPOSER) update $(COMPOSERFLAGS) $(COMPOSER) update $(COMPOSERFLAGS)

View file

@ -1,5 +1,7 @@
# `docker-compose-viz` # `docker-compose-viz`
[![Build Status](https://img.shields.io/travis/pmsipilot/docker-compose-viz/master.svg?style=flat-square)](https://travis-ci.org/pmsipilot/docker-compose-viz)
[![StyleCI](https://styleci.io/repos/65026022/shield)](https://styleci.io/repos/65026022)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/pmsipilot/docker-compose-viz.svg)](http://isitmaintained.com/project/pmsipilot/docker-compose-viz "Average time to resolve an issue") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/pmsipilot/docker-compose-viz.svg)](http://isitmaintained.com/project/pmsipilot/docker-compose-viz "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/pmsipilot/docker-compose-viz.svg)](http://isitmaintained.com/project/pmsipilot/docker-compose-viz "Percentage of issues still open") [![Percentage of issues still open](http://isitmaintained.com/badge/open/pmsipilot/docker-compose-viz.svg)](http://isitmaintained.com/project/pmsipilot/docker-compose-viz "Percentage of issues still open")
[![Docker Stars](https://img.shields.io/docker/stars/pmsipilot/docker-compose-viz.svg?style=flat)](https://hub.docker.com/r/pmsipilot/docker-compose-viz/) [![Docker Stars](https://img.shields.io/docker/stars/pmsipilot/docker-compose-viz.svg?style=flat)](https://hub.docker.com/r/pmsipilot/docker-compose-viz/)
@ -11,11 +13,8 @@
Considering the current working directory is where your `docker-compose.yml` file is located: Considering the current working directory is where your `docker-compose.yml` file is located:
```bash ```
docker run --rm -it --name dcv -v $(pwd):/input pmsipilot/docker-compose-viz render -m image docker-compose.yml docker run --rm -it --name dcv -v $(pwd):/input pmsipilot/docker-compose-viz render -m image docker-compose.yml
# PowerShell
docker run --rm -it --name dcv -v ${pwd}:/input pmsipilot/docker-compose-viz render -m image docker-compose.yml
``` ```
This will generate the `docker-compose.png` file in the current working directory. This will generate the `docker-compose.png` file in the current working directory.
@ -25,7 +24,7 @@ This will generate the `docker-compose.png` file in the current working director
Before you start, make sure you have: Before you start, make sure you have:
* [Composer](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx) installed, * [Composer](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx) installed,
* [PHP 7.2](http://php.net/downloads.php#v7.2.32) (at least) installed, * [PHP 7](http://php.net/downloads.php#v7.0.9) installed,
* GraphViz installed (see below for a guide on how to install it) * GraphViz installed (see below for a guide on how to install it)
``` ```
@ -176,14 +175,7 @@ digraph G {
![display renderer](resources/display.png) ![display renderer](resources/display.png)
### Troubleshooting
#### Getting "failed to open stream: Permission denied"?
Make sure the target directory is writeable by the user in the Docker container.
Or create a writeable directory first. See [workaround #41](https://github.com/pmsipilot/docker-compose-viz/issues/41#issuecomment-483384999)
## License ## License
The MIT License (MIT) The MIT License (MIT)
Copyright ® 2020 PMSIpilot Copyright (c) 2016 PMSIpilot

View file

@ -2,15 +2,15 @@
"name": "pmsipilot/docker-compose-viz", "name": "pmsipilot/docker-compose-viz",
"description": "Docker compose graph visualization", "description": "Docker compose graph visualization",
"require": { "require": {
"php": "^7.2", "php": "^7",
"symfony/yaml": "^3.1 || ^4", "symfony/yaml": "^3.1 || ^4",
"symfony/console": "^3.1", "symfony/console": "^3.1",
"clue/graph": "^0.9", "clue/graph": "^0.9",
"graphp/graphviz": "^0.2" "graphp/graphviz": "^0.2"
}, },
"require-dev": { "require-dev": {
"friendsofphp/php-cs-fixer": "^2", "crysalead/kahlan": "^2.5.4",
"kahlan/kahlan": "^4.7" "friendsofphp/php-cs-fixer": "^2"
}, },
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
@ -25,9 +25,7 @@
"PMSIpilot\\DockerComposeViz\\": "src/" "PMSIpilot\\DockerComposeViz\\": "src/"
} }
}, },
"scripts": { "config": {
"cs": "php-cs-fixer fix", "bin-dir": "bin/"
"cst": "php-cs-fixer fix --dry-run",
"ut": "kahlan --grep='*.php' --reporter=verbose --persistent=false"
} }
} }

112
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "883183cc51537213776e61c66e969e5a", "content-hash": "e5370b9d4f890699543b1dbd6ba801de",
"packages": [ "packages": [
{ {
"name": "clue/graph", "name": "clue/graph",
@ -626,6 +626,58 @@
], ],
"time": "2020-06-04T11:16:35+00:00" "time": "2020-06-04T11:16:35+00:00"
}, },
{
"name": "crysalead/kahlan",
"version": "2.5.8",
"source": {
"type": "git",
"url": "https://github.com/kahlan/kahlan.git",
"reference": "4fad70f5a81698fe6cae725b21bb08c4aa677788"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/kahlan/kahlan/zipball/4fad70f5a81698fe6cae725b21bb08c4aa677788",
"reference": "4fad70f5a81698fe6cae725b21bb08c4aa677788",
"shasum": ""
},
"require": {
"php": ">=5.4"
},
"bin": [
"bin/kahlan"
],
"type": "library",
"autoload": {
"psr-4": {
"Kahlan\\": "src/"
},
"files": [
"src/init.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "CrysaLEAD"
}
],
"description": "Behavior-Driven Development (BDD) library.",
"keywords": [
"BDD",
"Behavior-Driven Development",
"Monkey Patching",
"TDD",
"mock",
"stub",
"testing",
"unit test"
],
"abandoned": "kahlan/kahlan",
"time": "2016-09-29T01:40:20+00:00"
},
{ {
"name": "doctrine/annotations", "name": "doctrine/annotations",
"version": "1.10.3", "version": "1.10.3",
@ -848,60 +900,6 @@
"description": "A tool to automatically fix PHP code style", "description": "A tool to automatically fix PHP code style",
"time": "2020-06-27T23:57:46+00:00" "time": "2020-06-27T23:57:46+00:00"
}, },
{
"name": "kahlan/kahlan",
"version": "4.7.5",
"source": {
"type": "git",
"url": "https://github.com/kahlan/kahlan.git",
"reference": "c529ef24201053ba76d3c8c3531acd76b629ce87"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/kahlan/kahlan/zipball/c529ef24201053ba76d3c8c3531acd76b629ce87",
"reference": "c529ef24201053ba76d3c8c3531acd76b629ce87",
"shasum": ""
},
"require": {
"php": ">=5.5"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.4"
},
"bin": [
"bin/kahlan"
],
"type": "library",
"autoload": {
"psr-4": {
"Kahlan\\": "src/"
},
"files": [
"src/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "CrysaLEAD"
}
],
"description": "The PHP Test Framework for Freedom, Truth and Justice.",
"keywords": [
"BDD",
"Behavior-Driven Development",
"Monkey Patching",
"TDD",
"mock",
"stub",
"testing",
"unit test"
],
"time": "2020-04-25T21:27:19+00:00"
},
{ {
"name": "paragonie/random_compat", "name": "paragonie/random_compat",
"version": "v9.99.99", "version": "v9.99.99",
@ -1720,10 +1718,10 @@
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": [], "stability-flags": [],
"prefer-stable": false, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": "^7.2" "php": "^7"
}, },
"platform-dev": [] "platform-dev": []
} }

View file

@ -12,8 +12,7 @@ $application->register('render')
->addOption('override', null, Console\Input\InputOption::VALUE_REQUIRED, 'Tag of the override file to use', 'override') ->addOption('override', null, Console\Input\InputOption::VALUE_REQUIRED, 'Tag of the override file to use', 'override')
->addOption('output-file', 'o', Console\Input\InputOption::VALUE_REQUIRED, 'Path to a output file (Only for "dot" and "image" output format)') ->addOption('output-file', 'o', Console\Input\InputOption::VALUE_REQUIRED, 'Path to a output file (Only for "dot" and "image" output format)')
->addOption('output-format', 'm', Console\Input\InputOption::VALUE_REQUIRED, 'Output format (one of: "dot", "image", "display", "graphviz")', 'display') ->addOption('output-format', 'm', Console\Input\InputOption::VALUE_REQUIRED, 'Output format (one of: "dot", "image", "display")', 'display')
->addOption('graphviz-output-format', null, Console\Input\InputOption::VALUE_REQUIRED, 'GraphViz Output format (see `man dot` for details)', 'svg')
->addOption('only', null, Console\Input\InputOption::VALUE_IS_ARRAY | Console\Input\InputOption::VALUE_REQUIRED, 'Display a graph only for a given services') ->addOption('only', null, Console\Input\InputOption::VALUE_IS_ARRAY | Console\Input\InputOption::VALUE_REQUIRED, 'Display a graph only for a given services')
->addOption('force', 'f', Console\Input\InputOption::VALUE_NONE, 'Overwrites output file if it already exists') ->addOption('force', 'f', Console\Input\InputOption::VALUE_NONE, 'Overwrites output file if it already exists')
@ -40,7 +39,7 @@ $application->register('render')
$outputFile = $input->getOption('output-file') ?: getcwd().DIRECTORY_SEPARATOR.'docker-compose.'.('dot' === $outputFormat ? $outputFormat : 'png'); $outputFile = $input->getOption('output-file') ?: getcwd().DIRECTORY_SEPARATOR.'docker-compose.'.('dot' === $outputFormat ? $outputFormat : 'png');
$onlyServices = $input->getOption('only'); $onlyServices = $input->getOption('only');
if (false === in_array($outputFormat, ['dot', 'image', 'display', 'graphviz'])) { if (false === in_array($outputFormat, ['dot', 'image', 'display'])) {
throw new Console\Exception\InvalidArgumentException(sprintf('Invalid output format "%s". It must be one of "dot", "image" or "display".', $outputFormat)); throw new Console\Exception\InvalidArgumentException(sprintf('Invalid output format "%s". It must be one of "dot", "image" or "display".', $outputFormat));
} }
@ -142,13 +141,6 @@ $application->register('render')
$renderer = new GraphViz(); $renderer = new GraphViz();
$renderer->display($graph); $renderer->display($graph);
break; break;
case 'graphviz':
$renderer = new GraphViz();
$format = $input->getOption('graphviz-output-format');
file_put_contents($outputFile, $renderer->setFormat($format)->createImageData($graph));
break;
} }
}); });

View file

@ -226,8 +226,7 @@ function makeVerticesAndEdges(Graph $graph, array $services, array $volumes, arr
if (false === ((bool) ($flags & WITHOUT_NETWORKS))) { if (false === ((bool) ($flags & WITHOUT_NETWORKS))) {
foreach ($networks as $network => $definition) { foreach ($networks as $network => $definition) {
addNetwork( addNetwork(
$graph, $graph, 'net: '.$network,
'net: '.$network,
isset($definition['external']) && true === $definition['external'] ? 'external_network' : 'network' isset($definition['external']) && true === $definition['external'] ? 'external_network' : 'network'
); );
} }
@ -237,17 +236,15 @@ function makeVerticesAndEdges(Graph $graph, array $services, array $volumes, arr
addService($graph, $service); addService($graph, $service);
if (isset($definition['extends'])) { if (isset($definition['extends'])) {
if (isset($definition['extends']['file'])) { $configuration = readConfiguration(dirname($path).DIRECTORY_SEPARATOR.$definition['extends']['file']);
$configuration = readConfiguration(dirname($path).DIRECTORY_SEPARATOR.$definition['extends']['file']); $extendedServices = fetchServices($configuration);
$extendedServices = fetchServices($configuration); $extendedVolumes = fetchVolumes($configuration);
$extendedVolumes = fetchVolumes($configuration); $extendedNetworks = fetchVolumes($configuration);
$extendedNetworks = fetchNetworks($configuration);
$graph = makeVerticesAndEdges($graph, $extendedServices, $extendedVolumes, $extendedNetworks, dirname($path).DIRECTORY_SEPARATOR.$definition['extends']['file'], $flags); $graph = makeVerticesAndEdges($graph, $extendedServices, $extendedVolumes, $extendedNetworks, dirname($path).DIRECTORY_SEPARATOR.$definition['extends']['file'], $flags);
}
addRelation( addRelation(
addService($graph, $definition['extends']['service']), addService($graph, $definition['extends']['service']),
$graph->getVertex($service), $graph->getVertex($service),
'extends' 'extends'
); );
@ -309,7 +306,7 @@ function makeVerticesAndEdges(Graph $graph, array $services, array $volumes, arr
$container = $volume['target']; $container = $volume['target'];
$attr = !empty($volume['read-only']) ? 'ro' : ''; $attr = !empty($volume['read-only']) ? 'ro' : '';
} else { } else {
list($host, $container, $attr) = explodeVolumeMapping($volume); list($host, $container, $attr) = explodeMapping($volume);
} }
$serviceVolumes[$container] = [$host, $attr]; $serviceVolumes[$container] = [$host, $attr];
@ -506,23 +503,13 @@ function explodeMapping($mapping): array
$parts = explode(':', $mapping); $parts = explode(':', $mapping);
$parts[1] = $parts[1] ?? $parts[0]; $parts[1] = $parts[1] ?? $parts[0];
return [$parts[0], $parts[1]]; $subparts = array_values(array_filter(explode('/', $parts[1])));
}
/** if (count($subparts) > 2) {
* @internal $subparts = [$parts[1], $parts[2] ?? null];
* }
* @param string $mapping A docker mapping (<from>[:<to>])
*
* @return array An 2 or 3 items array containing the parts of the mapping.
* If the mapping does not specify a second part, the first one will be repeated
*/
function explodeVolumeMapping($mapping): array
{
$parts = explode(':', $mapping);
$parts[1] = $parts[1] ?? $parts[0];
return [$parts[0], $parts[1], $parts[2] ?? null]; return [$parts[0], $subparts[0], $subparts[1] ?? null];
} }
/** /**