Test Failed
Push — master ( 8f2167...5d2217 )
by Georgi
08:27
created

PackageManifest   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 164
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 45
dl 0
loc 164
rs 10
c 0
b 0
f 0
wmc 15

8 Methods

Rating   Name   Duplication   Size   Complexity  
A joints() 0 5 1
A format() 0 3 1
A write() 0 8 2
A getManifest() 0 12 4
A build() 0 17 3
A __construct() 0 6 1
A packagesToIgnore() 0 9 2
A modules() 0 7 1
1
<?php
2
3
namespace Epesi\Core\System\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, $package) {
81
    		return array_map(function($moduleRelativePath) use ($package) {
82
    			return str_ireplace('/', DIRECTORY_SEPARATOR, implode('/', [$this->vendorPath, $package, $moduleRelativePath]));
83
    		}, (array) ($configuration['modules'] ?? []));
84
    	})->filter()->all();
85
    }
86
87
    /**
88
     * Get the current package manifest.
89
     *
90
     * @return array
91
     */
92
    protected function getManifest()
93
    {
94
        if (isset($this->manifest)) {
95
            return $this->manifest;
96
        }
97
98
        if (! file_exists($this->manifestPath)) {
99
            $this->build();
100
        }
101
        
102
        return $this->manifest = file_exists($this->manifestPath) ?
103
            $this->files->getRequire($this->manifestPath) : [];
104
    }
105
106
    /**
107
     * Build the manifest and write it to disk.
108
     *
109
     * @return void
110
     */
111
    public function build()
112
    {
113
        $packages = [];
114
115
        if ($this->files->exists($path = $this->vendorPath.'/composer/installed.json')) {
116
            $packages = json_decode($this->files->get($path), true);
117
        }
118
119
        $ignoreAll = in_array('*', $ignore = $this->packagesToIgnore());
120
121
        $this->write(collect($packages)->mapWithKeys(function ($package) {
122
            return [$this->format($package['name']) => $package['extra']['epesi'] ?? []];
123
        })->each(function ($configuration) use (&$ignore) {
124
            $ignore = array_merge($ignore, $configuration['dont-discover'] ?? []);
125
        })->reject(function ($configuration, $package) use ($ignore, $ignoreAll) {
126
            return $ignoreAll || in_array($package, $ignore);
127
        })->filter()->all());
128
    }
129
130
    /**
131
     * Format the given package name.
132
     *
133
     * @param  string  $package
134
     * @return string
135
     */
136
    protected function format($package)
137
    {
138
        return str_replace($this->vendorPath.'/', '', $package);
139
    }
140
141
    /**
142
     * Get all of the package names that should be ignored.
143
     *
144
     * @return array
145
     */
146
    protected function packagesToIgnore()
147
    {
148
        if (! file_exists($this->basePath.'/composer.json')) {
149
            return [];
150
        }
151
152
        return json_decode(file_get_contents(
153
            $this->basePath.'/composer.json'
154
        ), true)['extra']['epesi']['dont-discover'] ?? [];
155
    }
156
157
    /**
158
     * Write the given manifest array to disk.
159
     *
160
     * @param  array  $manifest
161
     * @return void
162
     * @throws \Exception
163
     */
164
    protected function write(array $manifest)
165
    {
166
        if (! is_writable(dirname($this->manifestPath))) {
167
            throw new Exception('The '.dirname($this->manifestPath).' directory must be present and writable.');
168
        }
169
170
        $this->files->put(
171
            $this->manifestPath, '<?php return '.var_export($manifest, true).';'
172
        );
173
    }
174
}
175