Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php: ['8.2', '8.3']
php: ['8.2', '8.3', '8.4', '8.5']
steps:
- uses: actions/checkout@v6

Expand Down
5 changes: 3 additions & 2 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
->setRules([
'@PSR12' => true,
'@PSR12:risky' => true,
'@PHP74Migration' => true,
'@PHP74Migration:risky' => true,
'@PHP82Migration' => true,
'@PHP80Migration:risky' => true,
'@PhpCsFixer' => true,
'@Symfony' => true,
'@Symfony:risky' => true,
'declare_strict_types' => ['strategy' => 'enforce'],
// Ensure there is no code on the same line as the PHP open tag and it is followed by a blank line.
'blank_line_after_opening_tag' => false,
// Using `isset($var) &&` multiple times should be done in one call.
Expand Down
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@
"require-dev": {
"friendsofphp/php-cs-fixer": "dev-master",
"phpunit/phpunit": "^11.5",
"phpstan/phpstan": "^1.12.9",
"phpstan/phpstan-phpunit": "^1.4.0",
"phpstan/phpstan": "^2.1",
"phpstan/phpstan-phpunit": "^2",
"phpstan/extension-installer": "^1.4.3",
"phpstan/phpstan-deprecation-rules": "^1.2.1",
"phpstan/phpstan-strict-rules": "^1.6.1",
"phpstan/phpstan-deprecation-rules": "^2",
"phpstan/phpstan-strict-rules": "^2",
"infection/infection": "^0.29.14"
},
"scripts": {
Expand Down
1 change: 0 additions & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
parameters:
level: max
inferPrivatePropertyTypeFromConstructor: true
reportUnmatchedIgnoredErrors: false

paths:
Expand Down
2 changes: 1 addition & 1 deletion src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function __construct()
/** @var Command $command */
$command = $this->container->get($taggedService);

$this->add($command);
$this->addCommand($command);
}
}

Expand Down
11 changes: 8 additions & 3 deletions src/Command/LocalCommand.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php declare(strict_types=1);
<?php
declare(strict_types=1);

namespace Danger\Command;

Expand Down Expand Up @@ -47,15 +48,19 @@ public function execute(InputInterface $input, OutputInterface $output): int
if ($headBranch === null) {
$process = new Process(['git', 'symbolic-ref', '--short', 'refs/remotes/origin/HEAD'], $root);
$process->mustRun();
$headBranch = trim($process->getOutput());
$headBranch = mb_trim($process->getOutput());
}

$process = new Process(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], $root);
$process->mustRun();
$localBranch = trim($process->getOutput());
$localBranch = mb_trim($process->getOutput());

$config = $this->configLoader->loadByPath($configPath);

if (!\is_string($headBranch)) {
throw new \InvalidArgumentException('Invalid head-branch option given');
}

$this->localPlatform->load($root, $localBranch . '|' . $headBranch);

