Passed
Branch master (3e058b)
by Allan
02:59
created

InfoCommand::resolveVersion()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 3
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
use Vaimo\ComposerChangelogs\Exceptions\PackageResolverException;
11
12
use Vaimo\ComposerChangelogs\Factories;
13
14
/**
15
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
16
 */
17
class InfoCommand extends \Composer\Command\BaseCommand
18
{
19
    protected function configure()
20
    {
21
        $this->setName('changelog:info');
22
23
        $this->setDescription('Generates summary of a given release');
24
25
        $this->addArgument(
26
            'name',
27
            \Symfony\Component\Console\Input\InputArgument::OPTIONAL,
28
            'Targeted package name. Default: root package'
29
        );
30
31
        $this->addOption(
32
            '--from-source',
33
            null,
34
            \Symfony\Component\Console\Input\InputOption::VALUE_NONE,
35
            'Extract configuration from vendor package instead of using global installation data'
36
        );
37
38
        $this->addOption(
39
            '--brief',
40
            null,
41
            \Symfony\Component\Console\Input\InputOption::VALUE_NONE,
42
            'Output overview on the targeted release'
43
        );
44
45
        $this->addOption(
46
            '--release',
47
            null,
48
            \Symfony\Component\Console\Input\InputOption::VALUE_OPTIONAL,
49
            'Target specific release in the changelog. Default: latest valid versioned release'
50
        );
51
52
        $this->addOption(
53
            '--branch',
54
            null,
55
            \Symfony\Component\Console\Input\InputOption::VALUE_OPTIONAL,
56
            'Match release branch (if provided in changelog item)'
57
        );
58
59
        $pluginConfig = new \Vaimo\ComposerChangelogs\Composer\Plugin\Config();
60
61
        $this->addOption(
62
            '--format',
63
            null,
64
            \Symfony\Component\Console\Input\InputOption::VALUE_OPTIONAL,
65
            sprintf('Format of the output (%s)', implode(', ', $pluginConfig->getAvailableFormats())),
66
            'json'
67
        );
68
69
        $this->addOption(
70
            '--upcoming',
71
            null,
72
            \Symfony\Component\Console\Input\InputOption::VALUE_NONE,
73
            'Show upcoming version (if there is one)'
74
        );
75
    }
76
77
    protected function execute(InputInterface $input, OutputInterface $output)
78
    {
79
        $packageName = $input->getArgument('name');
80
81
        $fromSource = $input->getOption('from-source');
82
        $briefMode = $input->getOption('brief');
83
        $version = $input->getOption('release');
84
        $format = $input->getOption('format');
85
        $branch = $input->getOption('branch');
86
        $showUpcoming = $input->getOption('upcoming');
87
        
88
        $composerRuntime = $this->getComposer();
89
        
90
        try {
91
            $package = $this->resolvePackage($packageName);
0 ignored issues
show
Bug introduced by
It seems like $packageName can also be of type string[]; however, parameter $packageName of Vaimo\ComposerChangelogs...mmand::resolvePackage() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

91
            $package = $this->resolvePackage(/** @scrutinizer ignore-type */ $packageName);
Loading history...
92
        } catch (PackageResolverException $exception) {
93
            $this->printException($exception, $output);
94
95
            return 1;
96
        }
97
98
        $chLogLoaderFactory = new Factories\Changelog\LoaderFactory($composerRuntime);
99
        $chLogLoader = $chLogLoaderFactory->create($fromSource);
100
101
        $validator = new \Vaimo\ComposerChangelogs\Validators\ChangelogValidator($chLogLoader, array(
102
            'failure' => '<error>%s</error>',
103
            'success' => '<info>%s</info>'
104
        ));
105
106
        $result = $validator->validateForPackage($package, $output->getVerbosity());
107
108
        if (!$result()) {
109
            array_map(array($output, 'writeln'), $result->getMessages());
110
            
111
            return 1;
112
        }
113
114
        $changelog = $chLogLoader->load($package);
115
116
        if (!$version) {
117
            $version = $this->resolveVersion($changelog, $branch, $showUpcoming);
118
        }
119
120
        if (!$version || !isset($changelog[$version])) {
121
            return 0;
122
        }
123
124
        $details = $changelog[$version];
125
126
        $detailsResolver = new \Vaimo\ComposerChangelogs\Resolvers\ReleaseDetailsResolver();
127
128
        $generalInfo = $detailsResolver->resolveOverview($details);
129
        $groups = $detailsResolver->resolveChangeGroups($details);
130
131
        if ($briefMode) {
132
            $summary = array_map(function ($key, $group) {
133
                return sprintf('%s (%s)', $key, count($group));
134
            }, array_keys($groups), $groups);
135
136
            $generalInfo = $detailsResolver->resolveOverview($details);
137
138
            $groups = array(
139
                'overview' => $generalInfo['overview'],
140
                'summary' => sprintf('Includes: %s', implode(', ', $summary))
141
            );
142
        } elseif ($generalInfo['overview']) {
143
            $groups = array_merge(
144
                $groups,
145
                array('overview' => $generalInfo['overview'])
146
            );
147
        }
148
149
        try {
150
            $result = $this->generateOutput($groups, $format, $fromSource);
151
        } catch (\Exception $exception) {
152
            $output->writeln(
153
                sprintf('<error>%s</error>', $exception->getMessage())
154
            );
155
156
            return 1;
157
        }
158
159
        $output->writeln($result);
160
        
161
        return 0;
162
    }
163
    
164
    private function generateOutput($groups, $format, $fromSource)
165
    {
166
        $composerRuntime = $this->getComposer();
167
        
168
        if ($format === 'json') {
169
            $jsonEncoder = new \Camspiers\JsonPretty\JsonPretty();
170
171
            return $jsonEncoder->prettify($groups, null, '    ');
172
        }
173
174
        $confResolverFactory = new Factories\Changelog\ConfigResolverFactory($composerRuntime);
175
176
        $confResolver = $confResolverFactory->create($fromSource);
177
178
        $templates = $confResolver->resolveOutputTemplates();
179
180
        $renderCtxGenerator = new \Vaimo\ComposerChangelogs\Generators\Changelog\RenderContextGenerator();
181
        $templateRenderer = new \Vaimo\ComposerChangelogs\Generators\TemplateOutputGenerator();
182
183
        $ctxData = $renderCtxGenerator->generate(
184
            array('' => $groups)
185
        );
186
187
        if (!isset($templates[$format])) {
188
            throw new \Vaimo\ComposerChangelogs\Exceptions\GeneratorException(sprintf(
189
                'Unknown format: %s; available options: %s',
190
                $format,
191
                implode(', ', array_merge(array('json'), array_keys($templates)))
192
            ));
193
        }
194
195
        return $templateRenderer->generateOutput(
196
            reset($ctxData['releases']),
197
            array('root' => $templates[$format]['release'])
198
        );
199
    }
200
    
201
    private function printException($exception, OutputInterface $output)
202
    {
203
        $errorOutputGenerator = new \Vaimo\ComposerChangelogs\Console\OutputGenerator();
204
205
        \array_map(
206
            array($output, 'writeln'),
207
            $errorOutputGenerator->generateForResolverException($exception)
208
        );
209
    }
210
211
    /**
212
     * @param string $packageName
213
     * @return \Composer\Package\PackageInterface
214
     * @throws PackageResolverException
215
     */
216
    private function resolvePackage($packageName)
217
    {
218
        $composerRuntime = $this->getComposer();
219
        
220
        if (!$packageName) {
221
            $packageName = $composerRuntime->getPackage()->getName();
222
        }
223
224
        $packageRepoFactory = new Factories\PackageRepositoryFactory($composerRuntime);
225
226
        $packageRepository = $packageRepoFactory->create();
227
228
        return $packageRepository->getByName($packageName);
229
    }
230
    
231
    private function resolveVersion($changelog, $branch, $showUpcoming)
232
    {
233
        $releaseResolver = new \Vaimo\ComposerChangelogs\Resolvers\ChangelogReleaseResolver();
234
235
        if (!$showUpcoming) {
236
            return $releaseResolver->resolveLatestVersionedRelease($changelog, $branch);
237
        }
238
239
        return $releaseResolver->resolveUpcomingRelease($changelog, $branch);
240
    }
241
}
242