ApproverCommand   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 59
c 1
b 0
f 0
dl 0
loc 122
ccs 0
cts 42
cp 0
rs 10
wmc 12

5 Methods

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