$context = new Context($this->localPlatform);
Expand Down
2 changes: 1 addition & 1 deletion src/DependencyInjection/Factory/GithubClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static function build(): Client
{
$client = new Client();

if (isset($_SERVER['GITHUB_TOKEN'])) {
if (isset($_SERVER['GITHUB_TOKEN']) && \is_string($_SERVER['GITHUB_TOKEN'])) {
$client->authenticate($_SERVER['GITHUB_TOKEN'], null, AuthMethod::ACCESS_TOKEN);
}

Expand Down
4 changes: 2 additions & 2 deletions src/DependencyInjection/Factory/GitlabClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ public static function build(): Client
{
$client = new Client();

if (isset($_SERVER['CI_SERVER_URL'])) {
if (isset($_SERVER['CI_SERVER_URL']) && \is_string($_SERVER['CI_SERVER_URL'])) {
$client->setUrl($_SERVER['CI_SERVER_URL']);
}

if (isset($_SERVER['DANGER_GITLAB_TOKEN'])) {
if (isset($_SERVER['DANGER_GITLAB_TOKEN']) && \is_string($_SERVER['DANGER_GITLAB_TOKEN'])) {
$client->authenticate($_SERVER['DANGER_GITLAB_TOKEN'], Client::AUTH_HTTP_TOKEN);
}

Expand Down
5 changes: 3 additions & 2 deletions src/Platform/Github/Github.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,11 @@ private function getReviews(string $owner, string $repository, string $id): arra
{
$requestedReviewers = array_map(static fn (array $reviewer): string => $reviewer['login'], $this->raw['requested_reviewers']);

/** @var list<array{user: array{login: string}}> $reviewersRequest */
$reviewersRequest = $this->client->pullRequest()->reviews()->all($owner, $repository, (int) $id);
$reviewers = array_map(static fn (array $reviewer) => $reviewer['user']['login'], $reviewersRequest);
$reviewers = array_map(static fn (array $reviewer): string => $reviewer['user']['login'], $reviewersRequest);

return array_unique(array_merge($requestedReviewers, $reviewers));
return array_values(array_unique(array_merge($requestedReviewers, $reviewers)));
}

public function hasDangerMessage(): bool
Expand Down
11 changes: 8 additions & 3 deletions src/Platform/Github/GithubCommenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ public function comment(string $owner, string $repo, string $id, string $body, C
private function commentUsingProxy(string $owner, string $repo, string $id, string $body, Config $config): string
{
$url = sprintf('%s/repos/%s/%s/issues/%s/comments', $config->getGithubCommentProxy(), $owner, $repo, $id);
/** @var array{html_url?: string} $response */
$response = $this->httpClient->request('POST', $url, [
'json' => ['body' => $body, 'mode' => $config->getUpdateCommentMode()],
'headers' => [
'User-Agent' => 'Comment-Proxy',
'temporary-github-token' => $_SERVER['GITHUB_TOKEN'],
'temporary-github-token' => \is_string($_SERVER['GITHUB_TOKEN'] ?? null) ? $_SERVER['GITHUB_TOKEN'] : '',
],
])->toArray();

Expand All @@ -54,6 +55,7 @@ private function commentUsingApiKey(string $owner, string $repo, string $id, str
$this->client->issues()->comments()->remove($owner, $repo, $commentId);
}

/** @var array{html_url: string} $comment */
$comment = $this->client->issues()->comments()->create($owner, $repo, (int) $id, ['body' => $body]);

return $comment['html_url'];
Expand All @@ -63,6 +65,7 @@ private function commentUsingApiKey(string $owner, string $repo, string $id, str
* Could not find any comment. Lets create a new one
*/
if (\count($ids) === 0) {
/** @var array{html_url: string} $comment */
$comment = $this->client->issues()->comments()->create($owner, $repo, (int) $id, ['body' => $body]);

return $comment['html_url'];
Expand All @@ -75,6 +78,7 @@ private function commentUsingApiKey(string $owner, string $repo, string $id, str
*/
foreach ($ids as $i => $commentId) {
if ($i === 0) {
/** @var array{html_url: string} $comment */
$comment = $this->client->issues()->comments()->update($owner, $repo, $commentId, ['body' => $body]);

$url = $comment['html_url'];
Expand All @@ -95,11 +99,12 @@ public function getCommentIds(string $owner, string $repo, string $id): array
$ids = [];

$pager = new ResultPager($this->client);
/** @var list<array{id: int, body: string}> $comments */
$comments = $pager->fetchAll($this->client->issues()->comments(), 'all', [$owner, $repo, (int) $id]);

foreach ($comments as $comment) {
if (str_contains($comment['body'], HTMLRenderer::MARKER)) {
$ids[] = (int) $comment['id'];
$ids[] = $comment['id'];
}
}

Expand All @@ -114,7 +119,7 @@ public function remove(string $owner, string $repo, string $id, Config $config):
'json' => ['body' => 'delete', 'mode' => $config->getUpdateCommentMode()],
'headers' => [
'User-Agent' => 'Comment-Proxy',
'temporary-github-token' => $_SERVER['GITHUB_TOKEN'],
'temporary-github-token' => \is_string($_SERVER['GITHUB_TOKEN'] ?? null) ? $_SERVER['GITHUB_TOKEN'] : '',
],
])->toArray();

Expand Down
6 changes: 4 additions & 2 deletions src/Platform/Gitlab/GitlabCommenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public function removeThread(string $projectIdentifier, int $prId): void
public function getRelevantNoteIds(string $projectIdentifier, int $prId): array
{
$pager = new ResultPager($this->client, 100);
/** @var list<array{id: int, system: bool, body: string}> $notes */
$notes = $pager->fetchAll($this->client->mergeRequests(), 'showNotes', [$projectIdentifier, $prId]);

$ids = [];
Expand All @@ -111,7 +112,7 @@ public function getRelevantNoteIds(string $projectIdentifier, int $prId): array
}

if (str_contains($note['body'], HTMLRenderer::MARKER)) {
$ids[] = (int) $note['id'];
$ids[] = $note['id'];
}
}

Expand All @@ -124,6 +125,7 @@ public function getRelevantNoteIds(string $projectIdentifier, int $prId): array
private function getRelevantThreadIds(string $projectIdentifier, int $prId): array
{
$pager = new ResultPager($this->client, 100);
/** @var list<array{id: string, notes: list<array{id: int, body: string}>}> $threads */
$threads = $pager->fetchAll($this->client->mergeRequests(), 'showDiscussions', [$projectIdentifier, $prId]);

$ids = [];
Expand All @@ -132,7 +134,7 @@ private function getRelevantThreadIds(string $projectIdentifier, int $prId): arr
if (str_contains($thread['notes'][0]['body'], HTMLRenderer::MARKER)) {
$ids[] = [
'threadId' => $thread['id'],
'noteId' => (int) $thread['notes'][0]['id'],
'noteId' => $thread['notes'][0]['id'],
'noteBody' => $thread['notes'][0]['body'],
];
}
Expand Down
14 changes: 12 additions & 2 deletions src/Platform/PlatformDetector.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,24 @@ public function detect(): AbstractPlatform

private function createFromGithubContext(): AbstractPlatform
{
$this->github->load($_SERVER['GITHUB_REPOSITORY'], $_SERVER['GITHUB_PULL_REQUEST_ID']);
/** @var string $repository */
$repository = $_SERVER['GITHUB_REPOSITORY'];
/** @var string $pullRequestId */
$pullRequestId = $_SERVER['GITHUB_PULL_REQUEST_ID'];

$this->github->load($repository, $pullRequestId);

return $this->github;
}

private function createFromGitlabContext(): AbstractPlatform
{
$this->gitlab->load($_SERVER['CI_PROJECT_ID'], $_SERVER['CI_MERGE_REQUEST_IID']);
/** @var string $projectId */
$projectId = $_SERVER['CI_PROJECT_ID'];
/** @var string $mergeRequestIid */
$mergeRequestIid = $_SERVER['CI_MERGE_REQUEST_IID'];

$this->gitlab->load($projectId, $mergeRequestIid);

return $this->gitlab;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Rule/DisallowRepeatedCommits.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function __invoke(Context $context): void
if ($context->platform instanceof Github) {
$messages = array_filter(
$messages,
fn ($message) => !(preg_match('/^Merge branch .* into .*$/', $message) === 1),
static fn ($message) => !(preg_match('/^Merge branch .* into .*$/', $message) === 1),
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Struct/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public function reduce(\Closure $closure, mixed $initial = null): mixed
*/
public function fmap(\Closure $closure): array
{
return array_filter($this->map($closure));
return array_filter($this->map($closure), static fn (mixed $value): bool => (bool) $value);
}

public function sort(\Closure $closure): void
Expand Down
15 changes: 10 additions & 5 deletions src/Struct/Github/PullRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class PullRequest extends \Danger\Struct\PullRequest
private ?CommentCollection $comments = null;

/**
* @var list<array{filename: string, status: string, additions: int, deletions: int, changes: int, patch: string}>
* @var list<array{filename: string, status: string, additions: int, deletions: int, changes: int, patch?: string}>
*/
public array $rawFiles = [];

Expand All @@ -46,11 +46,13 @@ public function getCommits(): CommitCollection
return $this->commits;
}

$this->rawCommits = $this->client->pullRequest()->commits($this->owner, $this->repo, $this->id);
/** @var list<array{sha: string, commit: array{message: string, committer: array{date: string, name: string, email: string}, verification: array{verified: bool}}}> $rawCommits */
$rawCommits = $this->client->pullRequest()->commits($this->owner, $this->repo, $this->id);
$this->rawCommits = $rawCommits;

$collection = new CommitCollection();

foreach ($this->rawCommits as $rawGithubCommit) {
foreach ($rawCommits as $rawGithubCommit) {
$commit = new Commit();
$commit->sha = $rawGithubCommit['sha'];
$commit->createdAt = new \DateTime($rawGithubCommit['commit']['committer']['date']);
Expand All @@ -76,13 +78,15 @@ public function getFiles(): FileCollection
return $this->files;
}

$this->rawFiles = (new ResultPager($this->client))
/** @var list<array{filename: string, status: string, additions: int, deletions: int, changes: int, patch?: string}> $rawFiles */
$rawFiles = (new ResultPager($this->client))
->fetchAll($this->client->pullRequest(), 'files', [$this->owner, $this->repo, $this->id])
;
$this->rawFiles = $rawFiles;

$collection = new FileCollection();

foreach ($this->rawFiles as $rawGithubFile) {
foreach ($rawFiles as $rawGithubFile) {
$file = new GithubFile($this->client, $this->owner, $this->repo, $rawGithubFile['filename'], $this->headSha);
$file->name = $rawGithubFile['filename'];
$file->status = $rawGithubFile['status'];
Expand All @@ -107,6 +111,7 @@ public function getComments(): CommentCollection
}

$pager = new ResultPager($this->client);
/** @var list<array{user: array{login: string}, body: string, created_at: string, updated_at: string}> $list */
$list = $pager->fetchAll($this->client->pullRequest()->comments(), 'all', [$this->owner, $this->repo, $this->id]);
$this->comments = new CommentCollection();

Expand Down
1 change: 1 addition & 0 deletions src/Struct/Gitlab/PullRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ public function getComments(): CommentCollection
$this->comments = new CommentCollection();

$pager = new ResultPager($this->client);
/** @var list<array{system: bool, author: array{username: string}, body: string, created_at: string, updated_at: string}> $list */
$list = $pager->fetchAll($this->client->mergeRequests(), 'showNotes', [$this->projectIdentifier, (int) $this->id]);

foreach ($list as $commentArray) {
Expand Down
5 changes: 3 additions & 2 deletions src/Struct/Local/LocalPullRequest.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php declare(strict_types=1);
<?php
declare(strict_types=1);

namespace Danger\Struct\Local;

Expand Down Expand Up @@ -106,7 +107,7 @@ public function getFiles(): FileCollection
}

$status = $line[0];
$file = trim(mb_substr($line, 1));
$file = mb_trim(mb_substr($line, 1));

$element = new LocalFile($this->repo . '/' . $file);
$element->name = $file;
Expand Down
2 changes: 1 addition & 1 deletion src/Struct/PullRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ abstract class PullRequest
public array $reviewers = [];

/**
* @var array<string, array{'id': string, 'committed_date': string, 'message': 'string', 'author_name': string, 'author_email': string}|string>
* @var array<mixed>
*/
public array $rawCommits = [];

Expand Down
4 changes: 2 additions & 2 deletions tests/RunnerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ public function testRunner(): void
$afterExecuted = false;

$config = new Config();
$config->useRule(function () use (&$ruleExecuted, &$afterExecuted): void {
$config->useRule(static function () use (&$ruleExecuted, &$afterExecuted): void {
static::assertFalse($afterExecuted); /** @phpstan-ignore-line */
$ruleExecuted = true;
});

$config->after(function () use (&$ruleExecuted, &$afterExecuted): void {
$config->after(static function () use (&$ruleExecuted, &$afterExecuted): void {
static::assertTrue($ruleExecuted);
$afterExecuted = true;
});
Expand Down
2 changes: 1 addition & 1 deletion tests/Struct/FileCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public function testMap(): void
$f1->name = 'A';

$c = new FileCollection([$f1]);
$list = $c->fmap(fn (FakeFile $file) => $file->name);
$list = $c->fmap(static fn (FakeFile $file) => $file->name);

static::assertSame(['A'], $list);
}
Expand Down
5 changes: 3 additions & 2 deletions tests/configs/all.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<?php declare(strict_types=1);
<?php
declare(strict_types=1);

use Danger\Config;

return
(new Config())
->useRule(function (Danger\Context $context): void {
->useRule(static function (Danger\Context $context): void {
$context->failure('A Failure');
$context->warning('A Warning');
$context->notice('A Notice');
Expand Down
5 changes: 3 additions & 2 deletions tests/configs/warning.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<?php declare(strict_types=1);
<?php
declare(strict_types=1);

use Danger\Config;

return
(new Config())
->useRule(function (Danger\Context $context): void {
->useRule(static function (Danger\Context $context): void {
$context->warning('Test');
})
;
Loading