Compiler::compile()   B
last analyzed

Complexity

Conditions 6
Paths 32

Size

Total Lines 73

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 73
rs 7.9668
c 0
b 0
f 0
cc 6
nc 32
nop 1

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
3
/*
4
 * This file is part of Bowerphp.
5
 *
6
 * (c) Massimiliano Arione <[email protected]>
7
 * (c) Mauro D'Alatri <[email protected]>
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace Bowerphp;
14
15
use Symfony\Component\Finder\Finder;
16
17
/**
18
 * The Compiler class compiles Bower into a phar.
19
 */
20
class Compiler
21
{
22
    /**
23
     * @var bool
24
     */
25
    private $gz;
26
27
    /**
28
     * @param bool $gz
29
     */
30
    public function __construct($gz = false)
31
    {
32
        $this->gz = $gz;
33
    }
34
35
    /**
36
     * Compiles bower into a single phar file
37
     *
38
     * @throws \RuntimeException
39
     * @param  string            $pharFile The full path to the file to create
40
     */
41
    public function compile($pharFile = 'bowerphp.phar')
42
    {
43
        if (file_exists($pharFile)) {
44
            unlink($pharFile);
45
        }
46
47
        $phar = new \Phar($pharFile, 0, 'bowerphp.phar');
48
        $phar->setSignatureAlgorithm(\Phar::SHA1);
49
50
        $phar->startBuffering();
51
52
        $finder = new Finder();
53
        $finder->files()
54
            ->ignoreVCS(true)
55
            ->name('*.php')
56
            ->notName('Compiler.php')
57
            ->notName('ClassLoader.php')
58
            ->in(__DIR__ . '/..')
59
        ;
60
61
        foreach ($finder as $file) {
62
            $this->addFile($phar, $file);
63
        }
64
65
        $finder = new Finder();
66
        $finder->files()
67
            ->ignoreVCS(true)
68
            ->name('*.php')
69
            ->name('*.pem')
70
            ->name('*.pem.md5')
71
            ->exclude('Tests')
72
            ->in(__DIR__ . '/../../vendor/symfony/')
73
            ->in(__DIR__ . '/../../vendor/guzzle/guzzle/src/')
74
            ->in(__DIR__ . '/../../vendor/ircmaxell/password-compat/lib/')
75
            ->in(__DIR__ . '/../../vendor/paragonie/random_compat/lib/')
76
            ->in(__DIR__ . '/../../vendor/knplabs/github-api/lib/')
77
            ->in(__DIR__ . '/../../vendor/samsonasik/package-versions/src/PackageVersions/')
78
            ->in(__DIR__ . '/../../vendor/vierbergenlars/php-semver/src/vierbergenlars/LibJs/')
79
            ->in(__DIR__ . '/../../vendor/vierbergenlars/php-semver/src/vierbergenlars/SemVer/')
80
            ->in(__DIR__ . '/../../vendor/hamcrest/hamcrest-php/hamcrest/')
81
        ;
82
83
        foreach ($finder as $file) {
84
            $this->addFile($phar, $file);
85
        }
86
87
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/autoload.php'));
88
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/autoload_psr4.php'));
89
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/autoload_files.php'));
90
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/autoload_namespaces.php'));
91
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/autoload_classmap.php'));
92
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/autoload_real.php'));
93
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/autoload_static.php'));
94
        if (file_exists(__DIR__ . '/../../vendor/composer/include_paths.php')) {
95
            $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/include_paths.php'));
96
        }
97
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/ClassLoader.php'));
98
        $this->addBin($phar);
99
100
        // Stubs
101
        $phar->setStub($this->getStub());
102
103
        $phar->stopBuffering();
104
105
        if ($this->gz) {
106
            $phar->compressFiles(\Phar::GZ);
107
        }
108
109
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../LICENSE'), false);
110
111
        unset($phar);
112
        chmod('bowerphp.phar', 0700);
113
    }
114
115
    /**
116
     * @param \Phar        $phar
117
     * @param \SplFileInfo $file
118
     * @param bool         $strip
119
     */
120
    private function addFile(\Phar $phar, \SplFileInfo $file, $strip = true)
121
    {
122
        $path = strtr(str_replace(dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR, '', $file->getRealPath()), '\\', '/');
123
124
        $content = file_get_contents($file);
125
        if ($strip) {
126
            $content = $this->stripWhitespace($content);
127
        } elseif ('LICENSE' === basename($file)) {
128
            $content = "\n" . $content . "\n";
129
        }
130
131
        $phar->addFromString($path, $content);
132
    }
133
134
    /**
135
     * @param \Phar $phar
136
     */
137
    private function addBin(\Phar $phar)
138
    {
139
        $content = file_get_contents(__DIR__ . '/../../bin/bowerphp');
140
        $content = preg_replace('{^#!/usr/bin/env php\s*}', '', $content);
141
        $phar->addFromString('bin/bowerphp', $content);
142
    }
143
144
    /**
145
     * Removes whitespace from a PHP source string while preserving line numbers.
146
     *
147
     * @param  string $source A PHP string
148
     * @return string The PHP string with the whitespace removed
149
     */
150
    private function stripWhitespace($source)
151
    {
152
        if (!function_exists('token_get_all')) {
153
            return $source;
154
        }
155
156
        $output = '';
157
        foreach (token_get_all($source) as $token) {
158
            if (is_string($token)) {
159
                $output .= $token;
160
            } elseif (in_array($token[0], [T_COMMENT, T_DOC_COMMENT], true)) {
161
                $output .= str_repeat("\n", substr_count($token[1], "\n"));
162
            } elseif (T_WHITESPACE === $token[0]) {
163
                // reduce wide spaces
164
                $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]);
165
                // normalize newlines to \n
166
                $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace);
167
                // trim leading spaces
168
                $whitespace = preg_replace('{\n +}', "\n", $whitespace);
169
                $output .= $whitespace;
170
            } else {
171
                $output .= $token[1];
172
            }
173
        }
174
175
        return $output;
176
    }
177
178
    /**
179
     * @return string
180
     */
181
    private function getStub()
182
    {
183
        $stub = <<<'EOF'
184
#!/usr/bin/env php
185
<?php
186
/*
187
 * This file is part of Bowerphp.
188
 *
189
 * (c) Massimiliano Arione <[email protected]>
190
 *     Mauro D'Alatri <[email protected]>
191
 *
192
 * For the full copyright and license information, please view
193
 * the license that is located at the bottom of this file.
194
 */
195
196
Phar::mapPhar('bowerphp.phar');
197
198
EOF;
199
200
        return $stub . <<<'EOF'
201
require 'phar://bowerphp.phar/bin/bowerphp';
202
203
__HALT_COMPILER();
204
EOF;
205
    }
206
}
207