Passed
Pull Request — master (#33)
by Sander
02:09
created

LinkCommand   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Importance

Changes 8
Bugs 0 Features 0
Metric Value
wmc 12
eloc 39
c 8
b 0
f 0
dl 0
loc 86
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 10 1
A execute() 0 22 5
A getPackage() 0 27 3
A getPaths() 0 12 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the composer-link plugin.
7
 *
8
 * Copyright (c) 2021-2022 Sander Visser <[email protected]>.
9
 *
10
 * For the full copyright and license information, please view the LICENSE.md
11
 * file that was distributed with this source code.
12
 *
13
 * @link https://github.com/SanderSander/composer-link
14
 */
15
16
namespace ComposerLink\Commands;
17
18
use ComposerLink\LinkedPackage;
19
use ComposerLink\PathHelper;
20
use Symfony\Component\Console\Input\InputArgument;
21
use Symfony\Component\Console\Input\InputInterface;
22
use Symfony\Component\Console\Input\InputOption;
23
use Symfony\Component\Console\Output\OutputInterface;
24
25
class LinkCommand extends Command
26
{
27
    protected function configure(): void
28
    {
29
        $this->setName('link');
30
        $this->setDescription('Link a package to a local directory');
31
        $this->addArgument('path', InputArgument::REQUIRED, 'The path of the package');
32
        $this->addOption(
33
            'only-installed',
34
            null,
35
            InputOption::VALUE_NEGATABLE,
36
            'Link only installed packages',
37
        );
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    protected function execute(InputInterface $input, OutputInterface $output): int
44
    {
45
        /** @var bool $onlyInstalled */
46
        $onlyInstalled = $input->getOption('only-installed');
47
        $paths = $this->getPaths($input);
48
49
        foreach ($paths as $path) {
50
            $package = $this->getPackage($path, $output);
51
52
            if (is_null($package) || $onlyInstalled && is_null($package->getOriginalPackage())) {
53
                continue;
54
            }
55
56
            $this->plugin->getRepository()->store($package);
57
            $this->plugin->getLinkManager()->linkPackage($package);
58
59
            // Could be optimized, but for now we persist every package,
60
            // so we know what we have done when a package fails
61
            $this->plugin->getRepository()->persist();
62
        }
63
64
        return 0;
65
    }
66
67
    /**
68
     * @return PathHelper[]
69
     */
70
    protected function getPaths(InputInterface $input): array
71
    {
72
        $helper = new PathHelper($input->getArgument('path'));
73
74
        // When run in global we should transform path to absolute path
75
        if ($this->plugin->isGlobal()) {
76
            /** @var string $working */
77
            $working = $this->getApplication()->getInitialWorkingDirectory();
78
            $helper = $helper->toAbsolutePath($working);
79
        }
80
81
        return $helper->isWildCard() ? $helper->getPathsFromWildcard() : [$helper];
82
    }
83
84
    protected function getPackage(PathHelper $helper, OutputInterface $output): ?LinkedPackage
85
    {
86
        $linkedPackage = $this->plugin->getPackageFactory()->fromPath($helper->getNormalizedPath());
87
        $repository = $this->plugin->getRepository();
88
89
        if (!is_null($repository->findByPath($helper->getNormalizedPath()))) {
90
            $output->writeln(
91
                sprintf('<warning>Package in path "%s" already linked</warning>', $helper->getNormalizedPath())
92
            );
93
94
            return null;
95
        }
96
97
        $currentLinked = $repository->findByName($linkedPackage->getName());
98
        if (!is_null($currentLinked)) {
99
            $output->writeln(
100
                sprintf(
101
                    '<warning>Package "%s" already linked from path "%s"</warning>',
102
                    $linkedPackage->getName(),
103
                    $currentLinked->getPath()
104
                )
105
            );
106
107
            return null;
108
        }
109
110
        return $linkedPackage;
111
    }
112
}
113