Passed
Push — master ( 6545c7...42d197 )
by Sebastian
02:37
created

Hook::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 4
crap 1
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 CaptainHook\App\Runner;
11
12
use CaptainHook\App\Config;
13
use CaptainHook\App\Config\Options;
14
use CaptainHook\App\Console\IO;
15
use CaptainHook\App\Console\IOUtil;
16
use SebastianFeldmann\Git\Repository;
17
use RuntimeException;
18
19
/**
20
 * Hook
21
 *
22
 * @package CaptainHook
23
 * @author  Sebastian Feldmann <[email protected]>
24
 * @link    https://github.com/captainhookphp/captainhook
25
 * @since   Class available since Release 0.9.0
26
 */
27
abstract class Hook extends RepositoryAware
28
{
29
    /**
30
     * Hook that should be handled.
31
     *
32
     * @var string
33
     */
34
    protected $hook;
35
36
    /**
37
     * Execute stuff before executing any actions
38
     *
39
     * @return void
40
     */
41 9
    public function beforeHook() : void
42
    {
43
        // empty template method
44 9
    }
45
46
    /**
47
     * Execute stuff before every actions
48
     *
49
     * @return void
50
     */
51 1
    public function beforeAction() : void
52
    {
53
        // empty template method
54 1
    }
55
56
    /**
57
     * Execute stuff after every actions
58
     *
59
     * @return void
60
     */
61 1
    public function afterAction() : void
62
    {
63
        //empty template method
64 1
    }
65
66
    /**
67
     * Execute stuff after all actions
68
     *
69
     * @return void
70
     */
71 9
    public function afterHook() : void
72
    {
73
        // empty template method
74 9
    }
75
76
    /**
77
     * Execute the hook and all its actions
78
     *
79
     * @return void
80
     * @throws \Exception
81
     */
82 23
    public function run() : void
83
    {
84
        /** @var \CaptainHook\App\Config\Hook $hookConfig */
85 23
        $hookConfig = $this->config->getHookConfig($this->hook);
86 23
        $actions    = $hookConfig->getActions();
87
88
        // if hook is not enabled in captainhook configuration skip the execution
89 23
        if (!$hookConfig->isEnabled()) {
90 8
            $this->io->write($this->formatHookHeadline('Skip'));
91 8
            return;
92
        }
93
        // if no actions are configured do nothing
94 15
        if (count($actions) === 0) {
95 4
            $this->io->write(['', '<info>No actions to execute</info>']);
96 4
            return;
97
        }
98
99 11
        $this->io->write($this->formatHookHeadline('Execute'));
100 11
        $this->beforeHook();
101 9
        foreach ($actions as $action) {
102 9
            $this->handleAction($action);
103
        }
104 9
        $this->afterHook();
105 9
    }
106
107
    /**
108
     * Executes a configured hook action
109
     *
110
     * @param  \CaptainHook\App\Config\Action $action
111
     * @return void
112
     * @throws \Exception
113
     */
114 9
    protected function handleAction(Config\Action $action) : void
115
    {
116 9
        $this->io->write(['', 'Action: <comment>' . $action->getAction() . '</comment>']);
117
118 9
        if (!$this->doConditionsApply($action->getConditions())) {
119 1
            $this->io->write(
120 1
                ['', 'Skipped due to failing conditions']
121
            );
122 1
            return;
123
        }
124
125 8
        $execMethod = self::getExecMethod(Util::getExecType($action->getAction()));
126 8
        $this->{$execMethod}($action);
127 8
    }
128
129
    /**
130
     * Execute a php hook action
131
     *
132
     * @param  \CaptainHook\App\Config\Action $action
133
     * @return void
134
     * @throws \CaptainHook\App\Exception\ActionFailed
135
     */
136 1
    protected function executePhpAction(Config\Action $action) : void
137
    {
138 1
        $this->beforeAction();
139 1
        $runner = new Action\PHP();
140 1
        $runner->execute($this->config, $this->io, $this->repository, $action);
141 1
        $this->afterAction();
142 1
    }
143
144
    /**
145
     * Execute a cli hook action
146
     *
147
     * @param  \CaptainHook\App\Config\Action $action
148
     * @return void
149
     * @throws \CaptainHook\App\Exception\ActionFailed
150
     */
151 7
    protected function executeCliAction(Config\Action $action) : void
152
    {
153
        // since the cli has no straight way to communicate back to php
154
        // cli hooks have to handle sync stuff by them self
155
        // so no 'beforeAction' or 'afterAction' is called here
156 7
        $runner = new Action\Cli();
157 7
        $runner->execute($this->io, $action);
158 7
    }
159
160
    /**
161
     * Return the right method name to execute an action
162
     *
163
     * @param  string $type
164
     * @return string
165
     */
166 10
    public static function getExecMethod(string $type) : string
167
    {
168 10
        $valid = ['php' => 'executePhpAction', 'cli' => 'executeCliAction'];
169
170 10
        if (!isset($valid[$type])) {
171 1
            throw new RuntimeException('invalid action type: ' . $type);
172
        }
173 9
        return $valid[$type];
174
    }
175
176
    /**
177
     * Check if conditions apply
178
     *
179
     * @param  \CaptainHook\App\Config\Condition[] $conditions
180
     * @return bool
181
     */
182 9
    private function doConditionsApply(array $conditions) : bool
183
    {
184 9
        $conditionRunner = new Condition($this->io, $this->repository);
185 9
        foreach ($conditions as $config) {
186 2
            if (!$conditionRunner->doesConditionApply($config)) {
187 1
                return false;
188
            }
189
        }
190 8
        return true;
191
    }
192
193
    /**
194
     * Some fancy output formatting
195
     *
196
     * @param  string $mode
197
     * @return string[]
198
     */
199 19
    private function formatHookHeadline(string $mode) : array
200
    {
201 19
        $headline = ' ' . $mode . ' hook: <comment>' . $this->hook . '</comment> ';
202
        return [
203 19
            '',
204 19
            IOUtil::getLineSeparator(8) .
205 19
            $headline .
206 19
            IOUtil::getLineSeparator(80 - 8 - strlen(strip_tags($headline)))
207
        ];
208
    }
209
}
210