35% of 1713OPs |
42% of 301Lines |
17% of 151Branches |
11% of 109Paths |
# | |
---|---|
1 |
<?php |
2 |
|
3 |
namespace mageekguy\atoum\scripts\phar; |
4 |
|
5 |
use |
6 |
mageekguy\atoum, |
7 |
mageekguy\atoum\scripts, |
8 |
mageekguy\atoum\exceptions |
9 |
; |
10 |
|
11 |
class stub extends scripts\runner |
12 |
{ |
13 |
const scriptsDirectory = 'scripts'; |
14 |
const scriptsExtension = '.php'; |
15 |
const updateUrl = 'http://downloads.atoum.org/update.php?version=%s'; |
16 |
|
17 |
protected $pharFactory = null; |
18 |
|
19 |
public function __construct($name, atoum\adapter $adapter = null)100% |
20 |
{ |
21 |
parent::__construct($name, $adapter); |
22 |
|
23 |
$this->setPharFactory(); |
24 |
} |
25 |
|
26 |
public function setPharFactory(\closure $factory = null)100% |
27 |
{ |
28 |
$this->pharFactory = $factory ?: function($path) { return new \phar($path); }; |
29 |
|
30 |
return $this; |
31 |
} |
32 |
|
33 |
public function getPharFactory()100% |
34 |
{ |
35 |
return $this->pharFactory; |
36 |
} |
37 |
|
38 |
public function listScripts()100% |
39 |
{ |
40 |
$this->writeMessage($this->locale->_('Available scripts are:') . PHP_EOL); |
41 |
$this->writeMessage(self::padding . 'builder' . PHP_EOL); |
42 |
$this->writeMessage(self::padding . 'tagger' . PHP_EOL); |
43 |
$this->writeMessage(self::padding . 'treemap' . PHP_EOL); |
44 |
$this->writeMessage(self::padding . 'coverage' . PHP_EOL); |
45 |
|
46 |
return $this->stopRun(); |
47 |
} |
48 |
|
49 |
public function useScript($script)0% |
50 |
{ |
51 |
$scriptFile = self::getScriptFile($script); |
52 |
|
53 |
if (file_exists($scriptFile) === false) |
54 |
{ |
55 |
throw new exceptions\logic\invalidArgument(sprintf($this->getLocale()->_('Script %s does not exist'), $script)); |
56 |
} |
57 |
|
58 |
require_once $scriptFile; |
59 |
|
60 |
exit(0); |
61 |
} |
62 |
|
63 |
public function infos()100% |
64 |
{ |
65 |
$phar = call_user_func($this->pharFactory, $this->getName()); |
66 |
|
67 |
$this->writeLabels($phar->getMetadata()); |
68 |
|
69 |
return $this->stopRun(); |
70 |
} |
71 |
|
72 |
public function signature()100% |
73 |
{ |
74 |
$phar = call_user_func($this->pharFactory, $this->getName()); |
75 |
|
76 |
$signature = $phar->getSignature(); |
77 |
|
78 |
$this->writeLabel($this->locale->_('Signature'), $signature['hash']); |
79 |
|
80 |
return $this->stopRun(); |
81 |
} |
82 |
|
83 |
public function extractTo($directory)5% |
84 |
{ |
85 |
if (($versions = $this->getVersions($phar = call_user_func($this->pharFactory, $this->getName()))) === null) |
86 |
{ |
87 |
throw new exceptions\runtime('Unable to extract the PHAR to \'' . $directory . '\', the versions\'s file is invalid'); |
88 |
} |
89 |
|
90 |
$directory = rtrim($directory, DIRECTORY_SEPARATOR); |
91 |
$pharName = \phar::running(); |
92 |
|
93 |
foreach (new \recursiveIteratorIterator($phar) as $pharFile) |
94 |
{ |
95 |
$pharFilePath = ltrim(str_replace($pharName, '', $pharFile), DIRECTORY_SEPARATOR); |
96 |
|
97 |
if (strpos($pharFilePath, $versions['current']) === 0) |
98 |
{ |
99 |
$path = $directory . '/' . ltrim(substr($pharFilePath, strlen($versions['current'])), DIRECTORY_SEPARATOR); |
100 |
|
101 |
$pathDirectory = dirname($path); |
102 |
|
103 |
@mkdir($pathDirectory, 0777, true); |
104 |
|
105 |
if (is_dir($pathDirectory) === false) |
106 |
{ |
107 |
throw new exceptions\runtime('Unable to create directory \'' . $pathDirectory . '\''); |
108 |
} |
109 |
|
110 |
$data = file_get_contents($pharFile); |
111 |
|
112 |
if (file_put_contents($path, $data) != strlen($data)) |
113 |
{ |
114 |
throw new exceptions\runtime('Unable to extract file \'' . $pharFilePath . '\' in directory \'' . $pathDirectory . '\''); |
115 |
} |
116 |
} |
117 |
} |
118 |
|
119 |
return $this->stopRun(); |
120 |
} |
121 |
|
122 |
public function extractResourcesTo($directory)0% |
123 |
{ |
124 |
$resourcesDirectory = $this->getResourcesDirectory(); |
125 |
$directory = rtrim($directory, DIRECTORY_SEPARATOR); |
126 |
|
127 |
foreach (new \recursiveIteratorIterator(new \recursiveDirectoryIterator($resourcesDirectory)) as $resourceFile) |
128 |
{ |
129 |
$resourceFilePath = ltrim(str_replace($resourcesDirectory, '', $resourceFile), DIRECTORY_SEPARATOR); |
130 |
|
131 |
$resourceFileDirectory = $directory . '/' . dirname($resourceFilePath); |
132 |
|
133 |
@mkdir($resourceFileDirectory, 0777, true); |
134 |
|
135 |
if (is_dir($resourceFileDirectory) === false) |
136 |
{ |
137 |
throw new exceptions\runtime('Unable to create directory \'' . $resourceFileDirectory . '\''); |
138 |
} |
139 |
|
140 |
$data = file_get_contents($resourceFile); |
141 |
|
142 |
if (file_put_contents($directory . '/' . $resourceFilePath, $data) != strlen($data)) |
143 |
{ |
144 |
throw new exceptions\runtime('Unable to extract resource file \'' . $resourceFilePath . '\' in directory \'' . $directory . '\''); |
145 |
} |
146 |
} |
147 |
|
148 |
return $this->stopRun(); |
149 |
} |
150 |
|
151 |
public function useDefaultConfigFiles($startDirectory = null)71% |
152 |
{ |
153 |
if ($startDirectory === null) |
154 |
{ |
155 |
$startDirectory = dirname($this->getName()); |
156 |
} |
157 | |
158 |
return parent::useDefaultConfigFiles($startDirectory); |
159 |
} |
160 |
|
161 |
public function version()100% |
162 |
{ |
163 |
$this |
164 |
->writeInfo(sprintf($this->locale->_('atoum version %s by %s (%s)'), atoum\version, atoum\author, \phar::running())) |
165 |
; |
166 |
|
167 |
return $this->stopRun(); |
168 |
} |
169 |
|
170 |
public function update()40% |
171 |
{ |
172 |
if ($this->adapter->ini_get('phar.readonly') == true) |
173 |
{ |
174 |
throw new exceptions\runtime('Unable to update the PHAR, phar.readonly is set, use \'-d phar.readonly=0\''); |
175 |
} |
176 |
|
177 |
if ($this->adapter->ini_get('allow_url_fopen') == false) |
178 |
{ |
179 |
throw new exceptions\runtime('Unable to update the PHAR, allow_url_fopen is not set, use \'-d allow_url_fopen=1\''); |
180 |
} |
181 |
|
182 |
if (($versions = $this->getVersions($currentPhar = call_user_func($this->pharFactory, $this->getName()))) === null) |
183 |
{ |
184 |
throw new exceptions\runtime('Unable to update the PHAR, the versions\'s file is invalid'); |
185 |
} |
186 |
|
187 |
unset($versions['current']); |
188 |
|
189 |
$this->writeMessage($this->locale->_('Checking if a new version is available...'), false); |
190 |
|
191 |
$data = json_decode($this->adapter->file_get_contents(sprintf(self::updateUrl, json_encode(array_values($versions)))), true); |
192 |
|
193 |
$this |
194 |
->clearMessage() |
195 |
->writeMessage($this->locale->_('Checking if a new version is available... Done!' . PHP_EOL)) |
196 |
; |
197 |
|
198 |
if (is_array($data) === false || isset($data['version']) === false || isset($data['phar']) === false) |
199 |
{ |
200 |
$this->writeInfo($this->locale->_('There is no new version available!')); |
201 |
} |
202 |
else |
203 |
{ |
204 |
$tmpFile = $this->adapter->realpath($this->adapter->sys_get_temp_dir()) . '/' . md5($data['version']) . '.phar'; |
205 |
|
206 |
if ($this->adapter->file_put_contents($tmpFile, utf8_decode($data['phar'])) === false) |
207 |
{ |
208 |
throw new exceptions\runtime('Unable to create temporary file to update to version \'' . $data['version']); |
209 |
} |
210 |
|
211 |
$this->writeMessage(sprintf($this->locale->_('Update to version \'%s\'...'), $data['version']), false); |
212 |
|
213 |
$pharPathLength = strlen($pharPath = 'phar://' . $tmpFile . '/1/'); |
214 |
|
215 |
$newCurrentDirectory = 1; |
216 |
|
217 |
while (isset($versions[$newCurrentDirectory]) === true) |
218 |
{ |
219 |
$newCurrentDirectory++; |
220 |
} |
221 |
|
222 |
$newFiles = new \arrayIterator(); |
223 |
|
224 |
foreach (new \recursiveIteratorIterator(new \recursiveDirectoryIterator($pharPath)) as $newFile) |
225 |
{ |
226 |
$newFiles[$newCurrentDirectory . '/' . substr($newFile, $pharPathLength)] = ($newFile = (string) $newFile); |
227 |
} |
228 |
|
229 |
$currentPhar->buildFromIterator($newFiles); |
230 |
|
231 |
$this |
232 |
->clearMessage() |
233 |
->writeMessage(sprintf($this->locale->_('Update to version \'%s\'... Done!' . PHP_EOL), $data['version'])) |
234 |
; |
235 |
|
236 |
@$this->adapter->unlink($tmpFile); |
237 |
|
238 |
$this->writeMessage(sprintf($this->locale->_('Enable version \'%s\'...'), $data['version']), false); |
239 |
|
240 |
$versions[$newCurrentDirectory] = $data['version']; |
241 |
$versions['current'] = $newCurrentDirectory; |
242 |
|
243 |
$currentPhar['versions'] = serialize($versions); |
244 |
|
245 |
$this |
246 |
->clearMessage() |
247 |
->writeMessage(sprintf($this->locale->_('Enable version \'%s\'... Done!' . PHP_EOL), $data['version'])) |
248 |
; |
249 |
|
250 |
$this->writeInfo(sprintf($this->locale->_('Atoum has been updated from version \'%s\' to \'%s\' successfully!'), atoum\version, $data['version'])); |
251 |
} |
252 |
|
253 |
return $this->stopRun(); |
254 |
} |
255 |
|
256 |
public function listAvailableVersions()0% |
257 |
{ |
258 |
$currentPhar = call_user_func($this->pharFactory, $this->getName()); |
259 |
|
260 |
if (isset($currentPhar['versions']) === false) |
261 |
{ |
262 |
throw new exceptions\runtime('Unable to list available versions in PHAR, the versions\'s file does not exist'); |
263 |
} |
264 |
|
265 |
$versions = unserialize(file_get_contents($currentPhar['versions'])); |
266 |
|
267 |
if (is_array($versions) === false || sizeof($versions) <= 0 || isset($versions['current']) === false) |
268 |
{ |
269 |
throw new exceptions\runtime('Unable to list available versions in PHAR, the versions\'s file is invalid'); |
270 |
} |
271 |
|
272 |
$currentDirectory = $versions['current']; |
273 |
|
274 |
unset($versions['current']); |
275 |
|
276 |
asort($versions); |
277 |
|
278 |
foreach ($versions as $directory => $version) |
279 |
{ |
280 |
$this->writeMessage(($directory == $currentDirectory ? '*' : ' ') . ' ' . $version . PHP_EOL); |
281 |
} |
282 |
|
283 |
return $this->stopRun(); |
284 |
} |
285 |
|
286 |
public function enableVersion($versionName, \phar $phar = null)6% |
287 |
{ |
288 |
if ($this->adapter->ini_get('phar.readonly') == true) |
289 |
{ |
290 |
throw new exceptions\runtime('Unable to update the PHAR, phar.readonly is set, use \'-d phar.readonly=0\''); |
291 |
} |
292 | |
293 |
if ($phar === null) |
294 |
{ |
295 |
$phar = call_user_func($this->pharFactory, $this->getName()); |
296 |
} |
297 |
|
298 |
if (($versions = $this->getVersions($phar)) === null) |
299 |
{ |
300 |
throw new exceptions\runtime('Unable to enable version \'' . $versionName . '\', the versions\'s file is invalid'); |
301 |
} |
302 |
|
303 |
$versionDirectory = array_search($versionName, $versions); |
304 |
|
305 |
if ($versionDirectory === false) |
306 |
{ |
307 |
throw new exceptions\runtime('Unable to enable version \'' . $versionName . '\' because it does not exist'); |
308 |
} |
309 |
|
310 |
$versions['current'] = $versionDirectory; |
311 |
|
312 |
$phar['versions'] = serialize($versions); |
313 |
|
314 |
return $this->stopRun(); |
315 |
} |
316 |
|
317 |
public function deleteVersion($versionName, \phar $phar = null)5% |
318 |
{ |
319 |
if ($this->adapter->ini_get('phar.readonly') == true) |
320 |
{ |
321 |
throw new exceptions\runtime('Unable to update the PHAR, phar.readonly is set, use \'-d phar.readonly=0\''); |
322 |
} |
323 |
|
324 |
if ($phar === null) |
325 |
{ |
326 |
$phar = call_user_func($this->pharFactory, $this->getName()); |
327 |
} |
328 |
|
329 |
if (($versions = $this->getVersions($phar)) === null) |
330 |
{ |
331 |
throw new exceptions\runtime('Unable to delete version \'' . $versionName . '\', the versions\'s file is invalid'); |
332 |
} |
333 |
|
334 |
$versionDirectory = array_search($versionName, $versions); |
335 |
|
336 |
if ($versionDirectory === false) |
337 |
{ |
338 |
throw new exceptions\runtime('Unable to delete version \'' . $versionName . '\' because it does not exist'); |
339 |
} |
340 |
|
341 |
if ($versionDirectory == $versions['current']) |
342 |
{ |
343 |
throw new exceptions\runtime('Unable to delete version \'' . $versionName . '\' because it is the current version'); |
344 |
} |
345 |
|
346 |
unset($versions[$versionDirectory]); |
347 |
unset($phar[$versionDirectory]); |
348 |
|
349 |
$phar['versions'] = serialize($versions); |
350 |
|
351 |
return $this->stopRun(); |
352 |
} |
353 |
|
354 |
public function getResourcesDirectory()0% |
355 |
{ |
356 |
if (($versions = $this->getVersions($phar = call_user_func($this->pharFactory, $this->getName()))) === null) |
357 |
{ |
358 |
throw new exceptions\runtime('Unable to define resources directory, verions\'s file is invalid'); |
359 |
} |
360 |
|
361 |
if (isset($phar[$versions['current'] . '/resources']) === false) |
362 |
{ |
363 |
throw new exceptions\logic('Resources directory does not exist in PHAR \'' . $this->getName() . '\''); |
364 |
} |
365 |
|
366 |
return 'phar://' . $this->getName() . '/' . $versions['current'] . '/resources'; |
367 |
} |
368 |
|
369 |
protected function setArgumentHandlers()63% |
370 |
{ |
371 |
return |
372 |
parent::setArgumentHandlers() |
373 |
->addArgumentHandler( |
374 |
function($script, $argument, $values) { |
375 |
if (sizeof($values) !== 0) |
376 |
{ |
377 |
throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName())); |
378 |
} |
379 |
|
380 |
$script->infos(); |
381 |
}, |
382 |
array('-i', '--infos'), |
383 |
null, |
384 |
$this->locale->_('Display informations, do not run any script') |
385 |
) |
386 |
->addArgumentHandler( |
387 |
function($script, $argument, $values) { |
388 |
if (sizeof($values) !== 0) |
389 |
{ |
390 |
throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName())); |
391 |
} |
392 |
|
393 |
$script->signature(); |
394 |
}, |
395 |
array('-s', '--signature'), |
396 |
null, |
397 |
$this->locale->_('Display phar signature, do not run any script') |
398 |
) |
399 |
->addArgumentHandler( |
400 |
function($script, $argument, $values) { |
401 |
if (sizeof($values) !== 1) |
402 |
{ |
403 |
throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName())); |
404 |
} |
405 |
|
406 |
$script->extractTo($values[0]); |
407 |
}, |
408 |
array('-e', '--extract-to'), |
409 |
'<directory>', |
410 |
$this->locale->_('Extract all file from phar to <directory>, do not run any script') |
411 |
) |
412 |
->addArgumentHandler( |
413 |
function($script, $argument, $values) { |
414 |
if (sizeof($values) !== 1) |
415 |
{ |
416 |
throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName())); |
417 |
} |
418 |
|
419 |
$script->extractResourcesTo($values[0]); |
420 |
}, |
421 |
array('-er', '--extract-resources-to'), |
422 |
'<directory>', |
423 |
$this->locale->_('Extract resources from phar to <directory>, do not run any script') |
424 |
) |
425 |
->addArgumentHandler( |
426 |
function($script, $argument, $values, $position) { |
427 |
if ($position !== 1 || sizeof($values) !== 1) |
428 |
{ |
429 |
throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName())); |
430 |
} |
431 |
|
432 |
unset($_SERVER['argv'][1]); |
433 |
unset($_SERVER['argv'][2]); |
434 |
|
435 |
$script->useScript($values[0]); |
436 |
|
437 |
}, |
438 |
array('-u', '--use'), |
439 |
'<script> <args>', |
440 |
$this->locale->_('Run script <script> from PHAR with <args> as arguments (this argument must be the first)'), |
441 |
4 |
442 |
) |
443 |
->addArgumentHandler( |
444 |
function($script, $argument, $values) { |
445 |
if (sizeof($values) > 0) |
446 |
{ |
447 |
throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName())); |
448 |
} |
449 |
|
450 |
$script->listScripts(); |
451 |
}, |
452 |
array('-ls', '--list-scripts'), |
453 |
null, |
454 |
$this->locale->_('List available scripts') |
455 |
) |
456 |
->addArgumentHandler( |
457 |
function($script, $argument, $values) { |
458 |
if (sizeof($values) > 0) |
459 |
{ |
460 |
throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName())); |
461 |
} |
462 |
|
463 |
$script->update(); |
464 |
}, |
465 |
array('--update'), |
466 |
null, |
467 |
$this->locale->_('Update atoum') |
468 |
) |
469 |
->addArgumentHandler( |
470 |
function($script, $argument, $values) { |
471 |
if (sizeof($values) > 0) |
472 |
{ |
473 |
throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName())); |
474 |
} |
475 |
|
476 |
$script->listAvailableVersions(); |
477 |
}, |
478 |
array('-lav', '--list-available-versions'), |
479 |
null, |
480 |
$this->locale->_('List available versions in the PHAR') |
481 |
) |
482 |
->addArgumentHandler( |
483 |
function($script, $argument, $values) { |
484 |
if (sizeof($values) != 1) |
485 |
{ |
486 |
throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName())); |
487 |
} |
488 |
|
489 |
$script->enableVersion($values[0]); |
490 |
}, |
491 |
array('-ev', '--enable-version'), |
492 |
'<version>', |
493 |
$this->locale->_('Enable version <version>') |
494 |
) |
495 |
->addArgumentHandler( |
496 |
function($script, $argument, $values) { |
497 |
if (sizeof($values) != 1) |
498 |
{ |
499 |
throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName())); |
500 |
} |
501 |
|
502 |
$script->deleteVersion($values[0]); |
503 |
}, |
504 |
array('-dv', '--delete-version'), |
505 |
'<version>', |
506 |
$this->locale->_('Delete version <version>') |
507 |
) |
508 |
; |
509 |
|
510 |
return $this; |
511 |
} |
512 |
|
513 |
protected function getVersions(\phar $phar)80% |
514 |
{ |
515 |
if (isset($phar['versions']) === false) |
516 |
{ |
517 |
throw new exceptions\runtime('The versions\'s file does not exist'); |
518 |
} |
519 |
|
520 |
$versions = unserialize($this->adapter->file_get_contents($phar['versions'])); |
521 |
|
522 |
return ((is_array($versions) === false || isset($versions['current']) === false || isset($versions[$versions['current']]) === false) ? null : $versions); |
523 |
} |
524 |
|
525 |
protected static function getScriptFile($scriptName)0% |
526 |
{ |
527 |
return atoum\directory . '/' . self::scriptsDirectory . '/' . $scriptName . self::scriptsExtension; |
528 |
} |
529 |
} |