Skip to content

Commit

Permalink
Merge 7ba3f96 into 431b930
Browse files Browse the repository at this point in the history
  • Loading branch information
eiriksm committed Jul 13, 2022
2 parents 431b930 + 7ba3f96 commit d761cd5
Show file tree
Hide file tree
Showing 24 changed files with 849 additions and 20 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"knplabs/github-api": "^2.0",
"php-http/guzzle6-adapter": "^1.1",
"violinist-dev/git-log-format": "^1.1.2",
"violinist-dev/violinist-messages": "^1.3.1",
"violinist-dev/violinist-messages": "^1.4.0",
"violinist-dev/slug-from-url": "^1",
"wa72/simplelogger": "^1.0",
"league/flysystem": "^1.0",
Expand Down
61 changes: 52 additions & 9 deletions src/CosyComposer.php
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,41 @@ protected function exportEnvVars()
}
}

protected function closeOutdatedPrsForPackage($package_name, $current_version, Config $config, $pr_id, $prs_named)
{
$fake_item = (object) [
'name' => $package_name,
'version' => $current_version,
'latest' => '',
];
$branch_name_prefix = $this->createBranchName($fake_item, false, $config);
foreach ($prs_named as $branch_name => $pr) {
if ($pr["number"] == $pr_id) {
// We really don't want to close the one we are considering as the latest one, do we?
continue;
}
// We are just going to assume, if the number of the PR does not match. And the branch name does
// indeed "match", well. Match as in it updates the exact package from the exact same version. Then
// the current/recent PR will update to a newer version. Or it could also be that the branch was
// created while the project was using one PR per version, and then they switched. Either way. These
// two scenarios are both scenarios we want to handle in such a way that we are closing this PR that
// is matching.
if (strpos($branch_name, $branch_name_prefix) === false) {
continue;
}
$comment = $this->messageFactory->getPullRequestClosedMessage($pr_id);
$pr_number = $pr['number'];
$this->getLogger()->log('info', new Message("Trying to close PR number $pr_number since it has been superseded by $pr_id"));
try {
$this->getPrClient()->closePullRequestWithComment($this->slug, $pr_number, $comment);
$this->getLogger()->log('info', new Message("Successfully closed PR $pr_number"));
} catch (\Throwable $e) {
$msg = $e->getMessage();
$this->getLogger()->log('error', new Message("Caught an exception trying to close pr $pr_number. The message was '$msg'"));
}
}
}

