1
|
|
|
<?php declare(strict_types = 1); |
2
|
|
|
/** |
3
|
|
|
* Created by Vitaly Iegorov <[email protected]>. |
4
|
|
|
* on 22.09.16 at 09:26 |
5
|
|
|
*/ |
6
|
|
|
namespace samsonframework\bitbucket; |
7
|
|
|
|
8
|
|
|
use Bitbucket\API\Authentication\AuthenticationInterface; |
9
|
|
|
use Bitbucket\API\Repositories\Changesets; |
10
|
|
|
use Bitbucket\API\Repositories\PullRequests; |
11
|
|
|
use Buzz\Message\MessageInterface; |
12
|
|
|
use Psr\Log\LoggerAwareInterface; |
13
|
|
|
use Symfony\Component\Console\Logger\ConsoleLogger; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Class BitBucketCloudReporter. |
17
|
|
|
* |
18
|
|
|
* @author Vitaly Egorov <[email protected]> |
19
|
|
|
*/ |
20
|
|
|
class CloudReporter |
21
|
|
|
{ |
22
|
|
|
/** @var PullRequests */ |
23
|
|
|
protected $pullRequests; |
24
|
|
|
|
25
|
|
|
/** @var Changesets */ |
26
|
|
|
protected $changeSets; |
27
|
|
|
|
28
|
|
|
/** @var string BitBucket account name */ |
29
|
|
|
protected $accountName; |
30
|
|
|
|
31
|
|
|
/** @var string BitBucket repository name */ |
32
|
|
|
protected $repoName; |
33
|
|
|
|
34
|
|
|
/** @var int BitBucket pull request id */ |
35
|
|
|
protected $pullRequestId; |
36
|
|
|
|
37
|
|
|
/** @var ConsoleLogger */ |
38
|
|
|
protected $logger; |
39
|
|
|
|
40
|
|
|
/** @var string Pull request author */ |
41
|
|
|
protected $author; |
42
|
|
|
|
43
|
|
|
/** @var ReporterInterface[] */ |
44
|
|
|
protected $reporters = []; |
45
|
|
|
|
46
|
|
|
public function __construct( |
47
|
|
|
AuthenticationInterface $credentials, |
48
|
|
|
ConsoleLogger $logger, |
49
|
|
|
string $accountName, |
50
|
|
|
string $repoName, |
51
|
|
|
int $pullRequestId |
52
|
|
|
) { |
53
|
|
|
$this->accountName = trim($accountName); |
54
|
|
|
$this->repoName = trim($repoName); |
55
|
|
|
$this->pullRequestId = $pullRequestId; |
56
|
|
|
$this->logger = $logger; |
57
|
|
|
|
58
|
|
|
$this->pullRequests = new PullRequests(); |
59
|
|
|
$this->pullRequests->setCredentials($credentials); |
60
|
|
|
|
61
|
|
|
$this->changesets = new Changesets(); |
|
|
|
|
62
|
|
|
$this->changesets->setCredentials(clone $credentials); |
|
|
|
|
63
|
|
|
|
64
|
|
|
$this->author = $this->getPullRequestAuthor(); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* Add reporter. |
69
|
|
|
* |
70
|
|
|
* @param ReporterInterface $reporter Reporter instance |
71
|
|
|
*/ |
72
|
|
|
public function addReporter(ReporterInterface $reporter) |
73
|
|
|
{ |
74
|
|
|
$this->reporters[] = $reporter; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Report violations to BitBucket pull request. |
79
|
|
|
*/ |
80
|
|
|
public function report() |
81
|
|
|
{ |
82
|
|
|
foreach ($this->reporters as $reporter) { |
83
|
|
|
$reporter->report($this, $this->logger); |
84
|
|
|
} |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Get pull request author username. |
89
|
|
|
* |
90
|
|
|
* @return string Pull request author username |
91
|
|
|
*/ |
92
|
|
|
public function getPullRequestAuthor() |
93
|
|
|
{ |
94
|
|
|
$responseString = $this->pullRequests->get($this->accountName, $this->repoName, $this->pullRequestId); |
95
|
|
|
try { |
96
|
|
|
$responseObject = json_decode($responseString->getContent()); |
97
|
|
|
|
98
|
|
|
if (isset($responseObject->error)) { |
99
|
|
|
$this->logger->critical($responseObject->error->message); |
100
|
|
|
} elseif (isset($responseObject->author)) { |
101
|
|
|
return $responseObject->author->username; |
102
|
|
|
} else { |
103
|
|
|
$this->logger->log(ConsoleLogger::INFO, 'BitBucket response has no values'); |
104
|
|
|
} |
105
|
|
|
} catch (\InvalidArgumentException $exception) { |
106
|
|
|
$this->logger->critical('Cannot json_decode BitBucket response'); |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Collection of changed files in pull request. |
112
|
|
|
* |
113
|
|
|
* @return string[] Collection of changed files |
114
|
|
|
*/ |
115
|
|
|
public function getChangedFiles() |
116
|
|
|
{ |
117
|
|
|
$files = []; |
118
|
|
|
$responseString = $this->pullRequests->commits($this->accountName, $this->repoName, $this->pullRequestId); |
119
|
|
|
|
120
|
|
|
try { |
121
|
|
|
$responseObject = json_decode($responseString->getContent()); |
122
|
|
|
|
123
|
|
|
if (isset($responseObject->error)) { |
124
|
|
|
$this->logger->critical($responseObject->error->message); |
125
|
|
|
} elseif (isset($responseObject->values) && is_array($responseObject->values)) { |
126
|
|
|
foreach ($responseObject->values as $commit) { |
127
|
|
|
$changeSet = $this->changesets->diffstat($this->accountName, $this->repoName, $commit->hash); |
|
|
|
|
128
|
|
|
$files[] = json_decode($changeSet->getContent())[0]->file; |
129
|
|
|
} |
130
|
|
|
} else { |
131
|
|
|
$this->logger->log(ConsoleLogger::INFO, 'BitBucket response has no values'); |
132
|
|
|
} |
133
|
|
|
} catch (\InvalidArgumentException $exception) { |
134
|
|
|
$this->logger->critical('Cannot json_decode BitBucket response'); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
return $files; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Create general pull request comment. |
142
|
|
|
* |
143
|
|
|
* @param string $content The comment content |
144
|
|
|
* |
145
|
|
|
* @return MessageInterface |
146
|
|
|
*/ |
147
|
|
|
public function createGeneralComment(string $content) |
148
|
|
|
{ |
149
|
|
|
return $this->postComment(['content' => $content]); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* Add a new comment to pull request. |
154
|
|
|
* |
155
|
|
|
* @param string $content The comment content |
156
|
|
|
* @param null|string $filename File name |
157
|
|
|
* @param int|null $lineFrom Source code line number |
158
|
|
|
* |
159
|
|
|
* @return MessageInterface |
160
|
|
|
*/ |
161
|
|
|
public function createFileComment(string $content, string $filename = null, int $lineFrom = null) : MessageInterface |
162
|
|
|
{ |
163
|
|
|
$this->logger->log(ConsoleLogger::INFO, 'Creating comment in: '.$filename.'#'.$lineFrom.' - '.$content); |
164
|
|
|
|
165
|
|
|
return $this->postComment([ |
166
|
|
|
'content' => $content, |
167
|
|
|
'filename' => $filename, |
168
|
|
|
'line_from' => $lineFrom |
169
|
|
|
]); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* Low level post request for creating pull request comment. |
174
|
|
|
* |
175
|
|
|
* @param array $commentData Comment data |
176
|
|
|
* |
177
|
|
|
* @return MessageInterface |
178
|
|
|
*/ |
179
|
|
|
protected function postComment(array $commentData) |
180
|
|
|
{ |
181
|
|
|
// Add pull request author |
182
|
|
|
$commentData['content'] = '@'.$this->author.' '.$commentData['content']; |
183
|
|
|
|
184
|
|
|
// Switch to old API version |
185
|
|
|
$this->pullRequests->getClient()->setApiVersion('1.0'); |
186
|
|
|
|
187
|
|
|
return $this->pullRequests->comments()->requestPost( |
188
|
|
|
sprintf('repositories/%s/%s/pullrequests/%d/comments', $this->accountName, $this->repoName, $this->pullRequestId), |
189
|
|
|
$commentData |
190
|
|
|
); |
191
|
|
|
} |
192
|
|
|
} |
193
|
|
|
|
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.