Passed
Push — master ( e4e152...8fde47 )
by Georgi
02:55
created

PackageManifest   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 162
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 43
c 0
b 0
f 0
dl 0
loc 162
rs 10
wmc 15

8 Methods

Rating   Name   Duplication   Size   Complexity  
A modules() 0 5 1
A format() 0 3 1
A getManifest() 0 12 4
A build() 0 17 3
A __construct() 0 6 1
A write() 0 8 2
A joints() 0 5 1
A packagesToIgnore() 0 9 2
1
<?php
2
3
namespace Epesi\Core\System\Integration\Modules;
4
5
use Exception;
6
use Illuminate\Filesystem\Filesystem;
7
8
class PackageManifest
9
{
10
    /**
11
     * The filesystem instance.
12
     *
13
     * @var \Illuminate\Filesystem\Filesystem
14
     */
15
    public $files;
16
17
    /**
18
     * The base path.
19
     *
20
     * @var string
21
     */
22
    public $basePath;
23
24
    /**
25
     * The vendor path.
26
     *
27
     * @var string
28
     */
29
    public $vendorPath;
30
31
    /**
32
     * The manifest path.
33
     *
34
     * @var string|null
35
     */
36
    public $manifestPath;
37
38
    /**
39
     * The loaded manifest array.
40
     *
41
     * @var array
42
     */
43
    public $manifest;
44
45
    /**
46
     * Create a new package manifest instance.
47
     *
48
     * @param  \Illuminate\Filesystem\Filesystem  $files
49
     * @param  string  $basePath
50
     * @param  string  $manifestPath
51
     * @return void
52
     */
53
    public function __construct(Filesystem $files, $basePath, $manifestPath)
54
    {
55
        $this->files = $files;
56
        $this->basePath = $basePath;
57
        $this->manifestPath = $manifestPath;
58
        $this->vendorPath = $basePath.'/vendor';
59
    }
60
61
    /**
62
     * Get all of the integrator class names for all packages.
63
     *
64
     * @return array
65
     */
66
    public function joints()
67
    {
68
        return collect($this->getManifest())->flatMap(function ($configuration) {
69
            return (array) ($configuration['joints'] ?? []);
70
        })->filter()->all();
71
    }
72
    
73
    /**
74
     * Get all of the module declared for all packages.
75
     *
76
     * @return array
77
     */
78
    public function modules()
79
    {
80
    	return collect($this->getManifest())->flatMap(function ($configuration) {
81
    		return (array) ($configuration['modules'] ?? []);
82
    	})->filter()->all();
83
    }
84
85
    /**
86
     * Get the current package manifest.
87
     *
88
     * @return array
89
     */
90
    protected function getManifest()
91
    {
92
        if (isset($this->manifest)) {
93
            return $this->manifest;
94
        }
95
96
        if (! file_exists($this->manifestPath)) {
97
            $this->build();
98
        }
99
        
100
        return $this->manifest = file_exists($this->manifestPath) ?
101
            $this->files->getRequire($this->manifestPath) : [];
102
    }
103
104
    /**
105
     * Build the manifest and write it to disk.
106
     *
107
     * @return void
108
     */
109
    public function build()
110
    {
111
        $packages = [];
112
113
        if ($this->files->exists($path = $this->vendorPath.'/composer/installed.json')) {
114
            $packages = json_decode($this->files->get($path), true);
115
        }
116
117
        $ignoreAll = in_array('*', $ignore = $this->packagesToIgnore());
118
119
        $this->write(collect($packages)->mapWithKeys(function ($package) {
120
            return [$this->format($package['name']) => $package['extra']['epesi'] ?? []];
121
        })->each(function ($configuration) use (&$ignore) {
122
            $ignore = array_merge($ignore, $configuration['dont-discover'] ?? []);
123
        })->reject(function ($configuration, $package) use ($ignore, $ignoreAll) {
124
            return $ignoreAll || in_array($package, $ignore);
125
        })->filter()->all());
126
    }
127
128
    /**
129
     * Format the given package name.
130
     *
131
     * @param  string  $package
132
     * @return string
133
     */
134
    protected function format($package)
135
    {
136
        return str_replace($this->vendorPath.'/', '', $package);
137
    }
138
139
    /**
140
     * Get all of the package names that should be ignored.
141
     *
142
     * @return array
143
     */
144
    protected function packagesToIgnore()
145
    {
146
        if (! file_exists($this->basePath.'/composer.json')) {
147
            return [];
148
        }
149
150
        return json_decode(file_get_contents(
151
            $this->basePath.'/composer.json'
152
        ), true)['extra']['epesi']['dont-discover'] ?? [];
153
    }
154
155
    /**
156
     * Write the given manifest array to disk.
157
     *
158
     * @param  array  $manifest
159
     * @return void
160
     * @throws \Exception
161
     */
162
    protected function write(array $manifest)
163
    {
164
        if (! is_writable(dirname($this->manifestPath))) {
165
            throw new Exception('The '.dirname($this->manifestPath).' directory must be present and writable.');
166
        }
167
168
        $this->files->put(
169
            $this->manifestPath, '<?php return '.var_export($manifest, true).';'
170
        );
171
    }
172
}
173