Passed
Branch 1.0.x (7d3940)
by Koldo
02:45
created

AdditionalPackages::ask()   B

Complexity

Conditions 8
Paths 14

Size

Total Lines 57
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 31.7587

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 34
c 1
b 0
f 0
nc 14
nop 0
dl 0
loc 57
ccs 9
cts 32
cp 0.2813
crap 31.7587
rs 8.1315

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Antidot\Installer\Question;
6
7
use Composer\IO\IOInterface;
8
use InvalidArgumentException;
9
use Throwable;
10
11
use function array_key_first;
12
use function array_keys;
13
use function file_get_contents;
14
use function json_decode;
15
use function preg_match;
16
use function sprintf;
17
18
use const JSON_THROW_ON_ERROR;
19
20
class AdditionalPackages
21
{
22
    private const PACKAGIST_API = 'https://packagist.org/packages/';
23
    private IOInterface $io;
24
25 2
    public function __construct(IOInterface $io)
26
    {
27 2
        $this->io = $io;
28 2
    }
29
30
    /**
31
     * @return array<string, string>
32
     */
33 1
    public function ask(): array
34
    {
35 1
        $packages = [];
36
37
        do {
38 1
            $installAnotherPackage = $this->io->askConfirmation(
39 1
                'Do you want no add any package from packagist? [Y/<info>N</info>]: ',
40 1
                false
41
            );
42
            try {
43 1
                if (true === $installAnotherPackage) {
44
                    $packageName = $this->io->ask('Add package name "vendor/package": ', null);
45
                    /** @var string $response */
46
                    $response = file_get_contents(self::PACKAGIST_API . $packageName . '.json');
47
                    /** @var array<string, mixed> $packageInfo */
48
                    $packageInfo = json_decode(
49
                        $response,
50
                        true,
51
                        48,
52
                        JSON_THROW_ON_ERROR
53
                    );
54
                    if (isset($packageInfo['status']) && 'error' === $packageInfo['status']) {
55
                        throw new InvalidArgumentException('Invalid package name %s given.');
56
                    }
57
58
                    /** @
59
                     * @var array<string> $versions
60
                     * @psalm-suppress MixedArrayAccess
61
                     * @psalm-suppress MixedArgument
62
                     */
63
                    $versions = array_keys($packageInfo['package']['versions']);
64
                    /** @var string $packageVersion */
65
                    $packageVersion = $this->io->select(
66
                        sprintf(
67
                            'Select version for package %s: [<info>%s</info>] ',
68
                            $packageName,
69
                            $versions[array_key_first($versions)] ?? '*'
70
                        ),
71
                        $versions,
72
                        $versions[array_key_first($versions)] ?? '*'
73
                    );
74
75
                    if (null !== $packageName) {
76
                        $prefix = '';
77
                        if (preg_match('`^(?:v)?\d+\.\d+\.\d+(?:\.\d+)?$`', $packageVersion)) {
78
                            $prefix = '^';
79
                        }
80 1
                        $packages[$packageName] = $prefix . $versions[$packageVersion];
81
                    }
82
                }
83
            } catch (Throwable $exception) {
84
                $installAnotherPackage = true;
85
                $this->io->writeError('<error>' . $exception->getMessage() . '</error>');
86
            }
87 1
        } while (true === $installAnotherPackage);
88
89 1
        return $packages;
90
    }
91
}
92