From 6a6e0a82272bd6052ce27e0109c5cca773539c8a Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Tue, 9 Aug 2016 21:28:02 -0300 Subject: [PATCH 1/7] Add `remove-source-branch` option to `pull-request:merge` command --- .../PullRequest/PullRequestMergeCommand.php | 22 +++++++++++++++---- src/ThirdParty/Github/GitHubAdapter.php | 8 +++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/Command/PullRequest/PullRequestMergeCommand.php b/src/Command/PullRequest/PullRequestMergeCommand.php index aefaf354..02fa9c2a 100644 --- a/src/Command/PullRequest/PullRequestMergeCommand.php +++ b/src/Command/PullRequest/PullRequestMergeCommand.php @@ -42,6 +42,7 @@ protected function configure() ->addOption('force-squash', null, InputOption::VALUE_NONE, 'Force squashing the PR, even if there are multiple authors (this will implicitly use --squash)') ->addOption('switch', null, InputOption::VALUE_REQUIRED, 'Switch the base of the pull request before merging') ->addOption('pat', null, InputOption::VALUE_REQUIRED, 'Give the PR\'s author a pat on the back after the merge') + ->addOption('remove-source-branch', null, InputOption::VALUE_NONE, 'Remove remote source branch after merging own pull request') ->setHelp( <<<'EOF' The %command.name% command merges the given pull request: @@ -99,6 +100,11 @@ protected function configure() which has precedence to the predefined configuration. The whole pat configuration will be ignored and no pat will be placed if the pull request is authored by yourself! + +If you are the author of the pull request, --remove-source-branch can be used in order to remove the remote source +branch after a successful merge: + + $ gush %command.name% --remove-source-branch EOF ) ; @@ -141,6 +147,12 @@ protected function execute(InputInterface $input, OutputInterface $output) $targetLabel = sprintf('Target: %s/%s', $targetRemote, $targetBranch); } + $authenticatedUser = $this->getParameter($input, 'authentication')['username']; + $removeSourceBranch = $input->getOption('remove-source-branch'); + if ($removeSourceBranch && $pr['user'] !== $authenticatedUser) { + throw new UserException(sprintf('`--remove-source-branch` option cannot be used with pull requests that aren\'t owned by the authenticated user (%s)', $authenticatedUser)); + } + $styleHelper->title(sprintf('Merging pull-request #%d - %s', $prNumber, $pr['title'])); $styleHelper->text([sprintf('Source: %s/%s', $sourceRemote, $sourceBranch), $targetLabel]); @@ -197,11 +209,13 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->addClosedPullRequestNote($pr, $mergeCommit, $squash, $input->getOption('switch')); } - if ($pr['user'] !== $this->getParameter($input, 'authentication')['username']) { - $patComment = $this->givePatToPullRequestAuthor($pr, $input->getOption('pat')); - if ($patComment) { - $styleHelper->note(sprintf('Pat given to @%s at %s.', $pr['user'], $patComment)); + if ($pr['user'] === $authenticatedUser) { + if ($removeSourceBranch) { + $adapter->removePullRequestSourceBranch($pr['number']); + $styleHelper->note(sprintf('Remote source branch %s:%s has been removed.', $sourceRemote, $sourceBranch)); } + } elseif ($patComment = $this->givePatToPullRequestAuthor($pr, $input->getOption('pat'))) { + $styleHelper->note(sprintf('Pat given to @%s at %s.', $pr['user'], $patComment)); } $styleHelper->success([$mergeNote, $pr['url']]); diff --git a/src/ThirdParty/Github/GitHubAdapter.php b/src/ThirdParty/Github/GitHubAdapter.php index ca02dbfd..fa19582e 100644 --- a/src/ThirdParty/Github/GitHubAdapter.php +++ b/src/ThirdParty/Github/GitHubAdapter.php @@ -625,6 +625,14 @@ public function createReleaseAssets($id, $name, $contentType, $content) return $asset['id']; } + public function removePullRequestSourceBranch($id) + { + $api = $this->client->api('git_data')->references(); + $pr = $this->getPullRequest($id); + + return $api->remove($pr['user'], $pr['head']['repo'], 'heads/'.$pr['head']['ref']); + } + protected function adaptIssueStructure(array $issue) { return [ From b7507eb2db01391333b9c6b6bcd780dbdf4db4aa Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Thu, 11 Aug 2016 00:41:02 -0300 Subject: [PATCH 2/7] Update help and behavior --- .../PullRequest/PullRequestMergeCommand.php | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Command/PullRequest/PullRequestMergeCommand.php b/src/Command/PullRequest/PullRequestMergeCommand.php index 02fa9c2a..d30c45a9 100644 --- a/src/Command/PullRequest/PullRequestMergeCommand.php +++ b/src/Command/PullRequest/PullRequestMergeCommand.php @@ -42,7 +42,7 @@ protected function configure() ->addOption('force-squash', null, InputOption::VALUE_NONE, 'Force squashing the PR, even if there are multiple authors (this will implicitly use --squash)') ->addOption('switch', null, InputOption::VALUE_REQUIRED, 'Switch the base of the pull request before merging') ->addOption('pat', null, InputOption::VALUE_REQUIRED, 'Give the PR\'s author a pat on the back after the merge') - ->addOption('remove-source-branch', null, InputOption::VALUE_NONE, 'Remove remote source branch after merging own pull request') + ->addOption('remove-source-branch', null, InputOption::VALUE_REQUIRED, 'Remove remote source branch after merging own pull request', 'no') ->setHelp( <<<'EOF' The %command.name% command merges the given pull request: @@ -101,10 +101,11 @@ protected function configure() The whole pat configuration will be ignored and no pat will be placed if the pull request is authored by yourself! -If you are the author of the pull request, --remove-source-branch can be used in order to remove the remote source -branch after a successful merge: +If you are the author of the pull request, you'll be prompted if the remote source +branch will be removed after a successful merge. +Also, you can pass your choice for this action with the --remove-source-branch option: - $ gush %command.name% --remove-source-branch + $ gush %command.name% --remove-source-branch=[yes|no] EOF ) ; @@ -149,7 +150,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $authenticatedUser = $this->getParameter($input, 'authentication')['username']; $removeSourceBranch = $input->getOption('remove-source-branch'); - if ($removeSourceBranch && $pr['user'] !== $authenticatedUser) { + if ('yes' === $removeSourceBranch && $pr['user'] !== $authenticatedUser) { throw new UserException(sprintf('`--remove-source-branch` option cannot be used with pull requests that aren\'t owned by the authenticated user (%s)', $authenticatedUser)); } @@ -209,8 +210,14 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->addClosedPullRequestNote($pr, $mergeCommit, $squash, $input->getOption('switch')); } + $styleHelper->success([$mergeNote, $pr['url']]); + + // Post merge options if ($pr['user'] === $authenticatedUser) { - if ($removeSourceBranch) { + if ('yes' !== $removeSourceBranch) { + $removeSourceBranch = $this->getHelper('gush_style')->choice('Delete source branch?', ['yes', 'no'], 'no'); + } + if ('yes' === $removeSourceBranch) { $adapter->removePullRequestSourceBranch($pr['number']); $styleHelper->note(sprintf('Remote source branch %s:%s has been removed.', $sourceRemote, $sourceBranch)); } @@ -218,8 +225,6 @@ protected function execute(InputInterface $input, OutputInterface $output) $styleHelper->note(sprintf('Pat given to @%s at %s.', $pr['user'], $patComment)); } - $styleHelper->success([$mergeNote, $pr['url']]); - return self::COMMAND_SUCCESS; } catch (CannotSquashMultipleAuthors $e) { $styleHelper->error([ From 99de2674c535efcde7c6800348ac334b7a783454 Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Thu, 11 Aug 2016 00:54:06 -0300 Subject: [PATCH 3/7] Add option `--remove-source-branch` to `pull-request:close` command --- .../PullRequest/PullRequestCloseCommand.php | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/Command/PullRequest/PullRequestCloseCommand.php b/src/Command/PullRequest/PullRequestCloseCommand.php index 85a454af..d788635f 100644 --- a/src/Command/PullRequest/PullRequestCloseCommand.php +++ b/src/Command/PullRequest/PullRequestCloseCommand.php @@ -30,12 +30,13 @@ protected function configure() ->setDescription('Closes a pull request') ->addArgument('pr_number', InputArgument::REQUIRED, 'Pull Request number to be closed') ->addOption('message', 'm', InputOption::VALUE_REQUIRED, 'Closing comment') + ->addOption('remove-source-branch', null, InputOption::VALUE_REQUIRED, 'Remove remote source branch after closing own pull request', 'no') ->setHelp( <<%command.name% command closes a Pull Request for either the current or the given organization and repository: - $ gush %command.name% 12 -m"let's try to keep it low profile guys." + $ gush %command.name% 12 -m"let's try to keep it low profile guys." --remove-source-branch=yes EOF ) @@ -47,11 +48,16 @@ protected function configure() */ protected function execute(InputInterface $input, OutputInterface $output) { - $prNumber = $input->getArgument('pr_number'); - $closingComment = $input->getOption('message'); - $adapter = $this->getAdapter(); + $prNumber = $input->getArgument('pr_number'); + $pr = $adapter->getPullRequest($prNumber); + $authenticatedUser = $this->getParameter($input, 'authentication')['username']; + $removeSourceBranch = $input->getOption('remove-source-branch'); + if ('yes' === $removeSourceBranch && $pr['user'] !== $authenticatedUser) { + throw new UserException(sprintf('`--remove-source-branch` option cannot be used with pull requests that aren\'t owned by the authenticated user (%s)', $authenticatedUser)); + } + $closingComment = $input->getOption('message'); $adapter->closePullRequest($prNumber); if ($input->getOption('message')) { @@ -61,6 +67,17 @@ protected function execute(InputInterface $input, OutputInterface $output) $url = $adapter->getPullRequest($prNumber)['url']; $this->getHelper('gush_style')->success("Closed {$url}"); + // Post close options + if ($pr['user'] === $authenticatedUser) { + if ('yes' !== $removeSourceBranch) { + $removeSourceBranch = $this->getHelper('gush_style')->choice('Delete source branch?', ['yes', 'no'], 'no'); + } + if ('yes' === $removeSourceBranch) { + $adapter->removePullRequestSourceBranch($pr['number']); + $this->getHelper('gush_style')->note(sprintf('Remote source branch %s:%s has been removed.', $pr['head']['user'], $pr['head']['ref'])); + } + } + return self::COMMAND_SUCCESS; } } From 6011a3ad749b57cf380f23d2273239f65696c255 Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Sun, 21 Aug 2016 18:27:54 -0300 Subject: [PATCH 4/7] Add `GitLabRepoAdapter::removePullRequestSourceBranch()` --- src/ThirdParty/Gitlab/Adapter/GitLabRepoAdapter.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ThirdParty/Gitlab/Adapter/GitLabRepoAdapter.php b/src/ThirdParty/Gitlab/Adapter/GitLabRepoAdapter.php index 08b26512..12ef6195 100644 --- a/src/ThirdParty/Gitlab/Adapter/GitLabRepoAdapter.php +++ b/src/ThirdParty/Gitlab/Adapter/GitLabRepoAdapter.php @@ -278,4 +278,12 @@ public function createReleaseAssets($id, $name, $contentType, $content) { throw new UnsupportedOperationException('Releases are not supported by Gitlab.'); } + + public function removePullRequestSourceBranch($id) + { + $api = $this->client->api('repo'); + $pr = $this->getPullRequest($id); + + return $api->deleteBranch($this->getCurrentProject()->id, $pr['head']['ref']); + } } From 9aad20d45913bf57b62982d52a3614659f3b604c Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Sat, 27 Aug 2016 11:35:36 -0300 Subject: [PATCH 5/7] Add `Adapter::removePullRequestSourceBranch()` --- src/Adapter/Adapter.php | 9 +++++++++ src/ThirdParty/Bitbucket/BitbucketRepoAdapter.php | 7 +++++++ tests/Fixtures/Adapter/TestAdapter.php | 5 +++++ 3 files changed, 21 insertions(+) diff --git a/src/Adapter/Adapter.php b/src/Adapter/Adapter.php index b865db57..bdf44aec 100644 --- a/src/Adapter/Adapter.php +++ b/src/Adapter/Adapter.php @@ -369,4 +369,13 @@ public function getReleaseAssets($id); * @throws AdapterException when deleting of release failed */ public function removeRelease($id); + + /** + * Deletes the remote source branch used in a pull request. + * + * @param int $id + * + * @return mixed + */ + public function removePullRequestSourceBranch($id); } diff --git a/src/ThirdParty/Bitbucket/BitbucketRepoAdapter.php b/src/ThirdParty/Bitbucket/BitbucketRepoAdapter.php index 5f84a4bc..8c355401 100644 --- a/src/ThirdParty/Bitbucket/BitbucketRepoAdapter.php +++ b/src/ThirdParty/Bitbucket/BitbucketRepoAdapter.php @@ -13,6 +13,7 @@ use Gush\Adapter\BaseAdapter; use Gush\Exception\AdapterException; +use Gush\Exception\UnsupportedOperationException; use Herrera\Version\Parser; use Herrera\Version\Validator as VersionValidator; @@ -519,4 +520,10 @@ protected function adaptPullRequestStructure(array $pr) ], ]; } + + public function removePullRequestSourceBranch($id) + { + /** @link https://developer.atlassian.com/static/rest/bitbucket-server/4.7.1/bitbucket-branch-rest.html#idp45632 REST Resources Provided By: Bitbucket Server - Branch */ + throw new UnsupportedOperationException('Bitbucket client "gentle/bitbucket-api" doesn\'t support references.'); + } } diff --git a/tests/Fixtures/Adapter/TestAdapter.php b/tests/Fixtures/Adapter/TestAdapter.php index 7c3536bd..7a5a3b15 100644 --- a/tests/Fixtures/Adapter/TestAdapter.php +++ b/tests/Fixtures/Adapter/TestAdapter.php @@ -544,6 +544,11 @@ public function createReleaseAssets($id, $name, $contentType, $content) return self::RELEASE_ASSET_NUMBER; } + public function removePullRequestSourceBranch($id) + { + return []; + } + /** * {@inheritdoc} */ From a6bdd797be4aaeecb3b151ef5a0abf37e3db91be Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Wed, 7 Sep 2016 16:36:50 -0300 Subject: [PATCH 6/7] Add `--no-remove-source-branch` option --- .../PullRequest/PullRequestMergeCommand.php | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/Command/PullRequest/PullRequestMergeCommand.php b/src/Command/PullRequest/PullRequestMergeCommand.php index d30c45a9..9efea228 100644 --- a/src/Command/PullRequest/PullRequestMergeCommand.php +++ b/src/Command/PullRequest/PullRequestMergeCommand.php @@ -42,7 +42,8 @@ protected function configure() ->addOption('force-squash', null, InputOption::VALUE_NONE, 'Force squashing the PR, even if there are multiple authors (this will implicitly use --squash)') ->addOption('switch', null, InputOption::VALUE_REQUIRED, 'Switch the base of the pull request before merging') ->addOption('pat', null, InputOption::VALUE_REQUIRED, 'Give the PR\'s author a pat on the back after the merge') - ->addOption('remove-source-branch', null, InputOption::VALUE_REQUIRED, 'Remove remote source branch after merging own pull request', 'no') + ->addOption('remove-source-branch', null, InputOption::VALUE_NONE, 'Remove remote source branch after merging own pull request') + ->addOption('no-remove-source-branch', null, InputOption::VALUE_NONE, 'Don\'t remove remote source branch after merging own pull request') ->setHelp( <<<'EOF' The %command.name% command merges the given pull request: @@ -101,11 +102,13 @@ protected function configure() The whole pat configuration will be ignored and no pat will be placed if the pull request is authored by yourself! -If you are the author of the pull request, you'll be prompted if the remote source -branch will be removed after a successful merge. -Also, you can pass your choice for this action with the --remove-source-branch option: +If you are the author of the pull request, you'll be prompted if the remote source branch will be removed after a successful merge. +Also, you can pass your choice for this action with the --remove-source-branch and --no-remove-source-branch +options: - $ gush %command.name% --remove-source-branch=[yes|no] + $ gush %command.name% --remove-source-branch + + $ gush %command.name% --no-remove-source-branch EOF ) ; @@ -150,7 +153,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $authenticatedUser = $this->getParameter($input, 'authentication')['username']; $removeSourceBranch = $input->getOption('remove-source-branch'); - if ('yes' === $removeSourceBranch && $pr['user'] !== $authenticatedUser) { + if ($removeSourceBranch && $pr['user'] !== $authenticatedUser) { throw new UserException(sprintf('`--remove-source-branch` option cannot be used with pull requests that aren\'t owned by the authenticated user (%s)', $authenticatedUser)); } @@ -214,10 +217,7 @@ protected function execute(InputInterface $input, OutputInterface $output) // Post merge options if ($pr['user'] === $authenticatedUser) { - if ('yes' !== $removeSourceBranch) { - $removeSourceBranch = $this->getHelper('gush_style')->choice('Delete source branch?', ['yes', 'no'], 'no'); - } - if ('yes' === $removeSourceBranch) { + if (!$input->getOption('no-remove-source-branch') && 'yes' === $this->getHelper('gush_style')->choice('Delete source branch?', ['yes', 'no'], 'no')) { $adapter->removePullRequestSourceBranch($pr['number']); $styleHelper->note(sprintf('Remote source branch %s:%s has been removed.', $sourceRemote, $sourceBranch)); } @@ -434,4 +434,13 @@ private function givePatToPullRequestAuthor(array $pr, $pat) return $this->getAdapter()->createComment($pr['number'], $patMessage); } } + + protected function initialize(InputInterface $input, OutputInterface $output) + { + parent::initialize($input, $output); + + if ($input->getOption('remove-source-branch') && $input->getOption('no-remove-source-branch')) { + throw new UserException('Options `--remove-source-branch` and `--no-remove-source-branch` cannot be used toghether'); + } + } } From 341830d68e6faa179fa4d821613c1195a50824a5 Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Fri, 9 Sep 2016 15:11:04 -0300 Subject: [PATCH 7/7] Update `PullRequestMergeCommand::execute()` --- src/Command/PullRequest/PullRequestMergeCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Command/PullRequest/PullRequestMergeCommand.php b/src/Command/PullRequest/PullRequestMergeCommand.php index 9efea228..14645af8 100644 --- a/src/Command/PullRequest/PullRequestMergeCommand.php +++ b/src/Command/PullRequest/PullRequestMergeCommand.php @@ -217,7 +217,7 @@ protected function execute(InputInterface $input, OutputInterface $output) // Post merge options if ($pr['user'] === $authenticatedUser) { - if (!$input->getOption('no-remove-source-branch') && 'yes' === $this->getHelper('gush_style')->choice('Delete source branch?', ['yes', 'no'], 'no')) { + if ($removeSourceBranch || (!$input->getOption('no-remove-source-branch') && 'yes' === $this->getHelper('gush_style')->choice('Delete source branch?', ['yes', 'no'], 'no'))) { $adapter->removePullRequestSourceBranch($pr['number']); $styleHelper->note(sprintf('Remote source branch %s:%s has been removed.', $sourceRemote, $sourceBranch)); }