Passed
Push — master ( 0cfc7e...b88fc1 )
by Tom
03:33 queued 42s
created

EnvResolver::addDefinition()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 3
nop 1
dl 0
loc 18
ccs 10
cts 10
cp 1
crap 4
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Runner;
6
7
use InvalidArgumentException;
8
use Ktomk\Pipelines\Cli\Args\Args;
9
use Ktomk\Pipelines\Cli\Args\OptionFilterIterator;
10
11
/**
12
 * resolve environment variables against docker --env & --env-file arguments
13
 *
14
 * some string values in the bitbucket-pipelines.yml file might need resolution
15
 * against a part of the current host environment but only if set for the
16
 * container as well (--env-file, -e, --env)
17
 *
18
 * @package Ktomk\Pipelines\Runner
19
 */
20
class EnvResolver
21
{
22
23
    /**
24
     * @var array host environment (that exports)
25
     */
26
    private $environment;
27
28
29
    /**
30
     * @var array container environment (partial w/o bitbucket environment)
31
     */
32
    private $variables;
33
34
    /**
35
     * EnvResolver constructor.
36
     * @param array|string[] $environment host environment variables (strings)
37
     */
38 4
    public function __construct(array $environment)
39
    {
40 4
        $this->environment = array_filter($environment, 'is_string');
41 4
    }
42
43 1
    public function addArguments(Args $args)
44
    {
45 1
        $files = new OptionFilterIterator($args, 'env-file');
46 1
        foreach ($files->getArguments() as $file) {
47 1
            $this->addFile($file);
48
        }
49
50 1
        $definitions = new OptionFilterIterator($args, array('e', 'env'));
51 1
        foreach ($definitions->getArguments() as $definition) {
52 1
            $this->addDefinition($definition);
53
        }
54 1
    }
55
56
    /**
57
     * add a file (--env-file option)
58
     *
59
     * @param string $file path to file
60
     */
61 2
    public function addFile($file)
62
    {
63 2
        $lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
64 2
        if (false === $lines) {
65 1
            throw new InvalidArgumentException(sprintf(
66 1
                    "File read error: '%s'", $file
67
                )
68
            );
69
        }
70 1
        $definitions = preg_grep('~^(\s*#.*|\s*)$~', $lines, PREG_GREP_INVERT);
71 1
        foreach ($definitions as $definition) {
72 1
            $this->addDefinition($definition);
73
        }
74 1
    }
75
76
    /**
77
     * add a variable definition (-e, --env option)
78
     *
79
     * @param string $definition variable definition, either name only or w/ equal sign
80
     */
81 2
    public function addDefinition($definition)
82
    {
83 2
        $pattern = '~^([^$={}\\x0-\\x20\\x7f-\\xff-]+)(?:=(.*))?$~';
84
85 2
        $result = preg_match($pattern, $definition, $matches);
86 2
        if (0 === $result) {
87 1
            throw new InvalidArgumentException(sprintf(
88 1
                "Variable definition error: '%s'", $definition
89
            ));
90
        }
91
92 1
        list(, $name, $value) = $matches + array(2 => null);
93
94 1
        if (null === $value && isset($this->environment[$name])) {
95 1
            $value = $this->environment[$name];
96
        }
97
98 1
        $this->variables[$name] = $value;
99 1
    }
100
101
    /**
102
     * get value of variable
103
     *
104
     * @param string $name of variable to obtain value from
105
     * @return string|null value, null if unset
106
     */
107 1
    public function getValue($name)
108
    {
109 1
        return isset($this->variables[$name])
110 1
            ? $this->variables[$name]
111 1
            : null;
112
    }
113
}
114