Passed
Pull Request — master (#22)
by
unknown
11:04
created

ReportCommand::outputFormattedLicenses()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 48
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 33
c 1
b 0
f 1
dl 0
loc 48
ccs 0
cts 34
cp 0
rs 8.4586
cc 7
nc 7
nop 4
crap 56
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Dominikb\ComposerLicenseChecker;
6
7
use Dominikb\ComposerLicenseChecker\Contracts\DependencyLoaderAware;
8
use Dominikb\ComposerLicenseChecker\Contracts\LicenseLookupAware;
9
use Dominikb\ComposerLicenseChecker\Traits\DependencyLoaderAwareTrait;
10
use Dominikb\ComposerLicenseChecker\Traits\LicenseLookupAwareTrait;
11
use Symfony\Component\Cache\Adapter\NullAdapter;
12
use Symfony\Component\Console\Command\Command;
13
use Symfony\Component\Console\Helper\Table;
14
use Symfony\Component\Console\Input\InputDefinition;
15
use Symfony\Component\Console\Input\InputInterface;
16
use Symfony\Component\Console\Input\InputOption;
17
use Symfony\Component\Console\Output\OutputInterface;
18
19
class ReportCommand extends Command implements LicenseLookupAware, DependencyLoaderAware
20
{
21
    use LicenseLookupAwareTrait, DependencyLoaderAwareTrait;
22
23
    protected static $defaultName = 'report';
24
25
    protected function configure()
26
    {
27
        $this->setDefinition(new InputDefinition([
28
            new InputOption(
29
                'project-path',
30
                'p',
31
                InputOption::VALUE_OPTIONAL,
32
                'Path to directory of composer.json file',
33
                realpath('.')
34
            ),
35
            new InputOption(
36
                'composer',
37
                'c',
38
                InputOption::VALUE_OPTIONAL,
39
                'Path to composer executable',
40
                realpath('./vendor/bin/composer')
41
            ),
42
            new InputOption(
43
                'no-cache',
44
                null,
45
                InputOption::VALUE_NONE,
46
                'Disables caching of license lookups'
47
            ),
48
            new InputOption(
49
                'show-packages',
50
                null,
51
                InputOption::VALUE_NONE,
52
                'Shows the packages for the license.'
53
            ),
54
        ]));
55
    }
56
57
    protected function execute(InputInterface $input, OutputInterface $output): int
58
    {
59
        $dependencies = $this->dependencyLoader->loadDependencies(
60
            $input->getOption('composer'),
61
            $input->getOption('project-path')
62
        );
63
64
        $groupedByName = $this->groupDependenciesByLicense($dependencies);
65
66
        $shouldCache = ! $input->getOption('no-cache');
67
        $licenses = $this->lookUpLicenses(array_keys($groupedByName), $output, $shouldCache);
68
69
        /* @var License $license */
70
        $this->outputFormattedLicenses($output, $input, $licenses, $groupedByName);
71
72
        return 0;
73
    }
74
75
    /**
76
     * @param  Dependency[]  $dependencies
77
     * @return array
78
     */
79
    private function groupDependenciesByLicense(array $dependencies): array
80
    {
81
        $grouped = [];
82
83
        foreach ($dependencies as $dependency) {
84
85
            [$license] = $dependency->getLicenses();
86
87
            if (! isset($grouped[$license])) {
88
                $grouped[$license] = [];
89
            }
90
            $grouped[$license][] = $dependency;
91
        }
92
93
        return $grouped;
94
    }
95
96
    private function lookUpLicenses(array $licenses, OutputInterface $output, $useCache = true): array
97
    {
98
        if (! $useCache) {
99
            $this->licenseLookup->setCache(new NullAdapter);
100
        }
101
102
        $lookedUp = [];
103
        foreach ($licenses as $license) {
104
            $output->writeln("Looking up $license ...");
105
            $lookedUp[$license] = $this->licenseLookup->lookUp($license);
106
        }
107
108
        return $lookedUp;
109
    }
110
111
    /**
112
     * @param OutputInterface $output
113
     * @param InputInterface $input
114
     * @param License[] $licenses
115
     * @param array $groupedByName
116
     */
117
    protected function outputFormattedLicenses(OutputInterface $output, InputInterface $input, array $licenses, array $groupedByName): void
118
    {
119
        foreach ($licenses as $license) {
120
121
            $dependencies = $groupedByName[$license->getShortName()];
122
123
            $usageCount = count($dependencies);
124
            $headline = sprintf(PHP_EOL.'Count %d - %s (%s)', $usageCount, $license->getShortName(),
125
                $license->getSource());
126
            $output->writeln($headline);
127
            $licenseTable = new Table($output);
128
            $licenseTable->setHeaders(['CAN', 'CAN NOT', 'MUST']);
129
130
            $can = $license->getCan();
131
            $cannot = $license->getCannot();
132
            $must = $license->getMust();
133
            $columnWidth = max(count($can), count($cannot), count($must));
134
135
            $can = array_pad($can, $columnWidth, null);
136
            $cannot = array_pad($cannot, $columnWidth, null);
137
            $must = array_pad($must, $columnWidth, null);
138
139
            $inlineHeading = function ($key) {
140
                return is_string($key) ? $key : '';
141
            };
142
143
            $can = array_map_keys($can, $inlineHeading);
144
            $cannot = array_map_keys($cannot, $inlineHeading);
145
            $must = array_map_keys($must, $inlineHeading);
146
147
            for ($i = 0; $i < $columnWidth; $i++) {
148
                $licenseTable->addRow([
149
                    'CAN'    => $can[$i],
150
                    'CANNOT' => $cannot[$i],
151
                    'MUST'   => $must[$i],
152
                ]);
153
            }
154
            $licenseTable->render();
155
156
            if ($input->getOption('show-packages') || $output->isVerbose()) {
157
                $output->writeln('');
158
                $packages = [];
159
                foreach ($dependencies as $dependency) {
160
                    $packages[] = $dependency->getName();
161
                }
162
163
                sort($packages);
164
                $output->writeln(sprintf('packages: %s', implode(', ', $packages)));
165
            }
166
        }
167
    }
168
}
169