From 400d25e0eaca20e8b431e71c4f6cbb129ef1b7b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Wed, 6 Sep 2017 14:50:34 +0300 Subject: [PATCH 1/4] add close issue command --- src/Application.php | 1 + src/Command/CloseIssueCommand.php | 189 ++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 src/Command/CloseIssueCommand.php diff --git a/src/Application.php b/src/Application.php index 56e8106..b620cc4 100644 --- a/src/Application.php +++ b/src/Application.php @@ -57,6 +57,7 @@ protected function getDefaultCommands() $commands[] = new Command\ConfigCommand(); $commands[] = new Command\AddTimeEntryCommand(); $commands[] = new Command\SetIssueStatusCommand(); + $commands[] = new Command\CloseIssueCommand(); if (strpos(__FILE__, 'phar:') === 0) { $commands[] = new Command\SelfUpdateCommand('self-update'); diff --git a/src/Command/CloseIssueCommand.php b/src/Command/CloseIssueCommand.php new file mode 100644 index 0000000..9364e10 --- /dev/null +++ b/src/Command/CloseIssueCommand.php @@ -0,0 +1,189 @@ +setName('close') + ->setDescription('Marks an issue as closed') + ->addArgument( + 'issue_id', + InputArgument::REQUIRED, + 'Issue id' + ) + ->addOption( + 'status', + 's', + InputOption::VALUE_REQUIRED, + 'New status for issue' + ) + ->addOption( + 'resolution', + 'r', + InputOption::VALUE_REQUIRED, + 'Resolution for issue' + ) + ->addOption( + 'notify', + null, + InputOption::VALUE_NONE, + 'Send notification about issue close', + null + ) + ->addOption( + 'no-notify', + null, + InputOption::VALUE_NONE, + 'Do not send notification about issue close', + null + ) + ->addOption( + 'message', + 'm', + InputOption::VALUE_REQUIRED, + 'Note message' + ) + // project_id required when retrieving statuses + // should really figure that out by asking via issue_id instead + ->addOption( + 'project', + null, + InputOption::VALUE_REQUIRED, + 'Project Id' + ) + ->setHelp( + <<%command.full_name% 123 + +Marks an issue as closed. +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $issue_id = (int )$input->getArgument('issue_id'); + $status = $this->getStatus(); + $resolution_id = $this->getResolutionId(); + $send_notification = $this->getSendNotification(); + $note = $this->getMessage(); + + $client = $this->getClient(); + $result = $client->closeIssue($issue_id, $status, $resolution_id, $send_notification, $note); + + $message = "OK: issue #$issue_id successfully closed."; + $output->writeln($message); + + if ($result === 'INCIDENT') { + $message = 'WARNING: This customer has incidents.'; + $message .= " Please redeem incidents by running 'eventum $issue_id redeem'"; + $output->writeln($message); + } + } + + /** + * Return issue status title. + * + * @return string + */ + private function getStatus() + { + $status = $this->input->getOption('status'); + if ($status) { + return $status; + } + + $list = $this->getClient()->getClosedAbbreviationAssocList($this->getProjectId()); + $prompt = 'Which status do you want to use in this action?'; + $errorMessage = "Entered status doesn't match any in the list available to you"; + + return $this->askChoices($prompt, $list, $errorMessage); + } + + /** + * @return int + */ + private function getResolutionId() + { + $resolution = $this->input->getOption('resolution'); + if ($resolution) { + return (int)$resolution; + } + + $list = $this->getClient()->getResolutionAssocList(); + $prompt = 'Which resolution do you want to use in this action?'; + $errorMessage = "Entered resolution doesn't match any in the list available to you"; + + return (int)$this->askChoices($prompt, $list, $errorMessage); + } + + /** + * @return bool + */ + private function getSendNotification() + { + $notify = $this->input->getOption('notify'); + $no_notify = $this->input->getOption('no-notify'); + if ($notify || $no_notify) { + return $notify || !$no_notify; + } + + $question = 'Would you like to send a notification email about this issue being closed? [Y/n]: '; + + return $this->io->askConfirmation($question, 'y'); + } + + /** + * Get issue close message from commandline option or prompt from user. + * + * @return string + */ + private function getMessage() + { + $message = $this->input->getOption('message'); + if ($message) { + return $message; + } + + $question = 'Please enter a reason for closing this issue (one line only): '; + + return $this->io->ask($question); + } + + /** + * ask choices, but return the key not value from the list. + */ + private function askChoices($prompt, $list, $errorMessage) + { + // avoid asking if answer is known + switch (count($list)) { + case 0: + return 0; + case 1: + return key($list); + } + + $answer = $this->io->askChoices($prompt, $list, $errorMessage); + + return array_search($answer, $list); + } +} From 08d5e9c533429789c29216b6df3c90f0e722cbb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Thu, 7 Sep 2017 00:08:20 +0300 Subject: [PATCH 2/4] document close command --- CHANGELOG.md | 1 + README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5465f7..18510ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ## [0.0.3] - implement date arguments for weekly-report #5 +- add `close` command to close issues, #4 [0.0.3]: https://github.com/eventum/cli/compare/0.0.2...master diff --git a/README.md b/README.md index 2ca3830..14865b4 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ Available commands: | Command | | | ------------- | ------------- | | **add-attachment** | Add attachment to issue | +| **close** | Marks an issue as closed | | **open-issues** | List open issues | | **set-status**, **ss** | Set Issue status | | **view-issue** | Display Issue details | From fd8620bf61bfc48b958bbbc314180939e1538daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Thu, 7 Sep 2017 00:23:24 +0300 Subject: [PATCH 3/4] status needs to be title not abbrevation over api --- src/Command/CloseIssueCommand.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Command/CloseIssueCommand.php b/src/Command/CloseIssueCommand.php index 9364e10..88bebd5 100644 --- a/src/Command/CloseIssueCommand.php +++ b/src/Command/CloseIssueCommand.php @@ -107,16 +107,15 @@ protected function execute(InputInterface $input, OutputInterface $output) */ private function getStatus() { - $status = $this->input->getOption('status'); - if ($status) { - return $status; - } + $default = $this->input->getOption('status'); $list = $this->getClient()->getClosedAbbreviationAssocList($this->getProjectId()); $prompt = 'Which status do you want to use in this action?'; $errorMessage = "Entered status doesn't match any in the list available to you"; - return $this->askChoices($prompt, $list, $errorMessage); + $answer = $this->askChoices($prompt, $list, $errorMessage, $default); + + return $list[$answer]; } /** @@ -172,7 +171,7 @@ private function getMessage() /** * ask choices, but return the key not value from the list. */ - private function askChoices($prompt, $list, $errorMessage) + private function askChoices($prompt, $list, $errorMessage, $default = null) { // avoid asking if answer is known switch (count($list)) { @@ -182,7 +181,11 @@ private function askChoices($prompt, $list, $errorMessage) return key($list); } - $answer = $this->io->askChoices($prompt, $list, $errorMessage); + if ($default) { + $prompt .= " ($default)"; + } + + $answer = $this->io->askChoices($prompt, $list, $errorMessage, $default); return array_search($answer, $list); } From f0ee82121e8fbd62caab90fef718845c2cef010a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Thu, 7 Sep 2017 00:24:47 +0300 Subject: [PATCH 4/4] use default answer if it is valid --- src/Command/CloseIssueCommand.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Command/CloseIssueCommand.php b/src/Command/CloseIssueCommand.php index 88bebd5..ad89c69 100644 --- a/src/Command/CloseIssueCommand.php +++ b/src/Command/CloseIssueCommand.php @@ -173,6 +173,11 @@ private function getMessage() */ private function askChoices($prompt, $list, $errorMessage, $default = null) { + // default given and present in $list, use that + if ($default && isset($list[$default])) { + return $default; + } + // avoid asking if answer is known switch (count($list)) { case 0: