Completed
Branch master (812a3e)
by Frank
04:30 queued 02:09
created

ReviewCommand::buildReviewMessageOutput()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5.0342

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 4
nop 1
dl 0
loc 15
ccs 8
cts 9
cp 0.8889
crap 5.0342
rs 8.8571
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 27
    public function __construct(Payload $payload, RealTimeClient $client)
31
    {
32 27
        $this->commandName = 'review';
33 27
        $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 27
        parent::__construct($payload, $client);
43 27
    }
44
45
    /**
46
     * process count.
47
     *
48
     * @return string
49
     */
50 1
    protected function processCount() : string
51
    {
52 1
        $project = !empty($this->params[1]) ? $this->params[1] : 'Packages/TYPO3.CMS';
53 1
        $result = $this->queryGerrit("is:open branch:master -message:WIP project:{$project}");
54 1
        $count = count($result);
55 1
        $result = $this->queryGerrit("label:Code-Review=-1 is:open branch:master -message:WIP project:{$project}");
56 1
        $countMinus1 = count($result);
57 1
        $result = $this->queryGerrit("label:Code-Review=-2 is:open branch:master -message:WIP project:{$project}");
58 1
        $countMinus2 = count($result);
59
60 1
        $returnString = '';
61 1
        $returnString .= 'There are currently ' . $this->bold($count) . ' open reviews for project '
62 1
            . $this->italic($project) . ' and branch master on <https://review.typo3.org/#/q/project:' . $project
63 1
            . '+status:open+branch:master|https://review.typo3.org>' . chr(10);
64 1
        $returnString .= $this->bold($countMinus1) . ' of ' . $this->bold($count) . ' open reviews voted with '
65 1
            . $this->bold('-1') . ' <https://review.typo3.org/#/q/label:Code-Review%253D-1+is:open+branch:'
66 1
            . 'master+project:' . $project . '|Check now> ' . chr(10);
67 1
        $returnString .= $this->bold($countMinus2) . ' of ' . $this->bold($count) . ' open reviews voted with '
68 1
            . $this->bold('-2') . ' <https://review.typo3.org/#/q/label:Code-Review%253D-2+is:open+branch:'
69 1
            . 'master+project:' . $project . '|Check now>';
70
71 1
        return $returnString;
72
    }
73
74
    /**
75
     * process random.
76
     *
77
     * @return Message
78
     */
79 1
    protected function processRandom() : Message
80
    {
81
        /** @var array $result */
82 1
        $result = $this->queryGerrit('is:open project:Packages/TYPO3.CMS');
83 1
        $item = $result[array_rand($result)];
84
85 1
        return $this->buildReviewMessage($item);
86
    }
87
88
    /**
89
     * process user.
90
     *
91
     * @return string
92
     */
93 3
    protected function processUser() : string
94
    {
95 3
        $username = !empty($this->params[1]) ? $this->params[1] : null;
96 3
        $project = !empty($this->params[2]) ? $this->params[2] : 'Packages/TYPO3.CMS';
97 3
        if ($username === null) {
98 1
            return 'hey, I need a username!';
99
        }
100 2
        $results = $this->queryGerrit('is:open owner:"' . $username . '" project:' . $project);
101 2
        if (count($results) > 0) {
102 1
            $listOfItems = ['*Here are the results for ' . $username . '*:'];
103 1
            if (is_array($results)) {
104 1
                foreach ($results as $item) {
105 1
                    $listOfItems[] = $this->buildReviewLine($item);
106
                }
107
            }
108
109 1
            return implode(chr(10), $listOfItems);
110
        }
111 1
        return $username . ' has no open reviews or username is unknown';
112
    }
113
114
    /**
115
     * process count.
116
     *
117
     * @return string|Message
118
     */
119 14
    protected function processShow()
