Completed
Push — master ( 023e21...5ec956 )
by Guillaume
07:09
created

Compiler::loadVersion()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 21
rs 9.0534
cc 4
eloc 14
nc 4
nop 0
1
<?php
2
3
namespace Hogosha\Monitor\Compiler;
4
5
use Symfony\Component\Finder\Finder;
6
use Symfony\Component\Process\Process;
7
8
/**
9
 *
10
 * @author Guillaume Cavana <[email protected]>
11
 */
12
class Compiler
13
{
14
    protected $version;
15
16
    /**
17
     * Compile.
18
     *
19
     */
20
    public function compile()
21
    {
22
        $pharFilePath = dirname(__FILE__).'/../../build/monitor.phar';
23
        if (file_exists($pharFilePath)) {
24
            unlink($pharFilePath);
25
        }
26
27
        $this->loadVersion();
28
29
        $phar = new \Phar($pharFilePath, 0, 'monitor.phar');
30
        $phar->setSignatureAlgorithm(\Phar::SHA1);
31
32
        $phar->startBuffering();
33
        $root = __DIR__.'/../..';
34
35
        $finder = new Finder();
36
        $finder->files()
37
            ->ignoreVCS(true)
38
            ->name('*.php')
39
            ->name('LICENSE')
40
            ->notName('Compiler.php')
41
            ->exclude('Tests')
42
            ->exclude('tests')
43
            ->exclude('docs')
44
            ->in($root.'/src')
45
            ->in($root.'/vendor/guzzlehttp')
46
            ->in($root.'/vendor/webmozart')
47
            ->in($root.'/vendor/psr')
48
            ->in($root.'/vendor/guzzle')
49
            ->in($root.'/vendor/symfony')
50
        ;
51
52
        foreach ($finder as $file) {
53
            $this->addFile($phar, $file);
54
        }
55
56
        $this->addFile($phar, new \SplFileInfo($root.'/vendor/autoload.php'));
57
        $this->addFile($phar, new \SplFileInfo($root.'/vendor/composer/autoload_namespaces.php'));
58
        $this->addFile($phar, new \SplFileInfo($root.'/vendor/composer/autoload_psr4.php'));
59
        $this->addFile($phar, new \SplFileInfo($root.'/vendor/composer/autoload_classmap.php'));
60
        $this->addFile($phar, new \SplFileInfo($root.'/vendor/composer/autoload_files.php'));
61
        $this->addFile($phar, new \SplFileInfo($root.'/vendor/composer/autoload_real.php'));
62
63
        if (file_exists($root.'/vendor/composer/include_paths.php')) {
64
            $this->addFile($phar, new \SplFileInfo($root.'/vendor/composer/include_paths.php'));
65
        }
66
        $this->addFile($phar, new \SplFileInfo($root.'/vendor/composer/ClassLoader.php'));
67
68
        $binContent = file_get_contents($root.'/bin/monitor');
69
        $binContent = preg_replace('{^#!/usr/bin/env php\s*}', '', $binContent);
70
        $phar->addFromString('bin/monitor', $binContent);
71
72
        // Stubs
73
        $phar->setStub($this->getStub());
74
        $phar->stopBuffering();
75
        unset($phar);
76
    }
77
78
    protected function addFile(\Phar $phar, \SplFileInfo $file, $strip = true)
79
    {
80
        $path = str_replace(dirname(dirname(__DIR__)).DIRECTORY_SEPARATOR, '', $file->getRealPath());
81
        $content = file_get_contents($file);
82
        if ($strip) {
83
            $content = self::stripWhitespace($content);
84
        } elseif ('LICENSE' === basename($file)) {
85
            $content = "\n".$content."\n";
86
        }
87
88
        if ($path === 'src/Monitor.php') {
89
            $content = str_replace('@package_version@', $this->version, $content);
90
        }
91
92
        $phar->addFromString($path, $content);
93
    }
94
95
    /**
96
     * @param string $source A PHP string
97
     *
98
     * @return string The PHP string with the whitespace removed
99
     */
100
    public static function stripWhitespace($source)
101
    {
102
        if (!function_exists('token_get_all')) {
103
            return $source;
104
        }
105
        $output = '';
106
        foreach (token_get_all($source) as $token) {
107
            if (is_string($token)) {
108
                $output .= $token;
109
            } elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
110
                $output .= str_repeat("\n", substr_count($token[1], "\n"));
111
            } elseif (T_WHITESPACE === $token[0]) {
112
                // reduce wide spaces
113
                $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]);
114
                // normalize newlines to \n
115
                $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace);
116
                // trim leading spaces
117
                $whitespace = preg_replace('{\n +}', "\n", $whitespace);
118
                $output .= $whitespace;
119
            } else {
120
                $output .= $token[1];
121
            }
122
        }
123
124
        return $output;
125
    }
126
127
128
    protected function getStub()
129
    {
130
        return <<<'EOF'
131
#!/usr/bin/env php
132
<?php
133
/*
134
 * This file is part of the Visithor package.
135
 *
136
 * For the full copyright and license information, please view the LICENSE
137
 * file that was distributed with this source code.
138
 *
139
 * Feel free to edit as you please, and have fun.
140
 *
141
 */
142
Phar::mapPhar('monitor.phar');
143
144
require 'phar://monitor.phar/bin/monitor';
145
__HALT_COMPILER();
146
EOF;
147
    }
148
149
150
    /**
151
     * Load versions
152
     */
153
    private function loadVersion()
154
    {
155
        $process = new Process('git log --pretty="%H" -n1 HEAD', __DIR__);
156
        if ($process->run() !== 0) {
157
            throw new \RuntimeException('Can\'t run git log. You must ensure to run compile from visithor git repository clone and that git binary is available.');
158
        }
159
        $this->version = trim($process->getOutput());
160
161
        $process = new Process('git log -n1 --pretty=%ci HEAD', __DIR__);
162
        if ($process->run() !== 0) {
163
            throw new \RuntimeException('Can\'t run git log. You must ensure to run compile from visithor git repository clone and that git binary is available.');
164
        }
165
        $date = new \DateTime(trim($process->getOutput()));
166
        $date->setTimezone(new \DateTimeZone('UTC'));
167
        $this->versionDate = $date->format('Y-m-d H:i:s');
0 ignored issues
show
Bug introduced by
The property versionDate does not seem to exist. Did you mean version?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
168
169
        $process = new Process('git describe --tags HEAD');
170
        if ($process->run() === 0) {
171
            $this->version = trim($process->getOutput());
172
        }
173
    }
174
}
175