diff --git a/src/Command/ExtractCommand.php b/src/Command/ExtractCommand.php index 8498294..f69082a 100644 --- a/src/Command/ExtractCommand.php +++ b/src/Command/ExtractCommand.php @@ -3,9 +3,14 @@ use modmore\Gitify\BaseCommand; use modmore\Gitify\Gitify; +use modTransportPackage; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Yaml\Exception\ParseException; +use Symfony\Component\Yaml\Yaml; +use xPDOTransport; /** * Class BuildCommand @@ -32,6 +37,13 @@ protected function configure() InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Specify the data partition key (folder name), or keys separated by a space, that you want to extract. ' ) + ->addOption( + 'packages', + 'p', + InputOption::VALUE_NEGATABLE, + 'Skip extracting installed package when set.', + true + ) ; } @@ -77,6 +89,10 @@ protected function execute(InputInterface $input, OutputInterface $output) } } + if ($input->getOption('packages')) { + $this->extractPackages(); + } + $output->writeln('Done! ' . $this->getRunStats()); return 0; } @@ -447,4 +463,55 @@ protected function filterPathSegment($path) } return \modResource::filterPathSegment($this->modx, $path, $options); } + + private function extractPackages(): void + { + $this->output->writeln('Extracting installed packages...'); + $file = GITIFY_WORKING_DIR . '.gitify'; + $data = Yaml::parseFile($file); + + $result = $this->modx->call('transport.modTransportPackage', 'listPackages', [ + &$this->modx, + 1, + 0, + 0, + '' + ]); + + $providers = []; + /** @var modTransportPackage $package */ + foreach ($result['collection'] as $package) { + $signature = $package->get('signature'); + $sig = xPDOTransport::parseSignature($signature); + + if (!$provider = $package->getOne('Provider')) { + $this->output->writeln("- Package {$sig[0]} is not assigned to a provider, skipping"); + continue; + } + + $providerKey = $provider->get('name'); + if (!isset($providers[$providerKey])) { + $providers[$providerKey] = [ + 'service_url' => $provider->get('service_url') + ]; + if ($provider->get('description')) { + $providers[$providerKey]['description'] = $provider->get('description'); + } + if ($provider->get('username')) { + $providers[$providerKey]['username'] = $provider->get('username'); + } + if ($provider->get('api_key') && !file_exists(GITIFY_WORKING_DIR . '.' . $providerKey . '.key')) { + $key = $provider->get('api_key'); + file_put_contents(GITIFY_WORKING_DIR . '.' . $providerKey . '.key', $key); + $providers[$providerKey]['api_key'] = '.' . $providerKey . '.key'; + } + } + + $providers[$providerKey]['packages'][] = $signature; + } + $data['packages'] = $providers; + + file_put_contents($file, Gitify::toYAML($data)); + $this->output->writeln('Packages updated.'); + } } diff --git a/src/Command/InstallPackageCommand.php b/src/Command/InstallPackageCommand.php index 843d1e2..ddec644 100644 --- a/src/Command/InstallPackageCommand.php +++ b/src/Command/InstallPackageCommand.php @@ -9,6 +9,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ChoiceQuestion; use Symfony\Component\Console\Question\ConfirmationQuestion; +use xPDOTransport; /** * Class InstallPackageCommand @@ -235,6 +236,37 @@ private function install($package, $provider = 0, array $installOptions = []) return false; } + $verbosity = $this->input->getOption('all') ? OutputInterface::VERBOSITY_VERBOSE : OutputInterface::VERBOSITY_NORMAL; + + $installed = $this->modx->getObject('transport.modTransportPackage', [ + 'signature' => $package, + 'provider' => $provider->get('id'), + ]); + if ($installed) { + $this->output->writeln("- $package is already installed, skipping", $verbosity); + return true; + } + + [$name, $version] = xPDOTransport::parseSignature($package); + $c = $this->modx->newQuery('transport.modTransportPackage'); + $c->where([ + 'provider' => $provider->get('id'), + 'signature:LIKE' => $name . '-%', + ]); + $c->sortby('installed', 'DESC'); // @todo is this sufficient to get highest installed version + + /** @var \modTransportPackage $lastVersion */ + $lastVersion = $this->modx->getObject('transport.modTransportPackage', $c); + if ($lastVersion) { + $sig = xPDOTransport::parseSignature($lastVersion->get('signature')); + $installedVersion = $sig[1]; + + if (version_compare($installedVersion, $version, '>=')) { + $this->output->writeln("- $package, found higher version {$installedVersion} already installed", $verbosity); + return true; + } + } + // Download and install the package from the chosen provider $completed = $this->download($package, $provider, $installOptions); if (!$completed) { @@ -482,6 +514,7 @@ private function download($packageName, $provider, $options = []) { // Grab the package object $obj = $response->getObject(); + /** @var \modTransportPackage $package */ if ($package = $this->modx->getObject('transport.modTransportPackage', ['signature' => $obj['signature']])) { // Install the package return $package->install($options);