Passed
Push — main ( 799be8...9a05b8 )
by Sebastian
04:00
created

MessageAware::beforeAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 10
rs 10
ccs 5
cts 5
cp 1
crap 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
namespace CaptainHook\App\Runner\Hook;
13
14
use CaptainHook\App\Config;
15
use CaptainHook\App\Hooks;
16
use CaptainHook\App\Runner\Hook;
17
use CaptainHook\App\Runner\Util;
18
use SebastianFeldmann\Git;
19
20
/**
21
 * Base class for message aware hooks
22
 *
23
 * Message aware hooks like `prepare-commit-msg` and `commit-msg` can potentially change the commit message.
24
 * This class makes sure the commit message is read and written before and after any php Action that is executed.
25
 */
26
abstract class MessageAware extends Hook
27
{
28
    /**
29
     * Comment char '#' by default
30
     *
31
     * @var string
32
     */
33
    protected string $commentChar;
34
35
    /**
36
     * Path to commit message file
37
     *
38
     * @var string
39
     */
40
    protected string $file;
41
42
    /**
43
     * The current commit message
44
     *
45
     * @var \SebastianFeldmann\Git\CommitMessage
46
     */
47
    protected Git\CommitMessage $commitMsg;
48
49
    /**
50
     * Fetch the original hook arguments and message related config settings
51
     *
52
     * @return void
53
     */
54 7
    public function beforeHook(): void
55
    {
56 7
        $this->commentChar = $this->repository->getConfigOperator()->getSettingSafely('core.commentchar', '#');
57 7
        $this->file        = $this->io->getArgument(Hooks::ARG_MESSAGE_FILE);
58
59 7
        $this->repository->setCommitMsg(
60 7
            Git\CommitMessage::createFromFile(
61 7
                $this->file,
62 7
                $this->commentChar
63 7
            )
64 7
        );
65
66 5
        parent::beforeHook();
67
    }
68
69
    /**
70
     * Read the commit message from file
71
     *
72
     * @param Config\Action $action
73
     * @return void
74
     */
75 2
    public function beforeAction(Config\Action $action): void
76
    {
77
        // since every action can potentially update the commit message
78
        // we have to load the commit message from disk every time
79
        // only load the commit message from disk if a php action is executed
80 2
        if (Util::getExecType($action->getAction()) !== 'cli') {
81 1
            $this->commitMsg = Git\CommitMessage::createFromFile($this->file, $this->commentChar);
82 1
            $this->repository->setCommitMsg($this->commitMsg);
83
        }
84 2
        parent::beforeAction($action);
85
    }
86
87
    /**
88
     * Write the commit message to disk so git or the next action can proceed further
89
     *
90
     * @param Config\Action $action
91
     * @return void
92
     */
93 2
    public function afterAction(Config\Action $action): void
94
    {
95
        // since the action could potentially change the commit message
96
        // only write the commit message to disk if a php action was executed
97 2
        if (Util::getExecType($action->getAction()) !== 'cli') {
98
            // if the commit message was changed write it to disk
99 1
            if ($this->commitMsg->getRawContent() !== $this->repository->getCommitMsg()->getRawContent()) {
100 1
                file_put_contents($this->file, $this->repository->getCommitMsg()->getRawContent());
101
            }
102
        }
103 2
        parent::afterAction($action);
104
    }
105
106
    /**
107
     * Makes sure we do not run commit message validation for fixup commits
108
     *
109
     * @return void
110
     * @throws \Exception
111
     */
112 5
    protected function runHook(): void
113
    {
114 5
        $msg = $this->repository->getCommitMsg();
115 5
        if ($msg->isFixup() || $msg->isSquash()) {
116 1
            $this->io->write(' - no commit message hooks for fixup and squash commits: skipping all actions');
117 1
            return;
118
        }
119 4
        parent::runHook();
120
    }
121
}
122