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);