1 | <?php |
||
81 | class MergePlugin implements PluginInterface, EventSubscriberInterface |
||
82 | { |
||
83 | |||
84 | /** |
||
85 | * Offical package name |
||
86 | */ |
||
87 | const PACKAGE_NAME = 'wikimedia/composer-merge-plugin'; |
||
88 | |||
89 | /** |
||
90 | * @var Composer $composer |
||
91 | */ |
||
92 | protected $composer; |
||
93 | |||
94 | /** |
||
95 | * @var PluginState $state |
||
96 | */ |
||
97 | protected $state; |
||
98 | |||
99 | /** |
||
100 | * @var Logger $logger |
||
101 | */ |
||
102 | protected $logger; |
||
103 | |||
104 | /** |
||
105 | * @var IOInterface $io |
||
106 | */ |
||
107 | protected $io; |
||
108 | |||
109 | /** |
||
110 | * Files that have already been processed |
||
111 | * |
||
112 | * @var string[] $loadedFiles |
||
113 | */ |
||
114 | 105 | protected $loadedFiles = array(); |
|
115 | |||
116 | 105 | /** |
|
117 | 105 | * {@inheritdoc} |
|
118 | 105 | */ |
|
119 | 105 | public function activate(Composer $composer, IOInterface $io) |
|
120 | { |
||
121 | $this->composer = $composer; |
||
122 | $this->state = new PluginState($this->composer); |
||
123 | $this->io = $io; |
||
124 | 5 | $this->logger = new Logger('merge-plugin', $io); |
|
125 | } |
||
126 | |||
127 | 5 | /** |
|
128 | 5 | * {@inheritdoc} |
|
129 | 5 | */ |
|
130 | 5 | public static function getSubscribedEvents() |
|
142 | |||
143 | /** |
||
144 | 85 | * Handle an event callback for an install, update or dump command by |
|
145 | * checking for "merge-plugin" in the "extra" data and merging package |
||
146 | 85 | * contents if found. |
|
147 | 85 | * |
|
148 | 85 | * @param Event $event |
|
149 | 85 | */ |
|
150 | public function onInstallUpdateOrDump(Event $event) |
||
165 | |||
166 | /** |
||
167 | * Find configuration files matching the configured glob patterns and |
||
168 | * merge their contents with the master package. |
||
169 | 85 | * |
|
170 | * @param array $patterns List of files/glob patterns |
||
171 | 85 | * @param bool $required Are the patterns required to match files? |
|
172 | * @throws MissingFileException when required and a pattern returns no |
||
173 | 85 | * results |
|
174 | 85 | */ |
|
175 | 85 | protected function mergeFiles(array $patterns, $required = false) |
|
176 | 5 | { |
|
177 | 5 | $root = $this->composer->getPackage(); |
|
178 | 5 | ||
179 | $files = array_map( |
||
180 | 80 | function ($files, $pattern) use ($required) { |
|
181 | 85 | if ($required && !$files) { |
|
182 | 85 | throw new MissingFileException( |
|
183 | "merge-plugin: No files matched required '{$pattern}'" |
||
184 | 85 | ); |
|
185 | } |
||
186 | 85 | return $files; |
|
187 | 80 | }, |
|
188 | 85 | array_map(array($this, 'validatePath'), $patterns), |
|
189 | 85 | $patterns |
|
190 | ); |
||
191 | |||
192 | foreach (array_reduce($files, 'array_merge', array()) as $path) { |
||
193 | $this->mergeFile($root, $path); |
||
194 | } |
||
195 | } |
||
196 | |||
197 | 80 | protected function validatePath($path){ |
|
198 | if(substr($path, 0, 4) === 'http'){ |
||
199 | 80 | $headers = get_headers ( $path ); |
|
200 | 80 | if ( strpos($headers[0], '404') == 0){ |
|
201 | 80 | return array($path); |
|
202 | }else{ |
||
203 | 80 | return []; |
|
204 | } |
||
205 | 80 | }else{ |
|
206 | return glob($path); |
||
207 | 80 | } |
|
208 | 80 | } |
|
209 | |||
210 | 80 | /** |
|
211 | 75 | * Read a JSON file and merge its contents |
|
212 | 75 | * |
|
213 | 75 | * @param RootPackageInterface $root |
|
214 | 80 | * @param string $path |
|
215 | */ |
||
216 | protected function mergeFile(RootPackageInterface $root, $path) |
||
217 | { |
||
218 | if (isset($this->loadedFiles[$path])) { |
||
219 | $this->logger->debug("Already merged <comment>$path</comment>"); |
||
220 | return; |
||
221 | } else { |
||
222 | $this->loadedFiles[$path] = true; |
||
223 | } |
||
224 | 80 | $this->logger->info("Loading <comment>{$path}</comment>..."); |
|
225 | |||
226 | 80 | $package = new ExtraPackage($path, $this->composer, $this->logger, $this->io); |
|
227 | 80 | $package->mergeInto($root, $this->state); |
|
228 | 10 | ||
229 | 10 | if ($this->state->recurseIncludes()) { |
|
230 | 10 | $this->mergeFiles($package->getIncludes(), false); |
|
231 | 10 | $this->mergeFiles($package->getRequires(), true); |
|
232 | 80 | } |
|
233 | 80 | } |
|
234 | 75 | ||
235 | 5 | /** |
|
236 | 5 | * Handle an event callback for pre-dependency solving phase of an install |
|
237 | 5 | * or update by adding any duplicate package dependencies found during |
|
238 | 5 | * initial merge processing to the request that will be processed by the |
|
239 | 75 | * dependency solver. |
|
240 | 75 | * |
|
241 | 80 | * @param InstallerEvent $event |
|
242 | */ |
||
243 | public function onDependencySolve(InstallerEvent $event) |
||
261 | 15 | ||
262 | 15 | /** |
|
263 | * Handle an event callback following installation of a new package by |
||
264 | * checking to see if the package that was installed was our plugin. |
||
265 | * |
||
266 | * @param PackageEvent $event |
||
267 | */ |
||
268 | public function onPostPackageInstall(PackageEvent $event) |
||
282 | |||
283 | /** |
||
284 | * Handle an event callback following an install or update command. If our |
||
285 | * plugin was installed during the run then trigger an update command to |
||
286 | * process any merge-patterns in the current config. |
||
287 | * |
||
288 | * @param Event $event |
||
289 | */ |
||
290 | public function onPostInstallOrUpdate(Event $event) |
||
332 | } |
||
333 | // vim:sw=4:ts=4:sts=4:et: |
||
334 |