Passed
Push — master ( 72fc34...cfd30c )
by Tom
02:20
created

Env::collectFiles()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 1
dl 0
loc 8
ccs 7
cts 7
cp 1
crap 3
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Runner;
6
use Ktomk\Pipelines\Cli\Args\Args;
7
use Ktomk\Pipelines\Cli\Args\Collector;
8
9
/**
10
 * Pipeline environment collaborator
11
 */
12
class Env
13
{
14
    /**
15
     * @var array pipelines (bitbucket) environment variables
16
     */
17
    private $vars;
18
19
    /**
20
     * collected arguments
21
     *
22
     * @var array
23
     */
24
    private $collected = array();
25
26
    /**
27
     * environment variables to inherit from
28
     *
29
     * @var array
30
     */
31
    private $inherit = array();
32
33
34
    /**
35
     * @var EnvResolver|null
36
     */
37
    private $resolver;
38
39
    /**
40
     * @param array|null $inherit
41
     * @return Env
42
     */
43 13
    public static function create(array $inherit = array())
44
    {
45 13
        $env = new Env();
46 13
        $env->initDefaultVars($inherit);
47
48 13
        return $env;
49
    }
50
51
    /**
52
     * Initialize default environment used in a Bitbucket Pipeline
53
     *
54
     * As the runner mimic some values, defaults are available
55
     *
56
     * @param array $inherit Environment variable store to inherit from
57
     */
58 16
    public function initDefaultVars(array $inherit)
59
    {
60 16
        $this->inherit = $inherit;
61
62
        $inheritable = array(
63 16
            'BITBUCKET_BOOKMARK' => null,
64
            'BITBUCKET_BRANCH' => null,
65 16
            'BITBUCKET_BUILD_NUMBER' => '0',
66 16
            'BITBUCKET_COMMIT' => '0000000000000000000000000000000000000000',
67 16
            'BITBUCKET_REPO_OWNER' => '' . $this->r($inherit['USER'], 'nobody'),
68 16
            'BITBUCKET_REPO_SLUG' => 'local-has-no-slug',
69
            'BITBUCKET_TAG' => null,
70 16
            'CI' => 'true',
71
            'PIPELINES_CONTAINER_NAME' => null,
72
            'PIPELINES_IDS' => null,
73
            'PIPELINES_PARENT_CONTAINER_NAME' => null,
74
        );
75
76
        $invariant = array(
77 16
            'PIPELINES_ID' => null,
78
        );
79
80 16
        foreach ($inheritable as $name => $value) {
81 16
            isset($inherit[$name]) ? $inheritable[$name] = $inherit[$name] : null;
82
        }
83
84 16
        $var = $invariant + $inheritable;
85 16
        ksort($var);
86
87 16
        $this->vars = $var;
88 16
    }
89
90
    /**
91
     * Map reference to environment variable setting
92
     *
93
     * Only add the BITBUCKET_BOOKMARK/_BRANCH/_TAG variable
94
     * if not yet set.
95
     *
96
     * @param Reference $ref
97
     */
98 2
    public function addReference(Reference $ref)
99
    {
100 2
        if (null === $type = $ref->getType()) {
101 1
            return;
102
        }
103
104
        $map = array(
105 2
            'bookmark' => 'BITBUCKET_BOOKMARK',
106
            'branch' => 'BITBUCKET_BRANCH',
107
            'tag' => 'BITBUCKET_TAG',
108
        );
109
110 2
        $var = $map[$type];
111
112 2
        if (!isset($this->vars[$var])) {
113 1
            $this->vars[$var] = $ref->getName();
114
        }
115 2
    }
116
117
    /**
118
     * @param string $name of container
119
     */
120 2
    public function setContainerName($name)
121
    {
122 2
        if (isset($this->vars['PIPELINES_CONTAINER_NAME'])) {
123 2
            $this->vars['PIPELINES_PARENT_CONTAINER_NAME']
124 2
                = $this->vars['PIPELINES_CONTAINER_NAME'];
125
        }
126
127 2
        $this->vars['PIPELINES_CONTAINER_NAME'] = $name;
128 2
    }
129
130 16
    private function r(&$v, $d)
131
    {
132 16
        if (isset($v)) {
133 1
            return $v;
134
        }
135
136 15
        unset($v);
137 15
        return $d;
138
    }
139
140
    /**
141
     * set the pipelines environment's running pipeline id
142
     *
143
     * @param string $id of pipeline, e.g. "default" or "branch/feature/*"
144
     * @return bool whether was used before (endless pipelines in pipelines loop)
145
     */
146 1
    public function setPipelinesId($id)
147
    {
148 1
        $list = (string)$this->getValue('PIPELINES_IDS');
149 1
        $hashes = preg_split('~\s+~', $list, -1, PREG_SPLIT_NO_EMPTY);
150 1
        $hashes = array_map('strtolower', /** @scrutinizer ignore-type */ $hashes);
151
152 1
        $idHash = md5($id);
153 1
        $hasId = in_array($idHash, $hashes, true);
154 1
        $hashes[] = $idHash;
155
156 1
        $this->vars['PIPELINES_ID'] = $id;
157 1
        $this->vars['PIPELINES_IDS'] = implode(' ', $hashes);
158
159 1
        return $hasId;
160
    }
161
162
    /**
163
     * @param string $option "-e" typically for Docker binary
164
     * @return array of options (from $option) and values, ['-e', 'val1', '-e', 'val2', ...]
165
     */
166 10
    public function getArgs($option)
167
    {
168 10
        $args = $this->collected;
169
170 10
        foreach ($this->getVarDefinitions() as $definition) {
171 10
            $args[] = $option;
172 10
            $args[] = $definition;
173
        }
174
175 10
        return $args;
176
    }
177
178
    /**
179
     * get a variables value or null if not set
180
     *
181
     * @param string $name
182
     * @return string|null
183
     */
184 4
    public function getValue($name)
185
    {
186 4
        return isset($this->vars[$name])
187 3
            ? $this->vars[$name]
188 4
            : null;
189
    }
190
191
    /**
192
     * collect option arguments
193
     *
194
     * those options to be passed to docker client, normally -e,
195
     * --env and --env-file.
196
     *
197
     * @param Args $args
198
     * @param string|string[] $option
199
     *
200
     * @throws \Ktomk\Pipelines\Cli\ArgsException
201
     */
202 1
    public function collect(Args $args, $option)
203
    {
204 1
        $collector = new Collector($args);
205 1
        $collector->collect($option);
206 1
        $this->collected = array_merge($this->collected, $collector->getArgs());
207
208 1
        $this->getResolver()->addArguments($collector);
209 1
    }
210
211 2
    public function collectFiles(array $paths)
212
    {
213 2
        $resolver = $this->getResolver();
214 2
        foreach ($paths as $path) {
215 2
            if ($resolver->addFileIfExists($path)) {
216 2
                $this->collected = array_merge(
217 2
                    $this->collected,
218 2
                    array('--env-file', $path)
219
                );
220
            }
221
        }
222 2
    }
223
224
    /**
225
     * @return array w/ a string variable definition (name=value) per value
226
     */
227 10
    private function getVarDefinitions()
228
    {
229 10
        $array = array();
230
231 10
        foreach ((array)$this->vars as $name => $value) {
232 10
            if (isset($value)) {
233 10
                $array[] = sprintf('%s=%s', $name, $value);
234
            }
235
        }
236
237 10
        return $array;
238
    }
239
240
    /**
241
     * @return EnvResolver
242
     */
243 4
    public function getResolver()
244
    {
245 4
        if (null === $this->resolver) {
246 4
            $this->resolver = new EnvResolver($this->inherit);
247
        }
248
249 4
        return $this->resolver;
250
    }
251
}
252