Passed
Branch master (655a42)
by Allan
03:27 queued 01:16
created

InfoCommand::resolvePackage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 13
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
/**
3
 * Copyright © Vaimo Group. All rights reserved.
4
 * See LICENSE_VAIMO.txt for license details.
5
 */
6
namespace Vaimo\ComposerChangelogs\Commands;
7
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Output\OutputInterface;
10
11
use Composer\Package\PackageInterface;
12
13
use Vaimo\ComposerChangelogs\Resolvers;
14
use Vaimo\ComposerChangelogs\Factories;
15
16
/**
17
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
18
 */
19
class InfoCommand extends \Composer\Command\BaseCommand
20
{
21
    protected function configure()
22
    {
23
        $this->setName('changelog:info');
24
25
        $this->setDescription('Generates summary of a given release');
26
27
        $this->addArgument(
28
            'name',
29
            \Symfony\Component\Console\Input\InputArgument::OPTIONAL,
30
            'Targeted package name. Default: root package'
31
        );
32
33
        $this->addOption(
34
            '--from-source',
35
            null,
36
            \Symfony\Component\Console\Input\InputOption::VALUE_NONE,
37
            'Extract configuration from vendor package instead of using global installation data'
38
        );
39
40
        $this->addOption(
41
            '--brief',
42
            null,
43
            \Symfony\Component\Console\Input\InputOption::VALUE_NONE,
44
            'Output overview on the targeted release'
45
        );
46
47
        $this->addOption(
48
            '--release',
49
            null,
50
            \Symfony\Component\Console\Input\InputOption::VALUE_OPTIONAL,
51
            'Target specific release in the changelog. Default: latest valid versioned release'
52
        );
53
54
        $this->addOption(
55
            '--branch',
56
            null,
57
            \Symfony\Component\Console\Input\InputOption::VALUE_OPTIONAL,
58
            'Match release branch (if provided in changelog item)'
59
        );
60
61
        $pluginConfig = new \Vaimo\ComposerChangelogs\Composer\Plugin\Config();
62
63
        $this->addOption(
64
            '--format',
65
            null,
66
            \Symfony\Component\Console\Input\InputOption::VALUE_OPTIONAL,
67
            sprintf('Format of the output (%s)', implode(', ', $pluginConfig->getAvailableFormats())),
68
            'json'
69
        );
70
71
        $this->addOption(
72
            '--upcoming',
73
            null,
74
            \Symfony\Component\Console\Input\InputOption::VALUE_NONE,
75
            'Show upcoming version (if there is one)'
76
        );
77
    }
78
79
    protected function execute(InputInterface $input, OutputInterface $output)
80
    {
81
        $packageName = $input->getArgument('name');
82
83
        $fromSource = $input->getOption('from-source');
84
        $briefMode = $input->getOption('brief');
85
        $version = $input->getOption('release');
86
        $format = $input->getOption('format');
87
        $branch = $input->getOption('branch');
88
        $showUpcoming = $input->getOption('upcoming');
89
        
90
        $chLogRepoFactory = new Factories\ChangelogRepositoryFactory($this->getComposer(), $output);
0 ignored issues
show
Bug introduced by
The type Vaimo\ComposerChangelogs...ngelogRepositoryFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
91
        $chLogRepo = $chLogRepoFactory->create($fromSource);
92
93
        $changelog = $chLogRepo->getByPackageName(
94
            $packageName,
95
            $output->getVerbosity()
96
        );
97
98
        if ($changelog === null) {
99
            return 1;
100
        }
101
102
        $releases = $changelog->getReleases();
103
        
104
        if (!$version) {
105
            $version = $this->resolveVersion($releases, $branch, $showUpcoming);
106
        }
107
108
        if (!$version || !isset($releases[$version])) {
109
            return 0;
110
        }
111
112
        $groups = $this->resolveOutputGroups(
113
            $releases[$version],
114
            $briefMode
115
        );
116
117
        try {
118
            $result = $this->generateOutput($changelog->getOwner(), $groups, $format, $fromSource);
119
        } catch (\Exception $exception) {
120
            $output->writeln(
121
                sprintf('<error>%s</error>', $exception->getMessage())
122
            );
123
124
            return 1;
125
        }
126
127
        $output->writeln($result);
128
129
        return 0;
130
    }
131
132
    /**
133
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
134
     *
135
     * @param array $details
136
     * @param bool $briefMode
137
     * @return array
138
     */
139
    private function resolveOutputGroups(array $details, $briefMode = false)
140
    {
141
        $detailsResolver = new \Vaimo\ComposerChangelogs\Resolvers\ReleaseDetailsResolver();
142
143
        $generalInfo = $detailsResolver->resolveOverview($details);
144
        $groups = $detailsResolver->resolveChangeGroups($details);
145
146
        if ($briefMode) {
147
            $summary = array_map(function ($key, $group) {
148
                return sprintf('%s (%s)', $key, count($group));
149
            }, array_keys($groups), $groups);
150
151
            $generalInfo = $detailsResolver->resolveOverview($details);
152
153
            $groups = array(
154
                'overview' => $generalInfo['overview'],
155
                'summary' => sprintf('Includes: %s', implode(', ', $summary))
156
            );
157
        } elseif ($generalInfo['overview']) {
158
            $groups = array_merge(
159
                $groups,
160
                array('overview' => $generalInfo['overview'])
161
            );
162
        }
163
164
        return $groups;
165
    }
166
167
    private function generateOutput(PackageInterface $package, $groups, $format, $fromSource)
168
    {
169
        $composerRuntime = $this->getComposer();
170
171
        if ($format === 'json') {
172
            $jsonEncoder = new \Camspiers\JsonPretty\JsonPretty();
173
174
            return $jsonEncoder->prettify($groups, null, '    ');
175
        }
176
177
        $confResolverFactory = new Factories\Changelog\ConfigResolverFactory($composerRuntime);
178
179
        $confResolver = $confResolverFactory->create($fromSource);
180
181
        $templates = $confResolver->resolveOutputTemplates();
182
183
        $renderCtxGenerator = new \Vaimo\ComposerChangelogs\Generators\Changelog\RenderContextGenerator();
184
        $templateRenderer = new \Vaimo\ComposerChangelogs\Generators\TemplateOutputGenerator();
185
186
        $infoResolver = new Resolvers\PackageInfoResolver(
187
            $composerRuntime->getInstallationManager()
188
        );
189
        
190
        $repositoryRoot = $infoResolver->getSourcePath($package);
191
        
192
        $ctxData = $renderCtxGenerator->generate(
193
            array('' => $groups),
194
            '',
195
            $repositoryRoot
196
        );
197
198
        if (!isset($templates[$format])) {
199
            throw new \Vaimo\ComposerChangelogs\Exceptions\GeneratorException(sprintf(
200
                'Unknown format: %s; available options: %s',
201
                $format,
202
                implode(', ', array_merge(array('json'), array_keys($templates)))
203
            ));
204
        }
205
206
        return $templateRenderer->generateOutput(
207
            reset($ctxData['releases']),
208
            array('root' => $templates[$format]['release'])
209
        );
210
    }
211
    
212
    private function resolveVersion($changelog, $branch, $showUpcoming)
213
    {
214
        $releaseResolver = new \Vaimo\ComposerChangelogs\Resolvers\ChangelogReleaseResolver();
215
216
        if (!$showUpcoming) {
217
            return $releaseResolver->resolveLatestVersionedRelease($changelog, $branch);
218
        }
219
220
        return $releaseResolver->resolveUpcomingRelease($changelog, $branch);
221
    }
222
}
223