Passed
Push — master ( 8c031b...c762e9 )
by Emmanuel
02:46 queued 27s
created

RoboFile.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * This is project's console commands configuration for Robo task runner.
4
 *
5
 * @see http://robo.li/
6
 */
7
8
class RoboFile extends \Robo\Tasks
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
9
{
10
    /**
11
     * A test command just to make sure robo works on that computer
12
     */
13
    public function dockertest()
14
    {
15
        $this->stopOnFail(true);
16
17
        $this->taskDockerStop('robo_test')->run();
18
19
        $this->taskDockerRun('edyan/php:7.1')
20
             ->name('robo_test')
21
             ->detached()
22
             ->option('--rm')
23
             ->run();
24
25
        $this->taskDockerExec('robo_test')
26
             ->interactive()
27
             ->exec($this->taskExec('php -v'))
28
             ->run();
29
30
        $this->taskDockerStop('robo_test')->run();
31
    }
32
33
34
    /**
35
     * Run All Unit Test
36
     * @param  array  $opts
37
     */
38
    public function test(
39
        $opts = ['php' => '7.1', 'db' => 'mysql', 'keep-cts' => false, 'wait' => 5]
40
    ) {
41
        $this->stopOnFail(true);
42
43
        $this->setupDocker($opts['php'], $opts['db'], $opts['wait']);
44
45
        // Run the tests
46
        $this->taskDockerExec('robo_php')
47
            ->interactive()
48
            ->option('--user', 'www-data')
49
            ->exec($this->taskExec('/bin/bash -c "cd /var/www/html ; vendor/bin/phpunit"'))
50
            ->run();
51
52
        if ($opts['keep-cts'] === false) {
53
            $this->destroyDocker();
54
        }
55
    }
56
57
58
    /**
59
     * Build an executable phar
60
     */
61
    public function phar()
62
    {
63
        // Create a collection builder to hold the temporary
64
        // directory until the pack phar task runs.
65
        $collection = $this->collectionBuilder();
66
        $workDir = $collection->tmpDir();
67
        $buildDir = "$workDir/neuralyzer";
68
69
        $prepTasks = $this->collectionBuilder();
70
        $preparationResult = $prepTasks
71
            ->taskFilesystemStack()
72
                ->mkdir($workDir)
73
                ->taskCopyDir([__DIR__ . '/src' => $buildDir . '/src'])
74
            ->taskFilesystemStack()
75
                ->copy(__DIR__ . '/bin/neuralyzer', $buildDir . '/bin/neuralyzer')
76
                ->copy(__DIR__ . '/composer.json', $buildDir . '/composer.json')
77
                ->copy(__DIR__ . '/composer.lock', $buildDir . '/composer.lock')
78
                ->copy(__DIR__ . '/LICENSE', $buildDir . '/LICENSE')
79
                ->copy(__DIR__ . '/README.md', $buildDir . '/README.md')
80
81
            ->taskComposerInstall()
82
                ->dir($buildDir)
83
                ->noDev()
84
                ->noScripts()
85
                ->printOutput(true)
86
                ->optimizeAutoloader()
87
                ->run();
88
89
        // Exit if the preparation step failed
90
        if (!$preparationResult->wasSuccessful()) {
91
            return $preparationResult;
92
        }
93
94
        // Decide which files we're going to pack
95
        $files = \Symfony\Component\Finder\Finder::create()->ignoreVCS(true)
96
            ->files()
97
            ->name('*.php')
98
            ->name('*.exe') // for 1symfony/console/Resources/bin/hiddeninput.exe
99
            ->path('src')
100
            ->path('vendor')
101
            ->notPath('docs')
102
            ->notPath('/vendor\/.*\/[Tt]est/')
103
            ->in(is_dir($buildDir) ? $buildDir : __DIR__);
104
105
        // Build the phar
106
        return $collection
107
            ->taskPackPhar('neuralyzer.phar')
108
                ->compress()
109
                ->addFile('bin/neuralyzer', 'bin/neuralyzer')
110
                ->addFiles($files)
111
                ->executable('bin/neuralyzer')
112
            ->taskFilesystemStack()
113
                ->chmod(__DIR__ . '/neuralyzer.phar', 0755)
114
            ->run();
115
    }
116
117
118
    public function release()
119
    {
120
        $this->stopOnFail(true);
121
122
        $this->gitVerifyEverythingIsCommited();
123
        $this->gitVerifyBranchIsMaster();
124
        $this->gitVerifyBranchIsUpToDate();
125
126
        $version = null;
127
        $currentVersion = \Edyan\Neuralyzer\Console\Application::VERSION;
128
        while (empty($version)) {
129
            $version = $this->ask("Whats the version number ? (current : $currentVersion)");
130
        }
131
        $versionDesc = null;
132
        while (empty($versionDesc)) {
133
            $versionDesc = $this->ask('Describe your release');
134
        }
135
136
        $this->say("Preparing version $version");
137
138
        // Patch the right files
139
        $this->taskReplaceInFile(__DIR__ . '/src/Console/Application.php')
140
             ->from("const VERSION = '$currentVersion';")
141
             ->to("const VERSION = '$version';")
142
             ->run();
143
144
        $this->phar();
145
146
        // Commit a bump version
147
        $this->taskGitStack()
148
             ->add(__DIR__ . '/src/Console/Application.php')
149
             ->add(__DIR__ . '/neuralyzer.phar')
150
             ->commit("Bump version $version")
151
             ->push('origin', 'master')
152
             ->tag($version)
153
             ->push('origin', $version)
154
             ->run();
155
156
        // Create a release
157
        $this->taskGitHubRelease($version)
158
             ->uri('edyan/neuralyzer')
159
             ->description($versionDesc)
160
             ->run();
161
162
        $this->say('Release ready, you can push');
163
    }
164
165
166
    private function setupDocker(
167
        string $php = '7.1',
168
        string $dbType = 'mysql',
169
        int $wait = 10
170
    ) {
171
        $this->destroyDocker();
172
173
        if (!in_array($dbType, ['mysql', 'pgsql', 'sqlsrv'])) {
174
            throw new \InvalidArgumentException('Database can be only mysql, pgsql or sqlsrv');
175
        }
176
177
        $this->startDb($dbType);
178
        $this->say("Waiting $wait seconds $dbType to start");
179
        sleep($wait);
180
        // Now create a DB For SQL Server as there is no option in the docker image
181
        if ($dbType === 'sqlsrv') {
182
            $this->createSQLServerDB();
183
        }
184
185
        $this->startPHP($php, $dbType);
186
    }
187
188
    private function startDb($type)
189
    {
190
        $image = $type;
191
        if ($type === 'sqlsrv') {
192
            $image = 'microsoft/mssql-server-linux:2017-latest';
193
        } elseif ($type === 'pgsql') {
194
            $image = 'postgres';
195
        }
196
197
        $dbCt = $this->taskDockerRun($image)->detached()->name('robo_db')->option('--rm');
198
        if ($type === 'mysql') {
199
            $dbCt = $dbCt->env('MYSQL_ROOT_PASSWORD', 'rootRoot44root')->env('MYSQL_DATABASE', 'test_db');
200
        } elseif ($type === 'pgsql') {
201
            $dbCt = $dbCt->env('POSTGRES_PASSWORD', 'rootRoot44root')->env('POSTGRES_DB', 'test_db');
202
        } elseif ($type === 'sqlsrv') {
203
            $dbCt = $dbCt->env('ACCEPT_EULA', 'Y')->env('SA_PASSWORD', 'rootRoot44root');
204
        }
205
206
        $dbCt->run();
207
    }
208
209
210
    private function createSQLServerDB()
211
    {
212
        $createSqlQuery = '/opt/mssql-tools/bin/sqlcmd -U sa -P rootRoot44root ';
213
        $createSqlQuery.= '-S localhost -Q "CREATE DATABASE test_db"';
214
        $this->taskDockerExec('robo_db')
215
             ->interactive()
216
             ->exec($this->taskExec($createSqlQuery))
217
             ->run();
218
    }
219
220
221
    private function startPHP(string $version, string $dbType)
222
    {
223
        if (!in_array($version, ['7.1', '7.2'])) {
224
            throw new \InvalidArgumentException('PHP Version must be 7.1 or 7.2');
225
        }
226
227
        $dbUser = 'root';
228
        if ($dbType === 'pgsql') {
229
            $dbUser = 'postgres';
230
        } elseif ($dbType === 'sqlsrv') {
231
            $dbUser = 'sa';
232
        }
233
234
        $this->taskDockerRun('edyan/php:' . $version . '-sqlsrv')
235
            ->detached()->name('robo_php')->option('--rm')
236
            ->env('FPM_UID', getmyuid())->env('FPM_GID', getmygid())
237
            ->env('DB_HOST', 'robo_db')->env('DB_DRIVER', 'pdo_' . $dbType)
238
            ->env('DB_PASSWORD', 'rootRoot44root')->env('DB_USER', $dbUser)
239
            ->volume(__DIR__, '/var/www/html')
240
            ->link('robo_db', 'robo_db')
241
            ->run();
242
    }
243
244
245
    private function destroyDocker()
246
    {
247
        $cts = ['robo_db', 'robo_php'];
248
        foreach ($cts as $ct) {
249
            $this->stopContainer($ct);
250
        }
251
    }
252
253
254
    private function stopContainer(string $ct)
255
    {
256
        $process = new \Symfony\Component\Process\Process("docker ps | grep $ct | wc -l");
257
        $process->run();
258
259
        if ((int)$process->getOutput() === 0) {
260
            return;
261
        }
262
263
        $this->say('Destroying container ' . $ct);
264
        $this->taskDockerStop($ct)->run();
265
    }
266
267
    private function gitVerifyBranchIsMaster()
268
    {
269
        $branch = $this->taskGitStack()
270
                        ->silent(true)
271
                        ->exec('rev-parse --abbrev-ref HEAD')
272
                        ->run();
273
        if ($branch->getMessage() !== 'master') {
274
            throw new \RuntimeException('You must be on the master branch');
275
        }
276
    }
277
278
    private function gitVerifyEverythingIsCommited()
279
    {
280
        $modifiedFiles = $this->taskGitStack()
281
                              ->silent(true)
282
                              ->exec('status -s')
283
                              ->run();
284
        if (!empty($modifiedFiles->getMessage())) {
285
            throw new \RuntimeException('Some files have not been commited yet');
286
        }
287
    }
288
289
    private function gitVerifyBranchIsUpToDate()
290
    {
291
        $modifiedFiles = $this->taskGitStack()
292
                              ->silent(true)
293
                              ->exec('fetch --dry-run')
294
                              ->run();
295
        if (!empty($modifiedFiles->getMessage())) {
296
            throw new \RuntimeException('Your local repo is not up to date, run "git pull"');
297
        }
298
    }
299
300
301
}
302