GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( e11e84...669d0f )
by Sam
02:18
created

Module::createBuildContext()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 54
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 4.0065

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 54
ccs 25
cts 27
cp 0.9259
rs 9.0306
cc 4
eloc 31
nc 6
nop 0
crap 4.0065

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types=1);
3
4
namespace SamIT\Yii2\PhpFpm;
5
6
use Docker\Context\Context;
7
use Docker\Context\ContextBuilder;
8
use yii\base\InvalidConfigException;
9
use yii\mutex\Mutex;
10
11
class Module extends \yii\base\Module
12
{
13
14
    /**
15
     * @var bool Whether the container should attempt to run migrations on launch.
16
     */
17
    public $runMigrations = false;
18
19
    /**
20
     * @var bool whether migrations should acquire a lock.
21
     * It must be configured in the 'mutex' component of this module or the application
22
     * Note that this mutex must be shared between all instances of your application.
23
     * Consider using something like redis or mysql mutex.
24
     */
25
    public $migrationsUseMutex = true;
26
27
    /**
28
     * The variables will be populated via the pool config.
29
     * @var string[] List of required environment variables. If one is missing the container will exit.
30
     *
31
     */
32
    public $environmentVariables = [];
33
34
    /**
35
     * @var array Pool directives
36
     * @see http://php.net/manual/en/install.fpm.configuration.php
37
     *
38
     */
39
    public $poolConfig = [
40
        'user' => 'nobody',
41
        'group' => 'nobody',
42
        'listen' => 9000,
43
        'pm' => 'dynamic',
44
        'pm.max_children' => 40,
45
        'pm.start_servers' => 3,
46
        'pm.min_spare_servers' => 1,
47
        'pm.max_spare_servers' => 3,
48
        'access.log' => '/proc/self/fd/2',
49
        'clear_env' => 'yes',
50
51
    ];
52
53
    /**
54
     * @var array PHP configuration, supplied via php_admin_value in fpm config.
55
     */
56
    public $phpConfig = [
57
        'upload_max_filesize' => '20M',
58
        'post_max_size' => '25M'
59
    ];
60
61
    /**
62
     * @var array Global directives
63
     * @see http://php.net/manual/en/install.fpm.configuration.php
64
     *
65
     */
66
    public $fpmConfig = [
67
        'error_log' => '/proc/self/fd/2',
68
        'daemonize' => 'no',
69
    ];
70
71
    public $extensions = [
72
        'ctype',
73
        'gd',
74
        'iconv',
75
        'intl',
76
        'json',
77
        'mbstring',
78
        'session',
79
        'pdo_mysql',
80
        'session',
81
        'curl'
82
    ];
83
84
    /**
85
     * @var string The name of the created image.
86
     */
87
    public $image;
88
89
    /**
90
     * @var string The tag of the created image.
91
     */
92
    public $tag = 'latest';
93
94
    /**
95
     * @var bool wheter to push successful builds.
96
     */
97
    public $push = false;
98
99
    /**
100
     * @var string Location of composer.json / composer.lock
101
     */
102
    public $composerFilePath = '@app/../';
103
    /**
104
     * @return string A PHP-FPM config file.
105 4
     */
106
    protected function createFpmConfig()
107 4
    {
108
        $config = [];
109 4
        // Add global directives.
110 4
        if (!empty($this->fpmConfig)) {
111 4
            $config[] = '[global]';
112 4
            foreach ($this->fpmConfig as $key => $value) {
113
                $config[] = "$key = $value";
114
            }
115
        }
116
117 4
        // Add pool directives.
118 4
        $poolConfig = $this->poolConfig;
119 4
        foreach($this->phpConfig as $key => $value) {
120
            $poolConfig["php_admin_value[$key]"] = $value;
121
        }
122 4
123
        foreach($this->environmentVariables as $name) {
124
            $poolConfig["env[$name]"] = "$$name";
125
        }
126 4
127 4
        if (!empty($poolConfig)) {
128 4
            $config[] = '[www]';
129 4
            foreach ($poolConfig as $key => $value) {
130
                $config[] = "$key = $value";
131
            }
132
        }
133 4
134
        return \implode("\n", $config);
135
    }
136
137
    /**
138
     * @return string A shell script that checks for existence of (non-empty) variables and runs php-fpm.
139 4
     */
140
    protected function createEntrypoint(): string
141
    {
142 4
        // Get the route.
143
        $route = "{$this->getUniqueId()}/migrate/up";
144 4
        $script = "/project/{$this->getConsoleEntryScript()}";
145 4
        $result = [];
146
        $result[] = '#!/bin/sh';
147 4
        // Check for variables.
148
        foreach($this->environmentVariables as $name) {
149
            $result[] = \strtr('if [ -z "${name}" ]; then echo "Variable \${name} is required."; exit 1; fi', [
150
                '{name}' => $name
151
            ]);
152
        }
153 4
154
        if ($this->runMigrations) {
155
            $result[] = <<<SH
156
ATTEMPTS=0
157
while [ \$ATTEMPTS -lt 10 ]; do
158
  # First run migrations.
159
  $script $route --interactive=0
160
  if [ $? -eq 0 ]; then
161
    echo "Migrations done";
162
    break;
163
  fi
164
  echo "Failed to run migrations, retrying in 10s.";
165
  sleep 10;
166
  let ATTEMPTS=ATTEMPTS+1
167
done
168
169
if [ \$ATTEMPTS -gt 9 ]; then
170
  echo "Migrations failed.."
171
  exit 1;
172
fi
173
SH;
174
        }
175 4
176 4
        $result[] = 'exec php-fpm7 --force-stderr --fpm-config /php-fpm.conf';
177
        return \implode("\n", $result);
178
    }
179 4
180
    public function createBuildContext(): Context
181 4
    {
182 4
        $builder = new ContextBuilder();
183
184
        /**
185
         * BEGIN COMPOSER
186
         */
187 4
        $builder->from('composer');
188 4
        $builder->addFile('/build/composer.json', \Yii::getAlias($this->composerFilePath) .'/composer.json');
189 4
        if (\file_exists(\Yii::getAlias($this->composerFilePath) . '/composer.lock')) {
190 4
            $builder->addFile('/build/composer.lock', \Yii::getAlias($this->composerFilePath) . '/composer.lock');
191
        }
192
193 4
        $builder->run('cd /build && composer install --no-dev --no-autoloader --ignore-platform-reqs --prefer-dist -vvv && rm -rf /root/.composer');
194
195
196
        // Add the actual source code.
197 4
        $root = \Yii::getAlias('@app');
198 4
        if (!\is_string($root)) {
199
            throw new \Exception('Alias @app must be defined.');
200
        }
201 4
        $builder->addFile('/build/' . \basename($root), $root);
202 4
        $builder->run('cd /build && composer dumpautoload -o');
203
        /**
204
         * END COMPOSER
205
         */
206
207
208
        $builder->from('alpine:edge');
209 4
        $packages = [
210
            'php7',
211 4
            'php7-fpm',
212
            'tini',
213
            'ca-certificates'
214
        ];
215
        foreach ($this->extensions as $extension) {
216 4
            $packages[] = "php7-$extension";
217
        }
218
        $builder->run('apk add --update --no-cache ' . \implode(' ', $packages));
219 4
        $builder->volume('/runtime');
220 4
        $builder->copy('--from=0 /build', '/project');
221 4
        $builder->add('/entrypoint.sh', $this->createEntrypoint());
222 4
        $builder->run('chmod +x /entrypoint.sh');
223 4
        $builder->add('/php-fpm.conf', $this->createFpmConfig());
224 4
        $builder->run("php-fpm7 --force-stderr --fpm-config /php-fpm.conf -t");
225 4
        $builder->entrypoint('["/sbin/tini", "--", "/entrypoint.sh"]');
226 4
227
        // Test if we can run a console command.
228
        $script = "/project/{$this->getConsoleEntryScript()}";
229 4
        $builder->run("$script phpFpm/build/test-client");
230 4
231
232
        return $builder->getContext();
233 3
    }
234
235 3
    public function getLock(int $timeout = 0)
236 1
    {
237 1
        if ($this->has('mutex')) {
238 1
            $mutex = $this->get('mutex');
239
            if ($mutex instanceof Mutex
240 1
                && $mutex->acquire(__CLASS__, $timeout)
241
            ) {
242 1
                \register_shutdown_function(function() use ($mutex): void {
243 1
                    $mutex->release(__CLASS__);
244
                });
245
                return true;
246 3
            }
247
        }
248
        return false;
249
    }
250
251
    /**
252
     * @throws InvalidConfigException in case the app is not configured as expected
253
     * @return string the relative path of the (console) entry script with respect to the project (not app) root.
254
     */
255
    private function getConsoleEntryScript(): string
256
    {
257
        $full = \array_slice(\debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), -1)[0]['file'];
258
        $relative = \strtr($full, [\dirname(\Yii::getAlias('@app')) => '']);
259
        if ($relative === $full){
260
            throw new InvalidConfigException("The console entryscript must be located inside the @app directory.");
261
        }
262
        return \ltrim($relative, '/');
263
    }
264
}