/**
* @throws \eiriksm\CosyComposer\Exceptions\ChdirException
* @throws \eiriksm\CosyComposer\Exceptions\GitCloneException
Expand Down Expand Up @@ -909,14 +944,7 @@ public function run()
// Safe to ignore.
$this->log('Had a runtime exception with the fetching of branches and Prs: ' . $e->getMessage());
}
$violinist_config = (object) [];
if (!empty($composer_json_data->extra) && !empty($composer_json_data->extra->violinist)) {
$violinist_config = $composer_json_data->extra->violinist;
}
$one_pr_per_dependency = false;
if (!empty($violinist_config->one_pull_request_per_package)) {
$one_pr_per_dependency = (bool) $violinist_config->one_pull_request_per_package;
}
$one_pr_per_dependency = $config->shouldUseOnePullRequestPerPackage();
foreach ($data as $delta => $item) {
$branch_name = $this->createBranchName($item, $one_pr_per_dependency, $config);
if (in_array($branch_name, $branches_flattened)) {
Expand All @@ -927,6 +955,7 @@ public function run()
'package' => $item->name,
]);
unset($data[$delta]);
$this->closeOutdatedPrsForPackage($item->name, $item->version, $config, $prs_named[$branch_name]['number'], $prs_named);
$total_prs++;
}
// Is the pr up to date?
Expand Down Expand Up @@ -967,6 +996,7 @@ public function run()
$context['url'] = $prs_named[$branch_name]['html_url'];
}
$this->log(sprintf('Skipping %s because a pull request already exists', $item->name), Message::PR_EXISTS, $context);
$this->closeOutdatedPrsForPackage($item->name, $item->version, $config, $prs_named[$branch_name]['number'], $prs_named);
unset($data[$delta]);
$total_prs++;
}
Expand Down Expand Up @@ -1433,7 +1463,7 @@ protected function handleIndividualUpdates($data, $lockdata, $cdata, $one_pr_per
$post_update_data->version,
$config
);
$this->log('Changing branch because of an unexpected update result: ' . $branch_name);
$this->log(sprintf('Changing branch because of an unexpected update result. We expected the branch name to be %s but instead we are now switching to %s.', $branch_name, $new_branch_name));
$this->execCommand('git checkout -b ' . $new_branch_name, false);
$branch_name = $new_branch_name;
// Check if this new branch name has a pr up-to-date.
Expand All @@ -1443,6 +1473,7 @@ protected function handleIndividualUpdates($data, $lockdata, $cdata, $one_pr_per
'package' => $item->name,
]);
$total_prs++;
$this->closeOutdatedPrsForPackage($item->name, $item->version, $config, $prs_named[$branch_name]['number'], $prs_named);
continue;
}
// Is the pr up to date?
Expand All @@ -1451,6 +1482,7 @@ protected function handleIndividualUpdates($data, $lockdata, $cdata, $one_pr_per
'package' => $item->name,
]);
$total_prs++;
$this->closeOutdatedPrsForPackage($item->name, $item->version, $config, $prs_named[$branch_name]['number'], $prs_named);
continue;
}
}
Expand Down Expand Up @@ -1489,6 +1521,9 @@ protected function handleIndividualUpdates($data, $lockdata, $cdata, $one_pr_per
'package' => $package_name,
]);
$this->handleAutomerge($config, $pullRequest, $security_update);
if (!empty($pullRequest['number'])) {
$this->closeOutdatedPrsForPackage($item->name, $item->version, $config, $pullRequest['number'], $prs_named);
}
}
$total_prs++;
} catch (CanNotUpdateException $e) {
Expand Down Expand Up @@ -1525,8 +1560,16 @@ protected function handleIndividualUpdates($data, $lockdata, $cdata, $one_pr_per
} catch (ValidationFailedException $e) {
// @todo: Do some better checking. Could be several things, this.
$this->handlePossibleUpdatePrScenario($e, $branch_name, $pr_params, $prs_named, $config, $security_update);
// If it failed validation because it already exists, we also want to make sure all outdated PRs are
// closed.
if (!empty($prs_named[$branch_name]['number'])) {
$this->closeOutdatedPrsForPackage($item->name, $item->version, $config, $prs_named[$branch_name]['number'], $prs_named);
}
} catch (\Gitlab\Exception\RuntimeException $e) {
$this->handlePossibleUpdatePrScenario($e, $branch_name, $pr_params, $prs_named, $config, $security_update);
if (!empty($prs_named[$branch_name]['number'])) {
$this->closeOutdatedPrsForPackage($item->name, $item->version, $config, $prs_named[$branch_name]['number'], $prs_named);
}
} catch (ComposerUpdateProcessFailedException $e) {
$this->log('Caught an exception: ' . $e->getMessage(), 'error');
$this->log($e->getErrorOutput(), Message::COMMAND, [
Expand Down
2 changes: 2 additions & 0 deletions src/ProviderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public function getDefaultBase(Slug $slug, $default_branch);

public function createFork($user, $repo, $fork_user);

public function closePullRequestWithComment(Slug $slug, $pr_id, $comment);

/**
* @param Slug $slug
* @param array $params
Expand Down
14 changes: 14 additions & 0 deletions src/Providers/Bitbucket.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public function getPrsNamed(Slug $slug) : array
'base' => [
'sha' => $pr["destination"]["commit"]["hash"],
],
'html_url' => $pr["links"]["html"]["href"],
'number' => $pr["id"],
'title' => $pr["title"],
];
Expand Down Expand Up @@ -160,6 +161,9 @@ public function createPullRequest(Slug $slug, $params)
if (!empty($data["links"]["html"]["href"])) {
$data['html_url'] = $data["links"]["html"]["href"];
}
if (!empty($data['id'])) {
$data['number'] = $data['id'];
}
return $data;
}

Expand All @@ -175,4 +179,14 @@ public function enableAutomerge(array $pr_data, Slug $slug) : bool
// @todo: Not implemented yet.
return false;
}

public function closePullRequestWithComment(Slug $slug, $pr_id, $comment)
{
$this->client->repositories()->users($slug->getUserName())->pullRequests($slug->getUserRepo())->comments($pr_id)->create([
'content' => [
'raw' => $comment,
]
]);
$this->client->repositories()->users($slug->getUserName())->pullRequests($slug->getUserRepo())->decline($pr_id);
}
}
10 changes: 10 additions & 0 deletions src/Providers/Github.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,14 @@ public function updatePullRequest(Slug $slug, $id, $params)
$user_repo = $slug->getUserRepo();
return $this->client->api('pull_request')->update($user_name, $user_repo, $id, $params);
}

public function closePullRequestWithComment(Slug $slug, $pr_id, $comment)
{
$this->client->issue()->comments()->create($slug->getUserName(), $slug->getUserRepo(), $pr_id, [
'body' => $comment,
]);
$this->client->api('pull_request')->update($slug->getUserName(), $slug->getUserRepo(), $pr_id, [
'state' => 'closed',
]);
}
}
11 changes: 11 additions & 0 deletions src/Providers/Gitlab.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ public function createFork($user, $repo, $fork_user)
throw new \Exception('Gitlab integration only support creating PRs as the authenticated user.');
}

public function closePullRequestWithComment(Slug $slug, $pr_id, $comment)
{
$this->client->mergeRequests()->addNote(self::getProjectId($slug->getUrl()), $pr_id, $comment);
$this->client->mergeRequests()->update(self::getProjectId($slug->getUrl()), $pr_id, [
'state_event' => 'close',
]);
}

public function createPullRequest(Slug $slug, $params)
{
/** @var MergeRequests $mr */
Expand All @@ -128,6 +136,9 @@ public function createPullRequest(Slug $slug, $params)
if (!empty($data['web_url'])) {
$data['html_url'] = $data['web_url'];
}
if (!empty($data['iid'])) {
$data['number'] = $data['iid'];
}
// Try to update with assignees.
if (!empty($params['assignees'])) {
$new_data = [
Expand Down
5 changes: 5 additions & 0 deletions test/fixtures/composer.close.outdated.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": {
"psr/log": "^1.0.0"
}
}
61 changes: 61 additions & 0 deletions test/fixtures/composer.close.outdated.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "034b92110b75e440ec32808b291e1717",
"packages": [
{
"name": "psr/log",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
"shasum": ""
},
"type": "library",
"autoload": {
"psr-0": {
"Psr\\Log\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"issues": "https://github.com/php-fig/log/issues",
"source": "https://github.com/php-fig/log/tree/1.0.0"
},
"time": "2012-12-21T11:40:51+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.3.0"
}
69 changes: 69 additions & 0 deletions test/fixtures/composer.close.outdated.lock.updated
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "034b92110b75e440ec32808b291e1717",
"packages": [
{
"name": "psr/log",
"version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/1.1.4"
},
"time": "2021-05-03T11:20:27+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.3.0"
}
10 changes: 10 additions & 0 deletions test/fixtures/composer.close.outdated.one_per.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"require": {
"psr/log": "^1.0.0"
},
"extra": {
"violinist": {
"one_pull_request_per_package": 1
}
}
}

0 comments on commit d761cd5

Please sign in to comment.