Passed
Pull Request — master (#22)
by
unknown
03:57 queued 01:38
created

ReportCommand::outputFormattedLicenses()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 47
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 47
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 each 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
            [$license] = $dependency->getLicenses();
85
86
            if (! isset($grouped[$license])) {
87
                $grouped[$license] = [];
88
            }
89
            $grouped[$license][] = $dependency;
90
        }
91
92
        return $grouped;
93
    }
94
95
    private function lookUpLicenses(array $licenses, OutputInterface $output, $useCache = true): array
96
    {
97
        if (! $useCache) {
98
            $this->licenseLookup->setCache(new NullAdapter);
99
        }
100
101
        $lookedUp = [];
102
        foreach ($licenses as $license) {
103
            $output->writeln("Looking up $license ...");
104
            $lookedUp[$license] = $this->licenseLookup->lookUp($license);
105
        }
106
107
        return $lookedUp;
108
    }
109
110
    /**
111
     * @param  OutputInterface  $output
112
     * @param  InputInterface  $input
113
     * @param  License[]  $licenses
114
     * @param  array  $groupedByName
115
     */
116
    protected function outputFormattedLicenses(OutputInterface $output, InputInterface $input, array $licenses, array $groupedByName): void
117
    {
118
        foreach ($licenses as $license) {
119
            $dependencies = $groupedByName[$license->getShortName()];
120
121
            $usageCount = count($dependencies);
122
            $headline = sprintf(PHP_EOL.'Count %d - %s (%s)', $usageCount, $license->getShortName(),
123
                $license->getSource());
124
            $output->writeln($headline);
125
            $licenseTable = new Table($output);
126
            $licenseTable->setHeaders(['CAN', 'CAN NOT', 'MUST']);
127
128
            $can = $license->getCan();
129
            $cannot = $license->getCannot();
130
            $must = $license->getMust();
131
            $columnWidth = max(count($can), count($cannot), count($must));
132
133
            $can = array_pad($can, $columnWidth, null);
134
            $cannot = array_pad($cannot, $columnWidth, null);
135
            $must = array_pad($must, $columnWidth, null);
136
137
            $inlineHeading = function ($key) {
138
                return is_string($key) ? $key : '';
139
            };
140
141
            $can = array_map_keys($can, $inlineHeading);
142
            $cannot = array_map_keys($cannot, $inlineHeading);
143
            $must = array_map_keys($must, $inlineHeading);
144
145
            for ($i = 0; $i < $columnWidth; $i++) {
146
                $licenseTable->addRow([
147
                    'CAN'    => $can[$i],
148
                    'CANNOT' => $cannot[$i],
149
                    'MUST'   => $must[$i],
150
                ]);
151
            }
152
            $licenseTable->render();
153
154
            if ($input->getOption('show-packages') || $output->isVerbose()) {
155
                $output->writeln('');
156
                $packages = [];
157
                foreach ($dependencies as $dependency) {
158
                    $packages[] = $dependency->getName();
159
                }
160
161
                sort($packages);
162
                $output->writeln(sprintf('packages: %s', implode(', ', $packages)));
163
            }
164
        }
165
    }
166
}
167