From ea3fdc5511d5dad649c006abb17d822e975a5d28 Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Thu, 18 Jul 2024 23:51:22 +0400 Subject: [PATCH] Polishing --- .gitignore | 1 + .../roadrunner-2024.1.5-windows-amd64.zip | Bin 0 -> 7224 bytes src/Command/Get.php | 107 +----------- src/DLoad.php | 154 ++++++++++++++++++ src/Module/Downloader/TaskManager.php | 1 + 5 files changed, 164 insertions(+), 99 deletions(-) create mode 100644 resources/mock/roadrunner-2024.1.5-windows-amd64.zip create mode 100644 src/DLoad.php diff --git a/.gitignore b/.gitignore index a333a05..88afc22 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /vendor/ /.env *.log +*.exe diff --git a/resources/mock/roadrunner-2024.1.5-windows-amd64.zip b/resources/mock/roadrunner-2024.1.5-windows-amd64.zip new file mode 100644 index 0000000000000000000000000000000000000000..cc6e995638ee33ed62d24ab133c334108c08cf96 GIT binary patch literal 7224 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 literal 0 HcmV?d00001 diff --git a/src/Command/Get.php b/src/Command/Get.php index 250c614..a4dd613 100644 --- a/src/Command/Get.php +++ b/src/Command/Get.php @@ -5,6 +5,7 @@ namespace Internal\DLoad\Command; use Internal\DLoad\Bootstrap; +use Internal\DLoad\DLoad; use Internal\DLoad\Module\Archive\ArchiveFactory; use Internal\DLoad\Module\Common\Architecture; use Internal\DLoad\Module\Common\Config\Destination; @@ -90,6 +91,7 @@ protected function execute( environment: \getenv(), )->finish(); $container->set($input, InputInterface::class); + $container->set($output, OutputInterface::class); $container->set(new SymfonyStyle($input, $output), StyleInterface::class); $container->set($this->logger); @@ -97,106 +99,13 @@ protected function execute( $output->writeln(' Op. system: ' . $container->get(OperatingSystem::class)->name); $output->writeln(' Stability: ' . $container->get(Stability::class)->name); - /** @var SoftwareCollection $softwareCollection */ - $softwareCollection = $container->get(SoftwareCollection::class); - /** @var ArchiveFactory $archiveFactory */ - $archiveFactory = $container->get(ArchiveFactory::class); - /** @var Downloader $downloader */ - $downloader = $container->get(Downloader::class); - - // / /* - $task = $downloader->download( - $softwareCollection->findSoftware('rr') ?? throw new \RuntimeException('Software not found.'), - static fn() => null, - ); - /*/ - $task = new \Internal\DLoad\Module\Downloader\Task\DownloadTask( - $softwareCollection->findSoftware('rr') ?? throw new \RuntimeException('Software not found.'), - static fn() => null, - fn(): \React\Promise\PromiseInterface => \React\Promise\resolve(new DownloadResult( - new \SplFileInfo('C:\Users\test\AppData\Local\Temp\roadrunner-2024.1.5-windows-amd64.zip'), - '2024.1.5' - )), - ); - //*/ - - ($task->handler)()->then( - function (DownloadResult $downloadResult) use ($task, $archiveFactory, $output): void { - $fileInfo = $downloadResult->file; - $archive = $archiveFactory->create($fileInfo); - $extractor = $archive->extract(); - - while ($extractor->valid()) { - $file = $extractor->current(); - \assert($file instanceof \SplFileInfo); - - $to = $this->shouldBeExtracted($file, $task->software->files); - - if ($to === null || !$this->checkExisting($to)) { - $extractor->next(); - continue; - } - - $extractor->send($to); - - // Success - $path = $to->getRealPath() ?: $to->getPathname(); - $output->writeln(\sprintf( - '%s (%s) has been installed into %s', - $to->getFilename(), - $downloadResult->version, - $path, - )); - - $to->isExecutable() or @\chmod($path, 0755); - } - }, - ); + /** @var DLoad $dload */ + $dload = $container->get(DLoad::class); - return Command::SUCCESS; - } - - /** - * @return bool True if the file should be extracted, false otherwise. - */ - private function checkExisting(\SplFileInfo $bin): bool - { - if (! \is_file($bin->getPathname())) { - return true; - } - - /** @var StyleInterface $io */ - $io = $this->container->get(StyleInterface::class); - $io->warning('File already exists: ' . $bin->getPathname()); - if (!$io->confirm('Do you want overwrite it?', false)) { - $io->note('Skipping ' . $bin->getFilename() . ' installation...'); - return false; - } + $binary = $input->getArgument('binary'); + $dload->addTask($binary); + $dload->run(); - return true; - } - - /** - * @param array $mapping - */ - private function shouldBeExtracted(\SplFileInfo $source, array $mapping): ?\SplFileInfo - { - /** @var Destination $destination */ - $destination = $this->container->get(Destination::class); - $path = $destination->path ?? \getcwd(); - - foreach ($mapping as $conf) { - if (\preg_match($conf->pattern, $source->getFilename())) { - $newName = match(true) { - $conf->rename === null => $source->getFilename(), - $source->getExtension() === '' => $conf->rename, - default => $conf->rename . '.' . $source->getExtension(), - }; - - return new \SplFileInfo($path . DIRECTORY_SEPARATOR . $newName); - } - } - - return null; + return Command::SUCCESS; } } diff --git a/src/DLoad.php b/src/DLoad.php new file mode 100644 index 0000000..2670b57 --- /dev/null +++ b/src/DLoad.php @@ -0,0 +1,154 @@ +useMock and $softwareName = 'rr'; + $this->taskManager->addTask(function () use ($softwareName): void { + // Find Software + $software = $this->softwareCollection->findSoftware($softwareName) ?? throw new \RuntimeException( + 'Software not found.', + ); + + // Create a Download task + $task = $this->prepareDownloadTask($software); + + // Extract files + ($task->handler)()->then($this->prepareExtractTask($software)); + }); + } + + public function run(): void + { + $this->taskManager->await(); + } + + private function prepareDownloadTask(Software $software): DownloadTask + { + return $this->useMock + ? new DownloadTask( + $software, + static fn() => null, + static fn(): PromiseInterface => resolve( + new DownloadResult( + new \SplFileInfo(Info::ROOT_DIR . '/resources/mock/roadrunner-2024.1.5-windows-amd64.zip'), + '2024.1.5', + ), + ), + ) + : $this->downloader->download($software, static fn() => null); + } + + /** + * @return \Closure(DownloadResult): void + */ + private function prepareExtractTask(Software $software): \Closure + { + return function (DownloadResult $downloadResult) use ($software): void { + $fileInfo = $downloadResult->file; + $archive = $this->archiveFactory->create($fileInfo); + $extractor = $archive->extract(); + + while ($extractor->valid()) { + $file = $extractor->current(); + \assert($file instanceof \SplFileInfo); + + $to = $this->shouldBeExtracted($file, $software->files); + + if ($to === null || !$this->checkExisting($to)) { + $extractor->next(); + continue; + } + + $extractor->send($to); + + // Success + $path = $to->getRealPath() ?: $to->getPathname(); + $this->output->writeln(\sprintf( + '%s (%s) has been installed into %s', + $to->getFilename(), + $downloadResult->version, + $path, + )); + + $to->isExecutable() or @\chmod($path, 0755); + } + }; + } + + /** + * @return bool True if the file should be extracted, false otherwise. + */ + private function checkExisting(\SplFileInfo $bin): bool + { + if (\is_file($bin->getPathname())) { + $this->io->warning('File already exists: ' . $bin->getPathname()); + if (!$this->io->confirm('Do you want overwrite it?', false)) { + $this->io->note('Skipping ' . $bin->getFilename() . ' installation...'); + return false; + } + } + + return true; + } + + /** + * @param list $mapping + */ + private function shouldBeExtracted(\SplFileInfo $source, array $mapping): ?\SplFileInfo + { + $path = $this->configDestination->path ?? \getcwd(); + + foreach ($mapping as $conf) { + if (\preg_match($conf->pattern, $source->getFilename())) { + $newName = match(true) { + $conf->rename === null => $source->getFilename(), + $source->getExtension() === '' => $conf->rename, + default => $conf->rename . '.' . $source->getExtension(), + }; + + return new \SplFileInfo($path . DIRECTORY_SEPARATOR . $newName); + } + } + + return null; + } +} diff --git a/src/Module/Downloader/TaskManager.php b/src/Module/Downloader/TaskManager.php index dfd04f5..6959eda 100644 --- a/src/Module/Downloader/TaskManager.php +++ b/src/Module/Downloader/TaskManager.php @@ -31,6 +31,7 @@ public function getProcessor(): \Generator try { if ($task->isTerminated()) { unset($this->tasks[$key]); + continue; } if (!$task->isStarted()) {