Skip to content

Commit

Permalink
Merge pull request #4 from eventum/close-issue
Browse files Browse the repository at this point in the history
add close issue command
  • Loading branch information
glensc authored Sep 29, 2017
2 parents 2be186d + f0ee821 commit 4e11bcb
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
1 change: 1 addition & 0 deletions src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
197 changes: 197 additions & 0 deletions src/Command/CloseIssueCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
<?php

/*
* This file is part of the Eventum (Issue Tracking System) package.
*
* @copyright (c) Eventum Team
* @license GNU General Public License, version 2 or later (GPL-2+)
*
* For the full copyright and license information,
* please see the LICENSE and AUTHORS files
* that were distributed with this source code.
*/

namespace Eventum\Console\Command;

use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class CloseIssueCommand extends Command
{
protected function configure()
{
$this
->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(
<<<EOT
<info>%command.full_name% 123</info>
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()
{
$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";

$answer = $this->askChoices($prompt, $list, $errorMessage, $default);

return $list[$answer];
}

/**
* @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, $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:
return 0;
case 1:
return key($list);
}

if ($default) {
$prompt .= " ($default)";
}

$answer = $this->io->askChoices($prompt, $list, $errorMessage, $default);

return array_search($answer, $list);
}
}

0 comments on commit 4e11bcb

Please sign in to comment.