Passed
Push — master ( e67480...0070a2 )
by Daniel
02:05
created

ApproverCommand::execute()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 29
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 19
nc 6
nop 2
dl 0
loc 29
ccs 0
cts 26
cp 0
crap 30
rs 9.3222
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace DanielPieper\MergeReminder\Command;
4
5
use DanielPieper\MergeReminder\Exception\MergeRequestApprovalNotFoundException;
6
use DanielPieper\MergeReminder\Exception\MergeRequestNotFoundException;
7
use DanielPieper\MergeReminder\Exception\UserNotFoundException;
8
use DanielPieper\MergeReminder\Filter\MergeRequestApprovalFilter;
9
use DanielPieper\MergeReminder\Service\MergeRequestApprovalService;
10
use DanielPieper\MergeReminder\Service\MergeRequestService;
11
use DanielPieper\MergeReminder\Service\UserService;
12
use DanielPieper\MergeReminder\SlackServiceAwareInterface;
13
use DanielPieper\MergeReminder\SlackServiceAwareTrait;
14
use DanielPieper\MergeReminder\ValueObject\MergeRequestApproval;
15
use DanielPieper\MergeReminder\ValueObject\User;
16
use Symfony\Component\Console\Input\InputArgument;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Input\InputOption;
19
use Symfony\Component\Console\Output\OutputInterface;
20
21
class ApproverCommand extends BaseCommand implements SlackServiceAwareInterface
22
{
23
    use SlackServiceAwareTrait;
24
25
    /** @var UserService */
26
    private $userService;
27
28
    /** @var MergeRequestService */
29
    private $mergeRequestService;
30
31
    /** @var MergeRequestApprovalService */
32
    private $mergeRequestApprovalService;
33
34
    /** @var MergeRequestApprovalFilter */
35
    private $mergeRequestApprovalFilter;
36
37
    public function __construct(
38
        UserService $userService,
39
        MergeRequestService $mergeRequestService,
40
        MergeRequestApprovalService $mergeRequestApprovalService,
41
        MergeRequestApprovalFilter $mergeRequestApprovalFilter
42
    ) {
43
        $this->userService = $userService;
44
        $this->mergeRequestService = $mergeRequestService;
45
        $this->mergeRequestApprovalService = $mergeRequestApprovalService;
46
        $this->mergeRequestApprovalFilter = $mergeRequestApprovalFilter;
47
        parent::__construct();
48
    }
49
50
    protected function configure()
51
    {
52
        $this
53
            ->setName('approver')
54
            ->setAliases(['a'])
55
            ->setDescription('Get approver\'s pending merge requests')
56
            ->addArgument(
57
                'username',
58
                InputArgument::OPTIONAL,
59
                'Gitlab username or email address'
60
            )->addOption(
61
                'slack',
62
                's',
63
                InputOption::VALUE_NONE,
64
                'Post to slack channel'
65
            )->addOption(
66
                'include-suggested',
67
                'i',
68
                InputOption::VALUE_NONE,
69
                'Include suggested approvers'
70
            );
71
    }
72
73
    /**
74
     * @param string|null $username
75
     * @return User
76
     * @throws UserNotFoundException
77
     */
78
    private function getUser(string $username = null): User
79
    {
80
        if ($username) {
81
            return $this->userService->getByName($username);
82
        }
83
        return $this->userService->getAuthenticated();
84
    }
85
86
    /**
87
     * @return array
88
     * @throws MergeRequestNotFoundException
89
     */
90
    private function getMergeRequests(): array
91
    {
92
        $mergeRequests = $this->mergeRequestService->all();
93
        if (count($mergeRequests) == 0) {
94
            throw new MergeRequestNotFoundException('No pending merge requests.');
95
        }
96
        return $mergeRequests;
97
    }
98
99
    /**
100
     * @param InputInterface $input
101
     * @param OutputInterface $output
102
     * @return int|null|void
103
     * @throws \Exception
104
     */
105
    protected function execute(InputInterface $input, OutputInterface $output)
106
    {
107
        $user = $this->getUser(/** @scrutinizer ignore-type */ $input->getArgument('username'));
108
        $mergeRequests = $this->getMergeRequests();
109
        $mergeRequestApprovals = $this->mergeRequestApprovalService->getByMergeRequests(
110
            $mergeRequests,
111
            $this->mergeRequestApprovalFilter->addUser($user, $input->getOption('include-suggested'))
112
        );
113
114
        $messageText = sprintf(
115
            '%u Pending merge requests for %s:',
116
            count($mergeRequestApprovals),
117
            $user->getName()
118
        );
119
120
        if (!$output->isQuiet()) {
121
            $output->writeln([$messageText, '']);
122
            foreach ($mergeRequestApprovals as $mergeRequestApproval) {
123
                $this->printMergeRequestApproval($output, $mergeRequestApproval);
124
            }
125
        }
126
127
        if ($input->getOption('slack')) {
128
            if (!$this->slackService) {
129
                $output->writeln('<error>Slack is not configured,'
130
                    . ' please specify SLACK_WEBHOOK_URL and SLACK_CHANNEL environment variables.</error>');
131
                return;
132
            }
133
            $this->slackService->postMessage($mergeRequestApprovals, $messageText);
134
        }
135
    }
136
}
137