-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added Archive module; add code to download and extract files
- Loading branch information
Showing
18 changed files
with
418 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
".": "0.1.0" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Internal\DLoad; | ||
|
||
/** | ||
* @internal | ||
*/ | ||
class Info | ||
{ | ||
public const NAME = 'DLoad'; | ||
|
||
public const LOGO_CLI_COLOR = ''; | ||
|
||
public const ROOT_DIR = __DIR__ . '/..'; | ||
|
||
private const VERSION = 'experimental'; | ||
|
||
/** | ||
* Returns the version of the Trap. | ||
* | ||
* @return non-empty-string | ||
*/ | ||
public static function version(): string | ||
{ | ||
/** @var non-empty-string|null $cache */ | ||
static $cache = null; | ||
|
||
if ($cache !== null) { | ||
return $cache; | ||
} | ||
|
||
$fileContent = \file_get_contents(self::ROOT_DIR . '/resources/version.json'); | ||
|
||
if ($fileContent === false) { | ||
return $cache = self::VERSION; | ||
} | ||
|
||
/** @var mixed $version */ | ||
$version = \json_decode($fileContent, true)['.'] ?? null; | ||
|
||
return $cache = \is_string($version) && $version !== '' | ||
? $version | ||
: self::VERSION; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Internal\DLoad\Module\Archive; | ||
|
||
interface Archive | ||
{ | ||
/** | ||
* Iterate archive files. If a {@see \SplFileInfo} is backed into the generator, the file will be | ||
* extracted to the given location. | ||
* | ||
* @return \Generator<non-empty-string, \SplFileInfo, \SplFileInfo|null, void> | ||
*/ | ||
public function extract(): \Generator; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Internal\DLoad\Module\Archive; | ||
|
||
use Closure as ArchiveMatcher; | ||
use Internal\DLoad\Module\Archive\Internal\PharArchive; | ||
use Internal\DLoad\Module\Archive\Internal\TarPharArchive; | ||
use Internal\DLoad\Module\Archive\Internal\ZipPharArchive; | ||
|
||
/** | ||
* @psalm-type ArchiveMatcher = \Closure(\SplFileInfo): ?Archive | ||
*/ | ||
final class ArchiveFactory | ||
{ | ||
/** | ||
* @var array<ArchiveMatcher> | ||
*/ | ||
private array $matchers = []; | ||
|
||
/** | ||
* FactoryTrait constructor. | ||
*/ | ||
public function __construct() | ||
{ | ||
$this->bootDefaultMatchers(); | ||
} | ||
|
||
public function extend(\Closure $matcher): void | ||
{ | ||
\array_unshift($this->matchers, $matcher); | ||
} | ||
|
||
public function create(\SplFileInfo $file): Archive | ||
{ | ||
$errors = []; | ||
|
||
foreach ($this->matchers as $matcher) { | ||
try { | ||
if ($archive = $matcher($file)) { | ||
return $archive; | ||
} | ||
} catch (\Throwable $e) { | ||
$errors[] = ' - ' . $e->getMessage(); | ||
continue; | ||
} | ||
} | ||
|
||
$error = \sprintf("Can not open the archive \"%s\":\n%s", $file->getFilename(), \implode(\PHP_EOL, $errors)); | ||
|
||
throw new \InvalidArgumentException($error); | ||
} | ||
|
||
private function bootDefaultMatchers(): void | ||
{ | ||
$this->extend($this->matcher( | ||
'zip', | ||
static fn(\SplFileInfo $info): Archive => new ZipPharArchive($info), | ||
)); | ||
|
||
$this->extend($this->matcher( | ||
'tar.gz', | ||
static fn(\SplFileInfo $info): Archive => new TarPharArchive($info), | ||
)); | ||
|
||
$this->extend($this->matcher( | ||
'phar', | ||
static fn(\SplFileInfo $info): Archive => new PharArchive($info), | ||
)); | ||
} | ||
|
||
/** | ||
* @param string $extension | ||
* @param ArchiveMatcher $then | ||
* | ||
* @return ArchiveMatcher | ||
*/ | ||
private function matcher(string $extension, \Closure $then): \Closure | ||
{ | ||
return static fn(\SplFileInfo $info): ?Archive => | ||
\str_ends_with(\strtolower($info->getFilename()), '.' . $extension) ? $then($info) : null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Internal\DLoad\Module\Archive\Internal; | ||
|
||
use Internal\DLoad\Module\Archive\Archive as ArchiveInterface; | ||
|
||
abstract class Archive implements ArchiveInterface | ||
{ | ||
/** | ||
* @param \SplFileInfo $archive | ||
*/ | ||
public function __construct(\SplFileInfo $archive) | ||
{ | ||
$this->assertArchiveValid($archive); | ||
} | ||
|
||
/** | ||
* @param \SplFileInfo $archive | ||
*/ | ||
private function assertArchiveValid(\SplFileInfo $archive): void | ||
{ | ||
if (! $archive->isFile()) { | ||
throw new \InvalidArgumentException( | ||
\sprintf('Archive "%s" is not a file.', $archive->getFilename()), | ||
); | ||
} | ||
|
||
if (! $archive->isReadable()) { | ||
throw new \InvalidArgumentException( | ||
\sprintf('Archive file "%s" is not readable.', $archive->getFilename()), | ||
); | ||
} | ||
} | ||
} |
Oops, something went wrong.