Test Failed
Push — master ( 4dff26...486b13 )
by Daniel
02:11
created

ApproverCommand::getMergeRequests()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 4
nop 0
dl 0
loc 10
ccs 7
cts 7
cp 1
crap 3
rs 10
c 0
b 0
f 0
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 7
    public function __construct(
40
        ProjectService $projectService,
41
        UserService $userService,
42
        MergeRequestService $mergeRequestService,
43
        MergeRequestApprovalService $mergeRequestApprovalService,
44
        MergeRequestApprovalFilter $mergeRequestApprovalFilter
45
    ) {
46 7
        $this->projectService = $projectService;
47 7
        $this->userService = $userService;
48 7
        $this->mergeRequestService = $mergeRequestService;
49 7
        $this->mergeRequestApprovalService = $mergeRequestApprovalService;
50 7
        $this->mergeRequestApprovalFilter = $mergeRequestApprovalFilter;
51 7
        parent::__construct();
52 7
    }
53
54 7
    protected function configure()
55
    {
56
        $this
57 7
            ->setName('approver')
58 7
            ->setAliases(['a'])
59 7
            ->setDescription('Get approver\'s pending merge requests')
60 7
            ->addArgument(
61 7
                'username',
62 7
                InputArgument::OPTIONAL,
63 7
                'Gitlab username or email address'
64 7
            )->addOption(
65 7
                'slack',
66 7
                's',
67 7
                InputOption::VALUE_NONE,
68 7
                'Post to slack channel'
69 7
            )->addOption(
70 7
                'include-suggested',
71 7
                'i',
72 7
                InputOption::VALUE_NONE,
73 7
                'Include suggested approvers'
74
            );
75 7
    }
76
77
    /**
78
     * @param string|null $username
79
     * @return User
80
     * @throws UserNotFoundException
81
     */
82 3
    private function getUser(string $username = null): User
83
    {
84 3
        if ($username) {
85 1
            return $this->userService->getByName($username);
86
        }
87 2
        return $this->userService->getAuthenticated();
88
    }
89
90
    /**
91
     * @return array
92
     * @throws MergeRequestNotFoundException
93
     * @throws \Exception
94
     */
95 3
    private function getMergeRequests(): array
96
    {
97 3
        $mergeRequests = [];
98 3
        foreach ($this->projectService->all() as $project) {
99 3
            $mergeRequests += $this->mergeRequestService->allByProject($project);
100
        }
101 3
        if (count($mergeRequests) == 0) {
102 1
            throw new MergeRequestNotFoundException('No pending merge requests.');
103
        }
104 2
        return $mergeRequests;
105
    }
106
107
    /**
108
     * @param InputInterface $input
109
     * @param OutputInterface $output
110
     * @return int|null|void
111
     * @throws \Exception
112
     */
113 3
    protected function execute(InputInterface $input, OutputInterface $output)
114
    {
115 3
        $user = $this->getUser(/** @scrutinizer ignore-type */ $input->getArgument('username'));
116 3
        $mergeRequests = $this->getMergeRequests();
117 2
        $mergeRequestApprovals = $this->mergeRequestApprovalService->getAll(
118 2
            $mergeRequests,
119 2
            $this->mergeRequestApprovalFilter->addUser($user, $input->getOption('include-suggested'))
120
        );
121
122 1
        $messageText = sprintf(
123 1
            '%u Pending merge requests for %s:',
124 1
            count($mergeRequestApprovals),
125 1
            $user->getName()
126
        );
127
128 1
        if (!$output->isQuiet()) {
129 1
            $output->writeln([$messageText, '']);
130 1
            foreach ($mergeRequestApprovals as $mergeRequestApproval) {
131 1
                $this->printMergeRequestApproval($output, $mergeRequestApproval);
132
            }
133
        }
134
135 1
        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 1
    }
144
}
145