Completed
Push — master ( 4e66b4...07b1de )
by Billie
05:44
created

Hook   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 8
c 1
b 0
f 0
lcom 1
cbo 10
dl 0
loc 115
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
B configure() 0 43 1
C execute() 0 45 7
1
<?php
2
declare(strict_types = 1);
3
4
namespace PurpleBooth\GitLintValidators\Command;
5
6
use PurpleBooth\GitLintValidators\MessageImplementation;
7
use PurpleBooth\GitLintValidators\Status\Status;
8
use PurpleBooth\GitLintValidators\ValidatorFactoryImplementation;
9
use Symfony\Component\Console\Command\Command;
10
use Symfony\Component\Console\Input\InputArgument;
11
use Symfony\Component\Console\Input\InputDefinition;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Input\InputOption;
14
use Symfony\Component\Console\Output\OutputInterface;
15
use Symfony\Component\Console\Style\SymfonyStyle;
16
17
/**
18
 * A command that allows you to try out the library
19
 *
20
 * @package PurpleBooth\GitGitHubLint\Command
21
 */
22
class Hook extends Command
23
{
24
    const COMMAND_NAME                 = 'git-lint-validator:hook';
25
    const ARGUMENT_COMMIT_MESSAGE_FILE = 'commit-message-file';
26
    const OPTION_COMMENT_CHAR          = 'comment-char';
27
    const OPTION_IGNORE                = 'ignore';
28
29
    /**
30
     * Configures the current command.
31
     */
32
    protected function configure()
33
    {
34
        $this->setName(self::COMMAND_NAME);
35
        $this->setDescription("Check the style of commit messages");
36
37
        $help = '';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
38
        $help .= "Check your commit messages to ensure they follow the guidelines\n";
39
        $help .= "in your add this to your .git/hooks/commit-msg file\n";
40
        $help .= "\n";
41
        $help .= "\n";
42
        $help .= "Here are some good articles on commit message style:\n";
43
        $help .= "\n";
44
        $help .= "* http://chris.beams.io/posts/git-commit/\n";
45
        $help .= "* https://git-scm.com/book/ch5-2.html#Commit-Guidelines\n";
46
        $help .= "* https://github.com/blog/926-shiny-new-commit-styles\n";
47
48
        $this->setHelp($help);
49
        $this->setDefinition(
50
            new InputDefinition(
51
                [
52
                    new InputArgument(
53
                        self::ARGUMENT_COMMIT_MESSAGE_FILE,
54
                        InputArgument::REQUIRED,
55
                        'Path to commit message file'
56
                    ),
57
                    new InputOption(
58
                        self::OPTION_IGNORE,
59
                        ['i'],
60
                        InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL,
61
                        'Ignore a commit message that matches this pattern and don\'t test it',
62
                        ['/^Merge branch/']
63
                    ),
64
                    new InputOption(
65
                        self::OPTION_COMMENT_CHAR,
66
                        ['c'],
67
                        InputOption::VALUE_OPTIONAL,
68
                        'Ignore lines that are prefixed with this character',
69
                        '#'
70
                    ),
71
                ]
72
            )
73
        );
74
    }
75
76
    /**
77
     * Executes the current command.
78
     *
79
     * This method is not abstract because you can use this class
80
     * as a concrete class. In this case, instead of defining the
81
     * execute() method, you set the code to execute by passing
82
     * a Closure to the setCode() method.
83
     *
84
     * @param InputInterface  $input  An InputInterface instance
85
     * @param OutputInterface $output An OutputInterface instance
86
     *
87
     * @return null|int null or 0 if everything went fine, or an error code
88
     *
89
     * @see setCode()
90
     */
91
    protected function execute(InputInterface $input, OutputInterface $output)
92
    {
93
        $styleHelper      = new SymfonyStyle($input, $output);
94
        $validatorFactory = new ValidatorFactoryImplementation();
95
        $validators       = $validatorFactory->getMessageValidator();
96
97
        $commitMessage    = file_get_contents($input->getArgument(self::ARGUMENT_COMMIT_MESSAGE_FILE));
98
        $commentCharacter = $input->getOption(self::OPTION_COMMENT_CHAR);
99
        $ignorePatterns   = $input->getOption(self::OPTION_IGNORE);
100
101
        foreach ($ignorePatterns as $ignorePattern) {
102
            if (preg_match($ignorePattern, $commitMessage)) {
103
                return 0;
104
            }
105
        }
106
107
        $safeCommitMessage = preg_replace("/" . preg_quote($commentCharacter) . ".*/", "", $commitMessage);
108
        $message           = new MessageImplementation($safeCommitMessage);
109
110
        $validators->validate($message);
111
112
        if (count($message->getStatuses()) < 1) {
113
            return 0;
114
        }
115
116
        $statusList = [];
117
        $isPositive = true;
118
119
        /** @var Status $status */
120
        foreach ($message->getStatuses() as $status) {
121
            $statusList[] = $status->getMessage() . " (" . $status->getDetailsUrl() . ")";
122
123
            $isPositive = $status->isPositive() && $isPositive;
124
        }
125
126
127
        if ($isPositive) {
128
            return 0;
129
        }
130
131
        $styleHelper->error("Incorrectly formatted commit message");
132
        $styleHelper->listing($statusList);
133
134
        return 1;
135
    }
136
}
137