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 ( 1f4b3f...0d920a )
by Sam
02:01
created

Module   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 259
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 88.16%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 6
dl 0
loc 259
ccs 67
cts 76
cp 0.8816
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A createFpmConfig() 0 22 4
A getConsoleEntryScript() 0 9 2
A __set() 0 8 2
A add() 0 7 2
A createEntrypoint() 0 48 3
B createBuildContext() 0 57 4
1
<?php
2
declare(strict_types=1);
3
4
namespace SamIT\Yii2\PhpFpm;
5
6
use SamIT\Docker\Context;
7
use yii\base\InvalidConfigException;
8
use yii\base\UnknownPropertyException;
9
use yii\helpers\ArrayHelper;
10
use yii\helpers\Console;
11
12
/**
13
 * Class Module
14
 * @package SamIT\Yii2\PhpFpm
15
 * @property-write string[] $additionalExtensions
16
 * @property-write string|int[] $additionalPoolConfig
17
 * @property-write string[] $additionalPhpConfig
18
 * @property-write string[] $additionalFpmConfig
19
 */
20
class Module extends \yii\base\Module
21
{
22
    /**
23
     * The variables will be written to /runtime/env.json as JSON, where your application can read them.
24
     * @var string[] List of required environment variables. If one is missing the container will exit.
25
     *
26
     */
27
    public $environmentVariables = [];
28
29
    /**
30
     * @var array Pool directives
31
     * @see http://php.net/manual/en/install.fpm.configuration.php
32
     *
33
     */
34
    public $poolConfig = [
35
        'user' => 'nobody',
36
        'group' => 'nobody',
37
        'listen' => 9000,
38
        'pm' => 'dynamic',
39
        'pm.max_children' => 40,
40
        'pm.start_servers' => 3,
41
        'pm.min_spare_servers' => 1,
42
        'pm.max_spare_servers' => 3,
43
        'access.log' => '/proc/self/fd/2',
44
        'clear_env' => 'yes',
45
        'catch_workers_output' => 'yes'
46
    ];
47
48
    /**
49
     * @var array PHP configuration, supplied via php_admin_value in fpm config.
50
     */
51
    public $phpConfig = [
52
        'upload_max_filesize' => '20M',
53
        'post_max_size' => '25M'
54
    ];
55
56
    /**
57
     * @var array Global directives
58
     * @see http://php.net/manual/en/install.fpm.configuration.php
59
     *
60
     */
61
    public $fpmConfig = [
62
        'error_log' => '/proc/self/fd/2',
63
        'daemonize' => 'no',
64
    ];
65
66
    /**
67
     * List of php extensions to install
68
     */
69
    public $extensions = [
70
        'ctype',
71
        'gd',
72
        'iconv',
73
        'intl',
74
        'json',
75
        'mbstring',
76
        'session',
77
        'pdo_mysql',
78
        'session',
79
        'curl'
80
    ];
81
82
    /**
83
     * @var string The name of the created image.
84
     */
85
    public $image;
86
87
    /**
88
     * @var string The tag of the created image.
89
     */
90
    public $tag = 'latest';
91
92
    /**
93
     * @var bool wheter to push successful builds.
94
     */
95
    public $push = false;
96
97
    /**
98
     * @var string Location of composer.json / composer.lock
99
     */
100
    public $composerFilePath = '@app/../';
101
102
    /**
103
     * @var string[] List of console commands that are executed upon container launch.
104
     */
105
    public $initializationCommands = [];
106
    /**
107
     * @return string A PHP-FPM config file.
108
     */
109 1
    protected function createFpmConfig()
110
    {
111 1
        $config = [];
112
        // Add global directives.
113 1
        $config[] = '[global]';
114 1
        foreach ($this->fpmConfig as $key => $value) {
115 1
            $config[] = "$key = $value";
116
        }
117
118
        // Add pool directives.
119 1
        $poolConfig = $this->poolConfig;
120 1
        foreach ($this->phpConfig as $key => $value) {
121 1
            $poolConfig["php_admin_value[$key]"] = $value;
122
        }
123
124 1
        $config[] = '[www]';
125 1
        foreach ($poolConfig as $key => $value) {
126 1
            $config[] = "$key = $value";
127
        }
128
129 1
        return \implode("\n", $config);
130
    }
131
132
    /**
133
     * @return string A shell script that checks for existence of (non-empty) variables and runs php-fpm.
134
     */
135 1
    protected function createEntrypoint(): string
136
    {
137
        // Get the route.
138 1
        $script = "/project/{$this->getConsoleEntryScript()}";
139 1
        $result = [];
140 1
        $result[] = '#!/bin/sh';
141
        // Check for variables.
142 1
        foreach ($this->environmentVariables as $name) {
143
            $result[] = \strtr('if [ -z "${name}" ]; then echo "Variable \${name} is required."; exit 1; fi', [
144
                '{name}' => $name
145
            ]);
146
        }
147
148
        // Check if runtime directory is writable.
149 1
        $result[] = <<<SH
150
su nobody -s /bin/touch /runtime/testfile && rm /runtime/testfile;
151
if [ $? -ne 0 ]; then
152
  echo Runtime directory is not writable;
153
  exit 1
154
fi
155
SH;
156
157
158
159
        // Check if runtime is a tmpfs.
160 1
        $message = Console::ansiFormat('/runtime should really be a tmpfs.', [Console::FG_RED]);
161 1
        $result[] = <<<SH
162 1
grep 'tmpfs /runtime' /proc/mounts;
163
if [ $? -ne 0 ]; then
164 1
  echo $message;
165
fi
166
SH;
167 1
        $result[] = <<<SH
168
su nobody -s /bin/touch /runtime/env.json
169
jq -n env > /runtime/env.json
170
if [ $? -ne 0 ]; then
171
  echo "failed to store env in /runtime/env.json";
172
  exit 1
173
fi
174
SH;
175
176
177 1
        foreach ($this->initializationCommands as $route) {
178
            $result[] = "$script $route --interactive=0 || exit";
179
        }
180 1
        $result[] = 'exec php-fpm7 --force-stderr --fpm-config /php-fpm.conf';
181 1
        return \implode("\n", $result);
182
    }
183
184
    /**
185
     * @param string $version This is stored in the VERSION environment variable.
186
     * @throws InvalidConfigException
187
     * @return Context
188
     */
189 1
    public function createBuildContext(string $version): Context
190
    {
191 1
        $root = \Yii::getAlias('@app');
192 1
        if (!\is_string($root)) {
193
            throw new \Exception('Alias @app must be defined.');
194
        }
195
196 1
        $context = new Context();
197
198
        /**
199
         * BEGIN COMPOSER
200
         */
201 1
        $context->command('FROM composer');
202 1
        $context->addFile('/build/composer.json', \Yii::getAlias($this->composerFilePath) .'/composer.json');
203
204 1
        if (\file_exists(\Yii::getAlias($this->composerFilePath) . '/composer.lock')) {
205 1
            $context->addFile('/build/composer.lock', \Yii::getAlias($this->composerFilePath) . '/composer.lock');
206
        }
207
208 1
        $context->run('composer global require hirak/prestissimo');
209
210 1
        $context->run('cd /build && composer install --no-dev --no-autoloader --ignore-platform-reqs --prefer-dist');
211
212
        // Add the actual source code.
213 1
        $context->addFile('/build/' . \basename($root), $root);
214 1
        $context->run('cd /build && composer dumpautoload -o --no-dev');
215
        /**
216
         * END COMPOSER
217
         */
218
219 1
        $context->from('php:7.4-fpm-alpine');
220 1
        $context->run('apk add --update --no-cache jq');
221 1
        $context->addUrl("/usr/local/bin/", "https://raw.githubusercontent.com/mlocati/docker-php-extension-installer/master/install-php-extensions");
222 1
        $context->run("chmod +x /usr/local/bin/install-php-extensions");
223 1
        $context->run('install-php-extensions ' . implode(' ', $this->extensions));
224 1
        $context->run('mkdir /runtime && chown nobody:nobody /runtime');
225 1
        $context->volume('/runtime');
226 1
        $context->copyFromLayer("/project", "0", "/build");
227
228 1
        $context->add('/entrypoint.sh', $this->createEntrypoint());
229
230 1
        $context->run('chmod +x /entrypoint.sh');
231
232 1
        $context->add('/php-fpm.conf', $this->createFpmConfig());
233
234 1
        $context->run("php-fpm --force-stderr --fpm-config /php-fpm.conf -t");
235
236 1
        $context->entrypoint(["/entrypoint.sh"]);
237
238 1
        $context->env('VERSION', $version);
239
        // Test if we can run a console command.
240 1
        if (\stripos($this->getConsoleEntryScript(), 'codecept') === false) {
241
            $script = "[ -f /project/{$this->getConsoleEntryScript()} ]";
242
            $context->run($script);
243
        }
244 1
        return $context;
245
    }
246
247
    /**
248
     * @throws InvalidConfigException in case the app is not configured as expected
249
     * @return string the relative path of the (console) entry script with respect to the project (not app) root.
250
     */
251 1
    public function getConsoleEntryScript(): string
252
    {
253 1
        $full = \array_slice(\debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), -1)[0]['file'];
254 1
        $relative = \strtr($full, [\dirname(\Yii::getAlias('@app')) => '']);
255 1
        if ($relative === $full) {
256
            throw new InvalidConfigException("The console entry script must be located inside the @app directory.");
257
        }
258 1
        return \ltrim($relative, '/');
259
    }
260
261
262 1
    public function __set($name, $value): void
263
    {
264 1
        if (\strncmp($name, 'additional', 10) === 0) {
265 1
            $this->add(\lcfirst(\substr($name, 10)), $value);
266
        } else {
267
            parent::__set($name, $value);
268
        }
269 1
    }
270
271 1
    private function add($name, array $value): void
272
    {
273 1
        if (!\property_exists($this, $name)) {
274
            throw new UnknownPropertyException("Unknown property $name");
275
        }
276 1
        $this->$name = ArrayHelper::merge($this->$name, $value);
277 1
    }
278
}
279