Completed
Push — master ( aa9657...bb9832 )
by Sebastian
05:21
created

Installer::run()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
ccs 5
cts 5
cp 1
rs 9.4285
cc 3
eloc 4
nc 2
nop 0
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
namespace SebastianFeldmann\CaptainHook\Runner;
11
12
use SebastianFeldmann\CaptainHook\Console\IOUtil;
13
use SebastianFeldmann\CaptainHook\Hook\Template;
14
use SebastianFeldmann\CaptainHook\Storage\File;
15
use SebastianFeldmann\CaptainHook\Hook\Util;
16
17
/**
18
 * Class Installer
19
 *
20
 * @package CaptainHook
21
 * @author  Sebastian Feldmann <[email protected]>
22
 * @link    https://github.com/sebastianfeldmann/captainhook
23
 * @since   Class available since Release 0.9.0
24
 */
25
class Installer extends HookHandler
26
{
27
    /**
28
     * Overwrite hook
29
     *
30
     * @var bool
31
     */
32
    private $force;
33
34
    /**
35
     * @param  bool $force
36
     * @return \SebastianFeldmann\CaptainHook\Runner\Installer
37
     */
38 2
    public function setForce(bool $force)
39
    {
40 2
        $this->force = $force;
41 2
        return $this;
42
    }
43
44
    /**
45
     * Execute installation.
46
     */
47 2
    public function run()
48
    {
49 2
        $hooks = $this->getHooksToInstall();
50
51 2
        foreach ($hooks as $hook => $ask) {
52 2
            $this->installHook($hook, ($ask && !$this->force));
53
        }
54 2
    }
55
56
    /**
57
     * Return list of hooks to install.
58
     *
59
     * @return array
60
     */
61 2
    public function getHooksToInstall() : array
62
    {
63 2
        return empty($this->hookToHandle) ? Util::getValidHooks() : [$this->hookToHandle => false];
64
    }
65
66
    /**
67
     * Install given hook.
68
     *
69
     * @param string $hook
70
     * @param bool   $ask
71
     */
72 3
    public function installHook(string $hook, bool $ask)
73
    {
74 3
        $doIt = true;
75 3
        if ($ask) {
76 1
            $answer = $this->io->ask('  <info>Install \'' . $hook . '\' hook?</info> <comment>[y,n]</comment> ', 'y');
77 1
            $doIt   = IOUtil::answerToBool($answer);
78
        }
79
80 3
        if ($doIt) {
81 2
            $this->writeHookFile($hook);
82
        }
83 3
    }
84
85
    /**
86
     * Write given hook to .git/hooks directory
87
     *
88
     * @param string $hook
89
     */
90 3
    public function writeHookFile(string $hook)
91
    {
92 3
        $hooksDir = $this->repository->getHooksDir();
93 3
        $hookFile = $hooksDir . DIRECTORY_SEPARATOR . $hook;
94 3
        $doIt     = true;
95
96
        // if hook is configured and no force option is set
97
        // ask the user if overwriting the hook is ok
98 3
        if ($this->needInstallConfirmation($hook)) {
99 1
            $ans  = $this->io->ask('  <comment>The \'' . $hook . '\' hook exists! Overwrite? [y,n]</comment> ', 'n');
100 1
            $doIt = IOUtil::answerToBool($ans);
101
        }
102
103 3
        if ($doIt) {
104 2
            $code = $this->getHookSourceCode($hook);
105 2
            $file = new File($hookFile);
106 2
            $file->write($code);
107 2
            chmod($hookFile, 0755);
108 2
            $this->io->write('  <info>\'' . $hook . '\' hook installed successfully</info>');
109
        }
110 3
    }
111
112
    /**
113
     * Return the source code for a given hook script.
114
     *
115
     * @param  string $hook
116
     * @return string
117
     */
118 2
    protected function getHookSourceCode(string $hook) : string
119
    {
120 2
        $absRepoPath = realpath($this->repository->getRoot());
121 2
        $vendorPath  = getcwd() . '/vendor';
122 2
        $configPath  = realpath($this->config->getPath());
123 2
        return Template::getCode($hook, $absRepoPath, $vendorPath, $configPath);
124
    }
125
126
    /**
127
     * If the hook already exists the user has to confirm the installation.
128
     *
129
     * @param  string $hook The name of the hook to check
130
     * @return bool
131
     */
132 3
    protected function needInstallConfirmation(string $hook) : bool
133
    {
134 3
        return $this->repository->hookExists($hook) && !$this->force;
135
    }
136
}
137