120
    {
121 14
        $urlPattern = '/http[s]*:\/\/review.typo3.org\/[#\/c]*([\d]*)(?:.*)/i';
122 14
        $refId = $this->params[1] ?? 0;
123 14
        if (preg_match_all($urlPattern, $refId, $matches)) {
124 4
            $refId = (int) $matches[1][0];
125
        } else {
126 10
            $refId = (int) $refId;
127
        }
128 14
        if ($refId === 0) {
129 2
            return 'hey, I need at least one change number!';
130
        }
131 12
        $paramsCount = count($this->params);
132 12
        if ($paramsCount > 2) {
133 1
            $returnMessage = $this->buildReviewLineOutput();
134
        } else {
135 11
            $returnMessage = $this->buildReviewMessageOutput($refId);
136
        }
137
138 12
        return $returnMessage;
139
    }
140
141
    /**
142
     * @return string
143
     */
144 1
    protected function buildReviewLineOutput() : string
145
    {
146 1
        $paramsCount = count($this->params);
147 1
        $changeIds = [];
148 1
        for ($i = 1; $i < $paramsCount; ++$i) {
149 1
            $changeIds[] = 'change:' . $this->params[$i];
150
        }
151 1
        $result = $this->queryGerrit(implode(' OR ', $changeIds));
152 1
        $listOfItems = [];
153 1
        if (is_array($result)) {
154 1
            foreach ($result as $item) {
155 1
                $listOfItems[] = $this->buildReviewLine($item);
156
            }
157
        }
158 1
        return implode(chr(10), $listOfItems);
159
    }
160
161
    /**
162
     * @param int $refId
163
     *
164
     * @return string|Message
165
     */
166 11
    protected function buildReviewMessageOutput(int $refId)
167
    {
168 11
        $result = $this->queryGerrit('change:' . $refId);
169 11
        if (!$result) {
170 1
            return "{$refId} not found, sorry!";
171
        }
172 10
        if (is_array($result)) {
173 10
            foreach ($result as $item) {
174 10
                if ($item->_number === $refId) {
175 10
                    return $this->buildReviewMessage($item);
176
                }
177
            }
178
        }
179
        return "{$refId} not found, sorry!";
180
    }
181
182
    /**
183
     * process query.
184
     *
185
     * @return string
186
     */
187 3
    protected function processQuery() : string
188
    {
189 3
        $queryParts = $this->params;
190 3
        array_shift($queryParts);
191 3
        $query = trim(implode(' ', $queryParts));
192 3
        if ($query === '') {
193 1
            return 'hey, I need a query!';
194
        }
195
196 2
        $results = $this->queryGerrit('limit:50 ' . $query);
197 2
        if (count($results) > 0) {
198 1
            $listOfItems = ["*Here are the results for {$query}*:"];
199 1
            if (is_array($results)) {
200 1
                foreach ($results as $item) {
201 1
                    $listOfItems[] = $this->buildReviewLine($item);
202
                }
203
            }
204 1
            return implode(chr(10), $listOfItems);
205
        }
206
207 1
        return "{$query} not found, sorry!";
208
    }
209
210
    /**
211
     * @return string
212
     */
213 3
    protected function processMerged() : string
214
    {
215 3
        $query = 'project:Packages/TYPO3.CMS status:merged after:###DATE### branch:master';
216
217 3
        $date = !empty($this->params[1]) ? $this->params[1] : '';
218 3
        if (!$this->isDateFormatCorrect($date)) {
219 2
            return 'hey, I need a date in the format YYYY-MM-DD!';
220
        }
221 1
        $query = str_replace('###DATE###', $date, $query);
222 1
        $result = $this->queryGerrit($query);
223
224 1
        $cnt = count($result);
225
226 1
        return 'Good job folks, since ' . $date . ' you merged *' . $cnt . '* patches into master';
227
    }
228
229
    /**
230
     * check format of given date.
231
     *
232
     * @param $date
233
     *
234
     * @return bool
235
     */
236 3
    protected function isDateFormatCorrect($date) : bool
237
    {
238 3
        return preg_match('/[\d]{4}-[\d]{2}-[\d]{2}/', $date) === 1;
239
    }
240
}
241