Add package management

This commit is contained in:
crazywhalecc
2024-02-18 13:54:06 +08:00
committed by Jerry Ma
parent 78f4317660
commit a30e054d7d
18 changed files with 481 additions and 85 deletions

View File

@@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace SPC\command;
use SPC\exception\DownloaderException;
use SPC\exception\FileSystemException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
#[AsCommand('del-download', 'Remove locked download source or package using name', ['delete-download', 'del-down'])]
class DeleteDownloadCommand extends BaseCommand
{
public function configure(): void
{
$this->addArgument('sources', InputArgument::REQUIRED, 'The sources/packages will be deleted, comma separated');
$this->addOption('all', 'A', null, 'Delete all downloaded and locked sources/packages');
}
public function initialize(InputInterface $input, OutputInterface $output): void
{
if ($input->getOption('all')) {
$input->setArgument('sources', '');
}
parent::initialize($input, $output);
}
/**
* @throws FileSystemException
*/
public function handle(): int
{
try {
// get source list that will be downloaded
$sources = array_map('trim', array_filter(explode(',', $this->getArgument('sources'))));
if (empty($sources)) {
logger()->notice('Removing downloads/ directory ...');
FileSystem::removeDir(DOWNLOAD_PATH);
logger()->info('Removed downloads/ dir!');
return static::SUCCESS;
}
$chosen_sources = $sources;
$lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? [];
foreach ($chosen_sources as $source) {
$source = trim($source);
if (!isset($lock[$source])) {
logger()->warning("Source/Package [{$source}] not locked or not downloaded, skipped.");
continue;
}
// remove download file/dir if exists
if ($lock[$source]['source_type'] === 'archive') {
if (file_exists($path = FileSystem::convertPath(DOWNLOAD_PATH . '/' . $lock[$source]['filename']))) {
logger()->info('Deleting file ' . $path);
unlink($path);
} else {
logger()->warning("Source/Package [{$source}] file not found, skip deleting file.");
}
} else {
if (is_dir($path = FileSystem::convertPath(DOWNLOAD_PATH . '/' . $lock[$source]['dirname']))) {
logger()->info('Deleting dir ' . $path);
FileSystem::removeDir($path);
} else {
logger()->warning("Source/Package [{$source}] directory not found, skip deleting dir.");
}
}
// remove locked sources
unset($lock[$source]);
}
FileSystem::writeFile(DOWNLOAD_PATH . '/.lock.json', json_encode($lock, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
logger()->info('Delete success!');
return static::SUCCESS;
} catch (DownloaderException $e) {
logger()->error($e->getMessage());
return static::FAILURE;
} catch (WrongUsageException $e) {
logger()->critical($e->getMessage());
return static::FAILURE;
}
}
}

View File

@@ -8,11 +8,11 @@ use SPC\builder\traits\UnixSystemUtilTrait;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\SourceExtractor;
use SPC\store\SourceManager;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
#[AsCommand('extract', 'Extract required sources')]
#[AsCommand('extract', 'Extract required sources', ['extract-source'])]
class ExtractCommand extends BaseCommand
{
use UnixSystemUtilTrait;
@@ -34,7 +34,7 @@ class ExtractCommand extends BaseCommand
$this->output->writeln('<error>sources cannot be empty, at least contain one !</error>');
return static::FAILURE;
}
SourceExtractor::initSource(sources: $sources);
SourceManager::initSource(sources: $sources);
logger()->info('Extract done !');
return static::SUCCESS;
}

View File

@@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace SPC\command;
use SPC\builder\traits\UnixSystemUtilTrait;
use SPC\exception\DownloaderException;
use SPC\exception\FileSystemException;
use SPC\exception\WrongUsageException;
use SPC\store\Config;
use SPC\store\PackageManager;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
#[AsCommand('install-pkg', 'Install additional packages', ['i', 'install-package'])]
class InstallPkgCommand extends BaseCommand
{
use UnixSystemUtilTrait;
public function configure(): void
{
$this->addArgument('packages', InputArgument::REQUIRED, 'The packages will be installed, comma separated');
$this->addOption('shallow-clone', null, null, 'Clone shallow');
$this->addOption('custom-url', 'U', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Specify custom source download url, e.g "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"');
}
/**
* @throws FileSystemException
*/
public function handle(): int
{
try {
// Use shallow-clone can reduce git resource download
if ($this->getOption('shallow-clone')) {
define('GIT_SHALLOW_CLONE', true);
}
// Process -U options
$custom_urls = [];
foreach ($this->input->getOption('custom-url') as $value) {
[$pkg_name, $url] = explode(':', $value, 2);
$custom_urls[$pkg_name] = $url;
}
$chosen_pkgs = array_map('trim', array_filter(explode(',', $this->getArgument('packages'))));
// Download them
f_mkdir(DOWNLOAD_PATH);
$ni = 0;
$cnt = count($chosen_pkgs);
foreach ($chosen_pkgs as $pkg) {
++$ni;
if (isset($custom_urls[$pkg])) {
$config = Config::getPkg($pkg);
$new_config = [
'type' => 'url',
'url' => $custom_urls[$pkg],
];
if (isset($config['extract'])) {
$new_config['extract'] = $config['extract'];
}
if (isset($config['filename'])) {
$new_config['filename'] = $config['filename'];
}
logger()->info("Installing source {$pkg} from custom url [{$ni}/{$cnt}]");
PackageManager::installPackage($pkg, $new_config);
} else {
logger()->info("Fetching package {$pkg} [{$ni}/{$cnt}]");
PackageManager::installPackage($pkg, Config::getPkg($pkg));
}
}
$time = round(microtime(true) - START_TIME, 3);
logger()->info('Install packages complete, used ' . $time . ' s !');
return static::SUCCESS;
} catch (DownloaderException $e) {
logger()->error($e->getMessage());
return static::FAILURE;
} catch (WrongUsageException $e) {
logger()->critical($e->getMessage());
return static::FAILURE;
}
}
}