Completed
Pull Request — master (#39)
by Aydin
02:30
created

E2EInstaller::exec()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace PackageVersionsTest;
4
5
use PHPUnit_Framework_TestCase;
6
use RecursiveCallbackFilterIterator;
7
use RecursiveDirectoryIterator;
8
use RecursiveIteratorIterator;
9
use SplFileInfo;
10
use ZipArchive;
11
12
/**
13
 * @author Aydin Hassan <[email protected]>
14
 */
15
class E2EInstaller extends PHPUnit_Framework_TestCase
16
{
17
    private $tempGlobalComposerHome;
18
    private $tempLocalComposerHome;
19
    private $tempArtifact;
20
21
    public function setUp()
22
    {
23
        $this->tempGlobalComposerHome = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/global';
24
        $this->tempLocalComposerHome = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/local';
25
        $this->tempArtifact = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/artifacts';
26
        mkdir($this->tempGlobalComposerHome, 0777, true);
27
        mkdir($this->tempLocalComposerHome, 0777, true);
28
        mkdir($this->tempArtifact, 0777, true);
29
30
        putenv('COMPOSER_HOME=' . $this->tempGlobalComposerHome);
31
    }
32
33
    public function tearDown()
34
    {
35
        $this->rmDir($this->tempGlobalComposerHome);
36
        $this->rmDir($this->tempLocalComposerHome);
37
        $this->rmDir($this->tempArtifact);
38
    }
39
40
    public function testGloballyInstalledPluginDoesNotGenerateVersionsForLocalProject()
41
    {
42
        $this->createPackageVersionsArtifact();
43
44
        file_put_contents($this->tempGlobalComposerHome . '/composer.json', json_encode([
45
            'name'         => 'package-versions/e2e-global',
46
            'require'      => [
47
                'ocramius/package-versions' => '1.0.0'
48
            ],
49
            'repositories' => [
50
                [
51
                    'packagist' => false,
52
                ],
53
                [
54
                    'type' => 'artifact',
55
                    'url' => $this->tempArtifact,
56
                ]
57
            ]
58
        ], JSON_PRETTY_PRINT));
59
60
        $this->exec(__DIR__ . '/../../vendor/bin/composer global update');
61
62
        $this->createArtifact();
63
        file_put_contents($this->tempLocalComposerHome . '/composer.json', json_encode([
64
            'name'         => 'package-versions/e2e-local',
65
            'require'      => [
66
                'test/package' => '2.0.0'
67
            ],
68
            'repositories' => [
69
                [
70
                    'packagist' => false,
71
                ],
72
                [
73
                    'type' => 'artifact',
74
                    'url' => $this->tempArtifact,
75
                ]
76
            ]
77
        ], JSON_PRETTY_PRINT));
78
79
        $this->execInDir('composer update -vvv', $this->tempLocalComposerHome);
80
81
        $this->assertFileNotExists($this->tempLocalComposerHome . '/vendor/ocramius/package-versions/src/PackageVersions/Versions.php');
82
    }
83
84
    private function createPackageVersionsArtifact()
85
    {
86
        $zip = new ZipArchive();
87
88
        $zip->open($this->tempArtifact . '/ocramius-package-versions-1.0.0.zip', ZipArchive::CREATE);
89
90
        $files = array_filter(
91
            iterator_to_array(new RecursiveIteratorIterator(
92
                new RecursiveCallbackFilterIterator(
93
                    new RecursiveDirectoryIterator(realpath(__DIR__ . '/../../'), RecursiveDirectoryIterator::SKIP_DOTS),
94
                    function (SplFileInfo $file) {
95
                        $filePath = substr($file->getRealPath(), strlen(realpath(__DIR__ . '/../../')) + 1);
96
97
                        if (substr($filePath, 0, 4) === '.git'
98
                            || substr($filePath, 0, 5) === '.idea'
99
                            || substr($filePath, 0, 6) === 'vendor'
100
                        ) {
101
                            return false;
102
                        }
103
104
                        return true;
105
                    }
106
                ),
107
                RecursiveIteratorIterator::LEAVES_ONLY
108
            )),
109
            function (SplFileInfo $file) {
110
                return !$file->isDir();
111
            }
112
        );
113
114
        array_walk(
115
            $files,
116
            function (SplFileInfo $file) use ($zip) {
117
                if ($file->getFilename() === 'composer.json') {
118
                    $contents = json_decode(file_get_contents($file->getRealPath()), true);
119
                    $contents['version'] = '1.0.0';
120
121
                    return $zip->addFromString('composer.json', json_encode($contents));
122
                }
123
124
                $zip->addFile(
125
                    $file->getRealPath(),
126
                    substr($file->getRealPath(), strlen(realpath(__DIR__ . '/../../')) + 1)
127
                );
128
            }
129
        );
130
131
        $zip->close();
132
    }
133
134
    private function createArtifact()
135
    {
136
        $zip = new ZipArchive();
137
138
        $zip->open($this->tempArtifact . '/test-package-2.0.0.zip', ZipArchive::CREATE);
139
        $zip->addFromString('composer.json', json_encode([
140
             'name'    => 'test/package',
141
             'version' => '2.0.0',
142
         ], JSON_PRETTY_PRINT)).
143
        $zip->close();
144
    }
145
146
    private function execInDir(string $command, string $dir) : array
147
    {
148
        $currentDir = getcwd();
149
        chdir($dir);
150
        $output = $this->exec($command);
151
        chdir($currentDir);
152
        return $output;
153
    }
154
155
    private function exec(string $command) : array
156
    {
157
        exec($command . ' 2> /dev/null', $output);
158
        return $output;
159
    }
160
161
    /**
162
     * @param string $directory
163
     *
164
     * @return void
165
     */
166
    private function rmDir(string $directory)
167
    {
168
        if (! is_dir($directory)) {
169
            unlink($directory);
170
171
            return;
172
        }
173
174
        array_map(
175
            function ($item) use ($directory) {
176
                $this->rmDir($directory . '/' . $item);
177
            },
178
            array_filter(
179
                scandir($directory),
180
                function (string $dirItem) {
181
                    return ! in_array($dirItem, ['.', '..'], true);
182
                }
183
            )
184
        );
185
186
        rmdir($directory);
187
    }
188
}
189