Test Failed
Push — master ( 359bf7...72eda2 )
by Emmanuel
02:11
created

RoboFile::gitVerifyBranchIsMaster()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 0
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
        // Verify everything is pulled
127
        $this->say('Need to implement a check to make sure everyhting has been pulled');
128
129
        $version = null;
130
        $currentVersion = \Edyan\Neuralyzer\Console\Application::VERSION;
131
        while (empty($version)) {
132
            $version = $this->ask("Whats the version number ? (current : $currentVersion)");
133
        }
134
        $versionDesc = null;
135
        while (empty($versionDesc)) {
136
            $versionDesc = $this->ask('Describe your release');
137
        }
138
139
        $this->say("Preparing version $version");
140
141
        // Patch the right files
142
        $this->taskReplaceInFile(__DIR__ . '/src/Console/Application.php')
143
             ->from("const VERSION = '$currentVersion';")
144
             ->to("const VERSION = '$version';")
145
             ->run();
146
147
        $this->phar();
148
149
        // Commit a bump version
150
        $this->taskGitStack()
151
             ->add(__DIR__ . '/src/Console/Application.php')
152
             ->add(__DIR__ . '/neuralyzer.phar')
153
             ->commit("Bump version $version")
154
             ->push('origin', 'master')
155
             ->tag($version)
156
             ->push('origin', $version)
157
             ->run();
158
159
        // Create a release
160
        $this->taskGitHubRelease($version)
161
             ->uri('edyan/neuralyzer')
162
             ->description($versionDesc)
163
             ->run();
164
165
        $this->say('Release ready, you can push');
166
    }
167
168
169
    private function setupDocker(
170
        string $php = '7.1',
171
        string $dbType = 'mysql',
172
        int $wait = 10
173
    ) {
174
        $this->destroyDocker();
175
176
        if (!in_array($dbType, ['mysql', 'postgres', 'sqlsrv'])) {
177
            throw new \InvalidArgumentException('Database can be only mysql, postgres or sqlsrv');
178
        }
179
180
        $this->startDb($dbType);
181
        $this->say("Waiting $wait seconds $dbType to start");
182
        sleep($wait);
183
        // Now create a DB For SQL Server as there is no option in the docker image
184
        if ($dbType === 'sqlsrv') {
185
            $this->createSQLServerDB();
186
        }
187
188
        $this->startPHP($php, $dbType);
189
    }
190
191
    private function startDb($type)
192
    {
193
        $image = $type;
194
        if ($type === 'sqlsrv') {
195
            $image = 'microsoft/mssql-server-linux:2017-latest';
196
        }
197
198
        $dbCt = $this->taskDockerRun($image)->detached()->name('robo_db')->option('--rm');
199
        if ($type === 'mysql') {
200
            $dbCt = $dbCt->env('MYSQL_ROOT_PASSWORD', 'rootRoot44root')->env('MYSQL_DATABASE', 'test_db');
201
        } elseif ($type === 'postgres') {
202
            $dbCt = $dbCt->env('POSTGRES_PASSWORD', 'rootRoot44root')->env('POSTGRES_DB', 'test_db');
203
        } elseif ($type === 'sqlsrv') {
204
            $dbCt = $dbCt->env('ACCEPT_EULA', 'Y')->env('SA_PASSWORD', 'rootRoot44root');
205
        }
206
207
        $dbCt->run();
208
    }
209
210
211
    private function createSQLServerDB()
212
    {
213
        $createSqlQuery = '/opt/mssql-tools/bin/sqlcmd -U sa -P rootRoot44root ';
214
        $createSqlQuery.= '-S localhost -Q "CREATE DATABASE test_db"';
215
        $this->taskDockerExec('robo_db')
216
             ->interactive()
217
             ->exec($this->taskExec($createSqlQuery))
218
             ->run();
219
    }
220
221
222
    private function startPHP(string $version, string $dbType)
223
    {
224
        if (!in_array($version, ['7.1', '7.2'])) {
225
            throw new \InvalidArgumentException('PHP Version must be 7.1 or 7.2');
226
        }
227
228
        $dbUser = 'root';
229
        if ($dbType === 'postgres') {
230
            $dbUser = 'postgres';
231
        } elseif ($dbType === 'sqlsrv') {
232
            $dbUser = 'sa';
233
        }
234
235
        $this->taskDockerRun('edyan/php:' . $version . '-sqlsrv')
236
            ->detached()->name('robo_php')->option('--rm')
237
            ->env('FPM_UID', getmyuid())->env('FPM_GID', getmygid())
238
            ->env('DB_HOST', 'robo_db')->env('DB_DRIVER', $dbType)
239
            ->env('DB_PASSWORD', 'rootRoot44root')->env('DB_USER', $dbUser)
240
            ->volume(__DIR__, '/var/www/html')
241
            ->link('robo_db', 'robo_db')
242
            ->run();
243
    }
244
245
246
    private function destroyDocker()
247
    {
248
        $cts = ['robo_db', 'robo_php'];
249
        foreach ($cts as $ct) {
250
            $this->stopContainer($ct);
251
        }
252
    }
253
254
255
    private function stopContainer(string $ct)
256
    {
257
        $process = new \Symfony\Component\Process\Process("docker ps | grep $ct | wc -l");
258
        $process->run();
259
260
        if ((int)$process->getOutput() === 0) {
261
            return;
262
        }
263
264
        $this->say('Destroying container ' . $ct);
265
        $this->taskDockerStop($ct)->run();
266
    }
267
268
    private function gitVerifyBranchIsMaster()
269
    {
270
        $branch = $this->taskGitStack()
271
                        ->silent(true)
272
                        ->exec('rev-parse --abbrev-ref HEAD')
273
                        ->run();
274
        if ($branch->getMessage() !== 'master') {
275
            throw new \RuntimeException('You must be on the master branch');
276
        }
277
    }
278
279
    private function gitVerifyEverythingIsCommited()
280
    {
281
        $modifiedFiles = $this->taskGitStack()
282
                              ->silent(true)
283
                              ->exec('status -s')
284
                              ->run();
285
        if (!empty($modifiedFiles->getMessage())) {
286
            throw new \RuntimeException('Some files have not been commited yet');
287
        }
288
    }
289
290
    private function gitVerifyBranchIsUpToDate()
291
    {
292
        $modifiedFiles = $this->taskGitStack()
293
                              ->silent(true)
294
                              ->exec('fetch --dry-run')
295
                              ->run();
296
        if (!empty($modifiedFiles->getMessage())) {
297
            throw new \RuntimeException('Your local repo is not up to date, run "git pull"');
298
        }
299
    }
300
301
302
}
303