Completed
Push — master ( b45d24...df18f1 )
by Sebastian
02:26
created

Docker::resolveBinaryPath()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 27
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 27
ccs 8
cts 8
cp 1
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 2
crap 3
1
<?php
2
/**
3
 * This file is part of CaptainHook.
4
 *
5
 * (c) Sebastian Feldmann <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
declare(strict_types=1);
11
12
namespace CaptainHook\App\Hook\Template;
13
14
use CaptainHook\App\Hook\Template;
15
use CaptainHook\App\Storage\Util;
16
17
/**
18
 * Docker class
19
 *
20
 * Generates the bash scripts placed in .git/hooks/* for every hook
21
 * to execute CaptainHook inside of a Docker container.
22
 *
23
 * @package CaptainHook
24
 * @author  Sebastian Feldmann <[email protected]>
25
 * @link    https://github.com/captainhookphp/captainhook
26
 * @since   Class available since Release 4.3.0
27
 */
28
class Docker implements Template
29
{
30
    private const BINARY = 'captainhook-run';
31
32
    /**
33
     * Path to the captainhook-run binary
34
     *
35
     * @var string
36
     */
37
    private $binaryPath;
38
39
    /**
40
     * Command to spin up the container
41
     *
42
     * @var string
43
     */
44
    private $command;
45
46
    /**
47
     * Docker constructor
48
     *
49
     * @param string $repoPath
50
     * @param string $vendorPath
51
     * @param string $command
52
     */
53 4
    public function __construct(string $repoPath, string $vendorPath, string $command)
54
    {
55 4
        $this->command    = $command;
56 4
        $this->binaryPath = $this->resolveBinaryPath($repoPath, $vendorPath);
57 4
    }
58
59
    /**
60
     * Return the code for the git hook scripts
61
     *
62
     * @param  string $hook Name of the hook to generate the sourcecode for
63
     * @return string
64
     */
65 4
    public function getCode(string $hook): string
66
    {
67 4
        return '#!/usr/bin/env bash' . PHP_EOL .
68 4
            $this->command . ' ' . $this->binaryPath . ' ' . $hook . ' "$@"' . PHP_EOL;
69
    }
70
71
    /**
72
     * Resolves the path to the captainhook-run binary and returns it.
73
     *
74
     * This path is either right inside the repo itself (captainhook) or only in vendor path.
75
     * Which happens if captainhook is required as dependency.
76
     *
77
     * @param  string $repoPath   Absolute path to the git repository root
78
     * @param  string $vendorPath Absolute path to the composer vendor directory
79
     * @return string
80
     */
81 4
    private function resolveBinaryPath(string $repoPath, string $vendorPath): string
82
    {
83
        // For docker we need to strip down the current working directory.
84
        // This is caused because docker will always connect to a specific working directory
85
        // where the absolute path will not be recognized.
86
        // E.g.:
87
        //   cwd    => /project/
88
        //   path   => /project/vendor/bin/captainhook-run
89
        //   docker => ./vendor/bin/captainhook-run
90
91
        // check if the captainhook binary is in the repository root directory
92
        // this is only the case if we work in the captainhook repository
93 4
        if (file_exists($repoPath . '/' . self::BINARY)) {
94 1
            return './' . self::BINARY;
95
        }
96
97 3
        $repoDir   = Util::pathToArray($repoPath);
98 3
        $vendorDir = Util::pathToArray($vendorPath);
99
100
        // if vendor dir is a subdirectory use a relative path
101 3
        if (Util::isSubDirectoryOf($vendorDir, $repoDir)) {
102 2
            $vendorPath = './' . Util::arrayToPath(Util::getSubPathOf($vendorDir, $repoDir));
103
        }
104
105
        // by default this should return something like ./vendor/bin/captainhook-run
106
        // if the vendor directory is not located in your git repository it will return an absolute path
107 3
        return $vendorPath . '/bin/' . self::BINARY;
108
    }
109
}
110