Passed
Push — master ( 034d7b...196627 )
by Sander
02:07
created

Plugin::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 2
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;
17
18
use Composer\Composer;
19
use Composer\EventDispatcher\EventSubscriberInterface;
20
use Composer\Installer\InstallationManager;
21
use Composer\IO\IOInterface;
22
use Composer\Plugin\Capability\CommandProvider as ComposerCommandProvider;
23
use Composer\Plugin\Capable;
24
use Composer\Plugin\PluginInterface;
25
use Composer\Repository\RepositoryManager;
26
use Composer\Script\ScriptEvents;
27
use Composer\Util\Filesystem as ComposerFileSystem;
28
use ComposerLink\Actions\LinkPackages;
29
use ComposerLink\Repository\JsonStorage;
30
use ComposerLink\Repository\Repository;
31
use ComposerLink\Repository\Transformer;
32
use RuntimeException;
33
34
class Plugin implements PluginInterface, Capable, EventSubscriberInterface
35
{
36
    protected ?IOInterface $io;
37
38
    protected ?Repository $repository = null;
39
40
    protected InstallationManager $installationManager;
41
42
    protected ComposerFileSystem $filesystem;
43
44
    protected ?LinkManager $linkManager = null;
45
46
    protected ?LinkedPackageFactory $packageFactory = null;
47
48
    protected RepositoryManager $repositoryManager;
49
50
    protected Composer $composer;
51
52
    protected ?LinkPackages $linkPackages;
53
54
    public function __construct(ComposerFileSystem $filesystem = null, LinkPackages $linkPackages = null)
55
    {
56
        $this->filesystem = $filesystem ?? new ComposerFileSystem();
57
        $this->linkPackages = $linkPackages;
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function deactivate(Composer $composer, IOInterface $io)
64
    {
65
        $io->debug("[ComposerLink]\tPlugin is deactivated");
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71
    public function uninstall(Composer $composer, IOInterface $io)
72
    {
73
        // TODO remove repository file and restore all packages
74
        $io->debug("[ComposerLink]\tPlugin uninstalling");
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function activate(Composer $composer, IOInterface $io)
81
    {
82
        $io->debug("[ComposerLink]\tPlugin is activating");
83
        $this->io = $io;
84
        $this->installationManager = $composer->getInstallationManager();
85
        $this->repositoryManager = $composer->getRepositoryManager();
86
        $this->composer = $composer;
87
88
        $storageFile = $composer->getConfig()->get('vendor-dir') . DIRECTORY_SEPARATOR . 'linked-packages.json';
89
        $this->repository = new Repository(
90
            new JsonStorage($storageFile),
91
            $io,
92
            new Transformer()
93
        );
94
95
        $this->initializeProperties();
96
    }
97
98
    /**
99
     * We can't do this in the constructor, would be nice to use some sort of container for this.
100
     */
101
    protected function initializeProperties(): void
102
    {
103
        $this->packageFactory = new LinkedPackageFactory(
104
            $this->installationManager,
105
            $this->repositoryManager->getLocalRepository()
106
        );
107
108
        $this->linkManager = new LinkManager(
109
            $this->filesystem,
110
            $this->composer->getLoop(),
111
            $this->composer->getInstallationManager(),
112
            $this->repositoryManager->getLocalRepository()
113
        );
114
115
        if (is_null($this->linkPackages)) {
116
            $this->linkPackages = new LinkPackages(
117
                $this->getLinkManager(),
118
                $this->getRepository(),
119
                $this->repositoryManager
120
            );
121
        }
122
    }
123
124
    public static function getSubscribedEvents(): array
125
    {
126
        return [
127
            ScriptEvents::POST_UPDATE_CMD => [
128
                ['linkLinkedPackages'],
129
            ],
130
        ];
131
    }
132
133
    public function getLinkManager(): LinkManager
134
    {
135
        if (is_null($this->linkManager)) {
136
            throw new RuntimeException('Plugin not activated');
137
        }
138
139
        return $this->linkManager;
140
    }
141
142
    public function linkLinkedPackages(): void
143
    {
144
        if (is_null($this->linkPackages)) {
145
            throw new RuntimeException('Plugin not activated');
146
        }
147
        $this->linkPackages->execute();
148
    }
149
150
    public function getCapabilities(): array
151
    {
152
        return [
153
            ComposerCommandProvider::class => CommandProvider::class,
154
        ];
155
    }
156
157
    public function getRepository(): Repository
158
    {
159
        if (is_null($this->repository)) {
160
            throw new RuntimeException('Plugin not activated');
161
        }
162
163
        return $this->repository;
164
    }
165
166
    public function getPackageFactory(): LinkedPackageFactory
167
    {
168
        if (is_null($this->packageFactory)) {
169
            throw new RuntimeException('Plugin not activated');
170
        }
171
172
        return $this->packageFactory;
173
    }
174
175
    /**
176
     * Check if this plugin is running from global or local project.
177
     */
178
    public function isGlobal(): bool
179
    {
180
        return getcwd() === $this->composer->getConfig()->get('home');
181
    }
182
}
183