Passed
Push — master ( b89ee9...82ea21 )
by Sebastian
03:18
created

Local   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 7
eloc 65
c 3
b 0
f 0
dl 0
loc 153
rs 10
ccs 19
cts 19
cp 1

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getPharHookLines() 0 21 1
A getLocalHookLines() 0 31 1
A getPathFromHookTo() 0 7 2
A __construct() 0 8 1
A getCode() 0 5 2
1
<?php
2
3
/**
4
 * This file is part of CaptainHook
5
 *
6
 * (c) Sebastian Feldmann <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace CaptainHook\App\Hook\Template;
15
16
use CaptainHook\App\Hook\Template;
17
use SebastianFeldmann\Camino\Path;
18
use SebastianFeldmann\Camino\Path\Directory;
19
use SebastianFeldmann\Camino\Path\File;
20
21
/**
22
 * Local class
23
 *
24
 * Generates the sourcecode for the php hook scripts in .git/hooks/*.
25
 *
26
 * @package CaptainHook
27
 * @author  Sebastian Feldmann <[email protected]>
28
 * @link    https://github.com/captainhookphp/captainhook
29
 * @since   Class available since Release 4.3.0
30
 */
31
class Local implements Template
32
{
33
    /**
34
     * Path to the captainhook configuration
35
     *
36
     * @var string
37
     */
38
    private $configPath;
39
40
    /**
41
     * Original bootstrap option
42
     *
43
     * @var string
44
     */
45
    private $bootstrap;
46
47
    /**
48
     * Path to the vendor directory
49
     *
50 5
     * @var string
51
     */
52 5
    private $bootstrapPath;
53 5
54 5
    /**
55
     * Path to the captainhook executable
56
     *
57
     * @var string
58
     */
59
    private $executablePath;
60
61
    /**
62 5
     * Is the executable a phar file
63
     *
64 5
     * @var bool
65 5
     */
66 5
    private $isPhar;
67 5
68 5
    /**
69 5
     * Local constructor
70 5
     *
71 5
     * @param \SebastianFeldmann\Camino\Path\Directory $repo
72 5
     * @param \SebastianFeldmann\Camino\Path\File      $config
73 5
     * @param \SebastianFeldmann\Camino\Path\File      $captainHook
74 5
     * @param string                                   $bootstrap
75 5
     * @param bool                                     $isPhar
76 5
     */
77 5
    public function __construct(Directory $repo, File $config, File $captainHook, string $bootstrap, bool $isPhar)
78
    {
79
        $bootstrapDir         = new Directory($config->getDirectory()->getPath() . '/' . $bootstrap);
80
        $this->bootstrap      = $bootstrap;
81
        $this->bootstrapPath  = $this->getPathFromHookTo($repo, $bootstrapDir);
82
        $this->configPath     = $this->getPathFromHookTo($repo, $config);
83
        $this->executablePath = $this->getPathFromHookTo($repo, $captainHook);
84
        $this->isPhar         = $isPhar;
85
    }
86
87
    /**
88
     * Return the code for the git hook scripts
89
     *
90
     * @param  string $hook Name of the hook to generate the sourcecode for
91
     * @return string
92
     */
93
    public function getCode(string $hook): string
94
    {
95
        $lines = $this->isPhar ? $this->getPharHookLines($hook) : $this->getLocalHookLines($hook);
96
97
        return implode(PHP_EOL, $lines) . PHP_EOL;
98
    }
99
100
    /**
101
     * Returns lines of code for the local src installation
102
     *
103
     * @param  string $hook
104
     * @return array<string>
105
     */
106
    private function getLocalHookLines(string $hook): array
107
    {
108
        return [
109
            '#!/usr/bin/env php',
110
            '<?php',
111
            '',
112
            'use CaptainHook\App\Console\Application\Cli as CaptainHook;',
113
            'use Symfony\Component\Console\Input\ArgvInput;',
114
            '',
115
            '(static function($argv)',
116
            '{',
117
            '    $bootstrap = ' . $this->bootstrapPath . ';',
118
            '    if (!file_exists($bootstrap)) {',
119
            '        fwrite(STDERR, \'Boostrap file \\\'\' . $bootstrap . \'\\\' could not be found\');',
120
            '        exit(1);',
121
            '    }',
122
            '    require $bootstrap;',
123
            '',
124
            '    $argv = array_merge(',
125
            '        [',
126
            '            $argv[0],',
127
            '            \'hook:' . $hook . '\',',
128
            '            \'--configuration=\' . ' . $this->configPath . ',',
129
            '            \'--git-directory=\' . dirname(__DIR__, 2) . \'/.git\',',
130
            '        ],',
131
            '        array_slice($argv, 1)',
132
            '    );',
133
            '    $captainHook = new CaptainHook($argv[0]);',
134
            '    $captainHook->run(new ArgvInput($argv));',
135
            '}',
136
            ')($argv);',
137
        ];
138
    }
139
140
    /**
141
     * Returns the lines of code for the local phar installation
142
     *
143
     * @param  string $hook
144
     * @return array<string>
145
     */
146
    private function getPharHookLines(string $hook): array
147
    {
148
        return [
149
            '#!/usr/bin/env php',
150
            '<?php',
151
            '',
152
            '(static function($argv)',
153
            '{',
154
            '    $argv = array_merge(',
155
            '        [',
156
            '            $argv[0],',
157
            '            \'hook:' . $hook . '\',',
158
            '            \'--configuration=\' . ' . $this->configPath . ',',
159
            '            \'--git-directory=\' . dirname(__DIR__, 2) . \'/.git\',',
160
            '            \'--bootstrap=' . $this->bootstrap . '\',',
161
            '        ],',
162
            '        array_slice($argv, 1)',
163
            '    );',
164
            '    include ' . $this->executablePath . ';',
165
            '}',
166
            ')($argv);',
167
        ];
168
    }
169
170
    /**
171
     * Return the path to the target path from inside the .git/hooks directory f.e. __DIR__ ../../vendor
172
     *
173
     * @param  \SebastianFeldmann\Camino\Path\Directory $repo
174
     * @param  \SebastianFeldmann\Camino\Path           $target
175
     * @return string
176
     */
177
    private function getPathFromHookTo(Directory $repo, Path $target): string
178
    {
179
        if (!$target->isChildOf($repo)) {
180
            return '\'' . $target->getPath() . '\'';
181
        }
182
183
        return '__DIR__ . \'/../../' . $target->getRelativePathFrom($repo) . '\'';
184
    }
185
}
186