Completed
Push — master ( 191869...afc708 )
by Frank
08:08
created

ReviewCommand::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 2
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * T3Bot.
4
 *
5
 * @author Frank Nägler <[email protected]>
6
 *
7
 * @link http://www.t3bot.de
8
 * @link http://wiki.typo3.org/T3Bot
9
 */
10
namespace T3Bot\Commands;
11
12
use Slack\Payload;
13
use Slack\RealTimeClient;
14
use T3Bot\Slack\Message;
15
16
/**
17
 * Class ReviewCommand.
18
 *
19
 * @property string commandName
20
 * @property array helpCommands
21
 */
22
class ReviewCommand extends AbstractCommand
23
{
24
    /**
25
     * AbstractCommand constructor.
26
     *
27
     * @param Payload        $payload
28
     * @param RealTimeClient $client
29
     */
30
    public function __construct(Payload $payload, RealTimeClient $client)
31
    {
32
        $this->commandName = 'review';
33
        $this->helpCommands = [
34
            'help' => 'shows this help',
35
            'count [PROJECT=Packages/TYPO3.CMS]' => 'shows the number of currently open reviews for [PROJECT]',
36
            'random' => 'shows a random open review',
37
            'show [Ref-ID] [[Ref-ID-2] [[Ref-ID-n]]]' => 'shows the review by given change number(s). Do not use separators other than space.',
38
            'user [username] [PROJECT=Packages/TYPO3.CMS]' => 'shows the open reviews by given username for [PROJECT]',
39
            'query [searchQuery]' => 'shows the results for given [searchQuery], max limit is 50',
40
            'merged [YYYY-MM-DD]' => 'shows a count of merged patches on master since given date',
41
        ];
42
        parent::__construct($payload, $client);
43
    }
44
45
    /**
46
     * process count.
47
     *
48
     * @return string
49
     */
50
    protected function processCount() : string
51
    {
52
        $project = !empty($this->params[1]) ? $this->params[1] : 'Packages/TYPO3.CMS';
53
        $result = $this->queryGerrit("is:open branch:master -message:WIP project:{$project}");
54
        $count = count($result);
55
        $result = $this->queryGerrit("label:Code-Review=-1 is:open branch:master -message:WIP project:{$project}");
56
        $countMinus1 = count($result);
57
        $result = $this->queryGerrit("label:Code-Review=-2 is:open branch:master -message:WIP project:{$project}");
58
        $countMinus2 = count($result);
59
60
        $returnString = '';
61
        $returnString .= 'There are currently ' . $this->bold($count) . ' open reviews for project '
62
            . $this->italic($project) . ' and branch master on <https://review.typo3.org/#/q/project:' . $project
63
            . '+status:open+branch:master|https://review.typo3.org>' . "\n";
64
        $returnString .= $this->bold($countMinus1) . ' of ' . $this->bold($count) . ' open reviews voted with '
65
            . $this->bold('-1') . ' <https://review.typo3.org/#/q/label:Code-Review%253D-1+is:open+branch:'
66
            . 'master+project:' . $project . '|Check now> ' . "\n";
67
        $returnString .= $this->bold($countMinus2) . ' of ' . $this->bold($count) . ' open reviews voted with '
68
            . $this->bold('-2') . ' <https://review.typo3.org/#/q/label:Code-Review%253D-2+is:open+branch:'
69
            . 'master+project:' . $project . '|Check now>';
70
71
        return $returnString;
72
    }
73
74
    /**
75
     * process random.
76
     *
77
     * @return Message
78
     */
79
    protected function processRandom() : Message
80
    {
81
        /** @var array $result */
82
        $result = $this->queryGerrit('is:open project:Packages/TYPO3.CMS');
83
        $item = $result[array_rand($result)];
84
85
        return $this->buildReviewMessage($item);
86
    }
87
88
    /**
89
     * process user.
90
     *
91
     * @return string
92
     */
93
    protected function processUser() : string
94
    {
95
        $username = !empty($this->params[1]) ? $this->params[1] : null;
96
        $project = !empty($this->params[2]) ? $this->params[2] : 'Packages/TYPO3.CMS';
97
        if ($username === null) {
98
            return 'hey, I need a username!';
99
        }
100
        $results = $this->queryGerrit('is:open owner:"' . $username . '" project:' . $project);
101 View Code Duplication
        if (count($results) > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
102
            $listOfItems = ['*Here are the results for ' . $username . '*:'];
103
            if (is_array($results)) {
104
                foreach ($results as $item) {
105
                    $listOfItems[] = $this->buildReviewLine($item);
106
                }
107
            }
108
109
            return implode("\n", $listOfItems);
110
        }
111
        return $username . ' has no open reviews or username is unknown';
112
    }
113
114
    /**
115
     * process count.
116
     *
117
     * @return string|Message
118
     */
119
    protected function processShow()
120
    {
121
        $urlPattern = '/http[s]*:\/\/review.typo3.org\/[#\/c]*([\d]*)(?:.*)/i';
122
        $refId = $this->params[1] ?? null;
123
        if (preg_match_all($urlPattern, $refId, $matches)) {
124
            $refId = (int) $matches[1][0];
125
        } else {
126
            $refId = (int) $refId;
127
        }
128
        if ($refId === null || $refId === 0) {
129
            return 'hey, I need at least one change number!';
130
        }
131
        $returnMessage = '';
132
        $paramsCount = count($this->params);
133
        if ($paramsCount > 2) {
134
            $changeIds = [];
135
            for ($i = 1; $i < $paramsCount; ++$i) {
136
                $changeIds[] = 'change:' . $this->params[$i];
137
            }
138
            $result = $this->queryGerrit(implode(' OR ', $changeIds));
139
            $listOfItems = [];
140
            if (is_array($result)) {
141
                foreach ($result as $item) {
142
                    $listOfItems[] = $this->buildReviewLine($item);
143
                }
144
            }
145
            $returnMessage = implode(chr(10), $listOfItems);
146
        } else {
147
            $result = $this->queryGerrit('change:' . $refId);
148
            if (!$result) {
149
                return "{$refId} not found, sorry!";
150
            }
151
            if (is_array($result)) {
152
                foreach ($result as $item) {
153
                    if ($item->_number === $refId) {
154
                        $returnMessage = $this->buildReviewMessage($item);
155
                    }
156
                }
157
            }
158
        }
159
160
        return $returnMessage;
161
    }
162
163
    /**
164
     * process query.
165
     *
166
     * @return string
167
     */
168
    protected function processQuery() : string
169
    {
170
        $queryParts = $this->params;
171
        array_shift($queryParts);
172
        $query = trim(implode(' ', $queryParts));
173
        if ($query === '') {
174
            return 'hey, I need a query!';
175
        }
176
177
        $results = $this->queryGerrit('limit:50 ' . $query);
178 View Code Duplication
        if (count($results) > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
179
            $listOfItems = ["*Here are the results for {$query}*:"];
180
            if (is_array($results)) {
181
                foreach ($results as $item) {
182
                    $listOfItems[] = $this->buildReviewLine($item);
183
                }
184
            }
185
            return implode(chr(10), $listOfItems);
186
        }
187
188
        return "{$query} not found, sorry!";
189
    }
190
191
    /**
192
     * @return string
193
     */
194
    protected function processMerged() : string
195
    {
196
        $query = 'project:Packages/TYPO3.CMS status:merged after:###DATE### branch:master';
197
198
        $date = !empty($this->params[1]) ? $this->params[1] : '';
199
        if (!$this->isDateFormatCorrect($date)) {
200
            return 'hey, I need a date in the format YYYY-MM-DD!';
201
        }
202
        $query = str_replace('###DATE###', $date, $query);
203
        $result = $this->queryGerrit($query);
204
205
        $cnt = count($result);
206
207
        return 'Good job folks, since ' . $date . ' you merged *' . $cnt . '* patches into master';
208
    }
209
210
    /**
211
     * check format of given date.
212
     *
213
     * @param $date
214
     *
215
     * @return bool
216
     */
217
    protected function isDateFormatCorrect($date) : bool
218
    {
219
        return preg_match('/[\d]{4}-[\d]{2}-[\d]{2}/', $date) === 1;
220
    }
221
}
222