Compiler::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
1
<?php
2
3
namespace Assimtech\Tempo\Phar;
4
5
use Phar;
6
use Assimtech\Tempo\Node\Local;
7
use Symfony\Component\Finder\Finder;
8
use RuntimeException;
9
10
final class Compiler
11
{
12
    /**
13
     * @var string $pharFile
14
     */
15
    private $pharFile;
16
17
    /**
18
     * @var string $baseDir
19
     */
20
    private $baseDir;
21
22
    /**
23
     * @var \Phar $phar
24
     */
25
    private $phar;
26
27
    /**
28
     * @var \Assimtech\Tempo\Node\Local $local
29
     */
30
    private $local;
31
32
    /**
33
     * @param \Assimtech\Tempo\Node\Local $local
34
     */
35
    public function __construct(Phar $phar, Local $local)
36
    {
37
        $this->phar = $phar;
38
        $this->local = $local;
39
        $this->baseDir = realpath(__DIR__.'/../../');
40
    }
41
42
    /**
43
     * @throws \RuntimeException
44
     */
45
    public function compile()
46
    {
47
        $this->checkWorkingDirectory();
48
        $this->checkVersion();
49
50
        if (file_exists($this->pharFile)) {
51
            unlink($this->pharFile);
52
        }
53
54
        $this->phar->setSignatureAlgorithm(Phar::SHA1);
55
56
        $this->phar->startBuffering();
57
58
        $finder = new Finder();
59
        $finder->files()
60
            ->ignoreVCS(true)
61
            ->name('*.php')
62
            ->notName('Compiler.php')
63
            ->exclude('Test')
64
            ->in('vendor/composer')
65
            ->in('vendor/assimtech/sysexits')
66
            ->in('vendor/symfony/console')
67
            ->in('vendor/symfony/polyfill-mbstring')
68
            ->in('vendor/symfony/process')
69
            ->in('vendor/symfony/yaml')
70
            ->in('src')
71
        ;
72
        foreach ($finder as $file) {
73
            $this->phar->addFile($file);
74
        }
75
        $this->phar->addFile('vendor/autoload.php');
76
77
        // Add bin/tempo but without shebang
78
        $tempoBinContents = file_get_contents($this->baseDir.'/bin/tempo');
79
        $tempoBinPhar = preg_replace('{^#!/usr/bin/env php\s*}', '', $tempoBinContents);
80
        $this->phar->addFromString('bin/tempo', $tempoBinPhar);
81
82
        // Stubs
83
        $stub = file_get_contents(__DIR__.'/tempo.phar.stub');
84
        $this->phar->setStub($stub);
85
86
        $this->phar->stopBuffering();
87
    }
88
89
    private function checkWorkingDirectory()
90
    {
91
        // Check we are in the right place
92
        if (getcwd() !== $this->baseDir) {
93
            throw new RuntimeException(sprintf('Please run this from %s', $this->baseDir));
94
        }
95
96
        // Check we are in a clean git working directory
97
        $gitStatus = $this->local->run('git status --porcelain');
98
        if (!empty($gitStatus)) {
99
            throw new RuntimeException('Local copy unclean (see `git status`)');
100
        }
101
    }
102
103
    private function checkVersion()
104
    {
105
        $namerev = trim($this->local->run('git name-rev --tags --name-only HEAD'));
106
        if ($namerev === 'undefined') {
107
            throw new RuntimeException('You must be on a tagged version to compile a phar');
108
        }
109
        $version = preg_replace('/\^.*$/', '', $namerev);
110
111
        $tempoBinContents = file_get_contents($this->baseDir.'/bin/tempo');
112
        $matches = array();
113
        if (!preg_match('/Application\(\'tempo\', \'(.+)\'\);$/m', $tempoBinContents, $matches)) {
114
            throw new RuntimeException('bin/tempo must contain "Application(\'tempo\', \'<version>\');"');
115
        }
116
117
        if ($matches[1] !== $version) {
118
            throw new RuntimeException(sprintf(
119
                'bin/tempo - version \'%s\' does not match git tag \'%s\', please update it before compiling',
120
                $matches[1],
121
                $version
122
            ));
123
        }
124
    }
125
}
126