diff --git a/system/src/Grav/Common/GPM/GPM.php b/system/src/Grav/Common/GPM/GPM.php index 9fce56e5f..997ca4a90 100644 --- a/system/src/Grav/Common/GPM/GPM.php +++ b/system/src/Grav/Common/GPM/GPM.php @@ -208,13 +208,13 @@ class GPM extends Iterator $repository = $this->repository['plugins']; if (isset($repository[$package_name])) { - return $repository[$package_name]->version; + return $repository[$package_name]->available; } //Not a plugin, it's a theme? $repository = $this->repository['themes']; if (isset($repository[$package_name])) { - return $repository[$package_name]->version; + return $repository[$package_name]->available; } return null; @@ -483,6 +483,41 @@ class GPM extends Iterator } } + /** + * Check the package identified by $slug can be updated to the version passed as argument. + * Thrown an exception if it cannot be updated because another package installed requires it to be at an older version. + * + * @param string $slug + * @param string $versionWithOperator The new version, with operator e.g. '~2.0' or '>=2.0' + * + * @return bool + * @throws \Exception + */ + public function checkNoOtherPackageNeedsThisDependencyInALowerVersion($slug, $versionWithOperator) { + // check if any of the currently installed package need this in a lower version than the one we need. In case, abort and tell which package + $dependent_packages = $this->getPackagesThatDependOnPackage($slug); + $version = $this->calculateVersionNumberFromDependencyVersion($versionWithOperator); + + if (count($dependent_packages)) { + foreach($dependent_packages as $dependent_package) { + $otherDependencyVersionWithOperator = $this->getVersionOfDependencyRequiredByPackage($dependent_package, $slug); + $otherDependencyVersion= $this->calculateVersionNumberFromDependencyVersion($otherDependencyVersionWithOperator); + + // check version is compatible with the one needed by the current package + if ($this->versionFormatIsNextSignificantRelease($otherDependencyVersionWithOperator)) { + $compatible = $this->checkNextSignificantReleasesAreCompatible($version, + $otherDependencyVersion); + if (!$compatible) { + throw new \Exception("Package $slug is required in an older version by package $dependent_package. This package needs a newer version, and because of this it cannot be installed. The $dependent_package package must be updated to use a newer release of $slug.", + 2); + } + } + } + } + + return true; + } + /** * Fetch the dependencies, check the installed packages and return an array with * the list of packages with associated an information on what to do: install, update or ignore. @@ -519,28 +554,7 @@ class GPM extends Iterator 2); } } else { - - // check if any of the currently installed package need this in a lower version than the one we need. In case, abort and tell which package - $dependent_packages = $this->getPackagesThatDependOnPackage($dependency_slug); - - if (count($dependent_packages)) { - foreach($dependent_packages as $dependent_package) { - - $otherDependencyVersionWithOperator = $this->getVersionOfDependencyRequiredByPackage($dependent_package, $dependency_slug); - $otherDependencyVersion= $this->calculateVersionNumberFromDependencyVersion($otherDependencyVersionWithOperator); - - // if requirement is next significant release, check it's compatible with the one needed by the current package - if ($this->versionFormatIsNextSignificantRelease($dependencyVersionWithOperator)) { - $compatible = $this->checkNextSignificantReleasesAreCompatible($dependencyVersion, - $otherDependencyVersion); - - if (!$compatible) { - throw new \Exception("Dependency $dependency_slug is required in an older version by package $dependent_package. This package needs a newer version, and because of this it cannot be installed. The $dependent_package package must be updated to use a newer release of $dependency_slug.", - 2); - } - } - } - } + $this->checkNoOtherPackageNeedsThisDependencyInALowerVersion($dependency_slug, $dependencyVersionWithOperator); } } @@ -700,25 +714,29 @@ class GPM extends Iterator * Examples: * $versionInformation == '~2.0' => returns '2.0' * $versionInformation == '>=2.0.2' => returns '2.0.2' + * $versionInformation == '2.0.2' => returns '2.0.2' * $versionInformation == '*' => returns null * $versionInformation == '' => returns null * - * @param $versionInformation + * @param string $version * * @return null|string */ - public function calculateVersionNumberFromDependencyVersion($versionInformation) + public function calculateVersionNumberFromDependencyVersion($version) { - if ($this->versionFormatIsNextSignificantRelease($versionInformation)) { - return substr($versionInformation, 1); - } elseif ($this->versionFormatIsEqualOrHigher($versionInformation)) { - return substr($versionInformation, 2); + if ($version == '*') { + return null; + } elseif ($version == '') { + return null; + } elseif ($this->versionFormatIsNextSignificantRelease($version)) { + return substr($version, 1); + } elseif ($this->versionFormatIsEqualOrHigher($version)) { + return substr($version, 2); + } else { + return $version; } - - return null; } - /** * Check if the passed version information contains next significant release (tilde) operator * diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index 159d73d8b..b5c6c31f9 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -189,6 +189,14 @@ class InstallCommand extends ConsoleCommand $this->processPackage($package, true); } else { if (Installer::lastErrorCode() == Installer::EXISTS) { + + try { + $this->gpm->checkNoOtherPackageNeedsThisDependencyInALowerVersion($package->slug, $package->available); + } catch (\Exception $e) { + $this->output->writeln("" . $e->getMessage() . ""); + return false; + } + $helper = $this->getHelper('question'); $question = new ConfirmationQuestion("The package $packageName is already installed, overwrite? [y|N] ", false); diff --git a/system/src/Grav/Console/Gpm/UpdateCommand.php b/system/src/Grav/Console/Gpm/UpdateCommand.php index f39d5f77e..fa869daed 100644 --- a/system/src/Grav/Console/Gpm/UpdateCommand.php +++ b/system/src/Grav/Console/Gpm/UpdateCommand.php @@ -122,7 +122,7 @@ class UpdateCommand extends ConsoleCommand } $this->output->writeln( - // index + // index str_pad($index++ + 1, 2, '0', STR_PAD_LEFT) . ". " . // name "" . str_pad($package->name, 15) . " " .