Add --major-only flag to outdated/show commands to restrict the list to packages with major updates available, fixes #10439 (#10827)
parent
70f2dd6edd
commit
0fd845eeaf
|
@ -497,7 +497,7 @@ php composer.phar show monolog/monolog 1.0.2
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
* **--all :** List all packages available in all your repositories.
|
* **--all:** List all packages available in all your repositories.
|
||||||
* **--installed (-i):** List the packages that are installed (this is enabled by default, and deprecated).
|
* **--installed (-i):** List the packages that are installed (this is enabled by default, and deprecated).
|
||||||
* **--locked:** List the locked packages from composer.lock.
|
* **--locked:** List the locked packages from composer.lock.
|
||||||
* **--platform (-p):** List only platform packages (php & extensions).
|
* **--platform (-p):** List only platform packages (php & extensions).
|
||||||
|
@ -508,8 +508,11 @@ php composer.phar show monolog/monolog 1.0.2
|
||||||
* **--tree (-t):** List your dependencies as a tree. If you pass a package name it will show the dependency tree for that package.
|
* **--tree (-t):** List your dependencies as a tree. If you pass a package name it will show the dependency tree for that package.
|
||||||
* **--latest (-l):** List all installed packages including their latest version.
|
* **--latest (-l):** List all installed packages including their latest version.
|
||||||
* **--outdated (-o):** Implies --latest, but this lists *only* packages that have a newer version available.
|
* **--outdated (-o):** Implies --latest, but this lists *only* packages that have a newer version available.
|
||||||
|
* **--ignore:** Ignore specified package(s). Use it with the --outdated option if you don't want to be informed about new versions of some packages
|
||||||
* **--no-dev:** Filters dev dependencies from the package list.
|
* **--no-dev:** Filters dev dependencies from the package list.
|
||||||
* **--minor-only (-m):** Use with --latest. Only shows packages that have minor SemVer-compatible updates.
|
* **--major-only (-M):** Use with --latest or --outdated. Only shows packages that have major SemVer-compatible updates.
|
||||||
|
* **--minor-only (-m):** Use with --latest or --outdated. Only shows packages that have minor SemVer-compatible updates.
|
||||||
|
* **--patch-only (-p):** Use with --latest or --outdated. Only shows packages that have patch-level SemVer-compatible updates.
|
||||||
* **--direct (-D):** Restricts the list of packages to your direct dependencies.
|
* **--direct (-D):** Restricts the list of packages to your direct dependencies.
|
||||||
* **--strict:** Return a non-zero exit code when there are outdated packages.
|
* **--strict:** Return a non-zero exit code when there are outdated packages.
|
||||||
* **--format (-f):** Lets you pick between text (default) or json output format.
|
* **--format (-f):** Lets you pick between text (default) or json output format.
|
||||||
|
@ -536,10 +539,13 @@ The color coding is as such:
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
* **--all (-a):** Show all packages, not just outdated (alias for `composer show -l`).
|
* **--all (-a):** Show all packages, not just outdated (alias for `composer show --latest`).
|
||||||
* **--direct (-D):** Restricts the list of packages to your direct dependencies.
|
* **--direct (-D):** Restricts the list of packages to your direct dependencies.
|
||||||
* **--strict:** Returns non-zero exit code if any package is outdated.
|
* **--strict:** Returns non-zero exit code if any package is outdated.
|
||||||
|
* **--ignore:** Ignore specified package(s). Use it if you don't want to be informed about new versions of some packages
|
||||||
|
* **--major-only (-M):** Only shows packages that have major SemVer-compatible updates.
|
||||||
* **--minor-only (-m):** Only shows packages that have minor SemVer-compatible updates.
|
* **--minor-only (-m):** Only shows packages that have minor SemVer-compatible updates.
|
||||||
|
* **--patch-only (-p):** Only shows packages that have patch-level SemVer-compatible updates.
|
||||||
* **--format (-f):** Lets you pick between text (default) or json output format.
|
* **--format (-f):** Lets you pick between text (default) or json output format.
|
||||||
* **--no-dev:** Do not show outdated dev dependencies.
|
* **--no-dev:** Do not show outdated dev dependencies.
|
||||||
* **--locked:** Shows updates for packages from the lock file, regardless of what is currently in vendor dir.
|
* **--locked:** Shows updates for packages from the lock file, regardless of what is currently in vendor dir.
|
||||||
|
|
|
@ -40,10 +40,11 @@ class OutdatedCommand extends BaseCommand
|
||||||
new InputOption('locked', null, InputOption::VALUE_NONE, 'Shows updates for packages from the lock file, regardless of what is currently in vendor dir'),
|
new InputOption('locked', null, InputOption::VALUE_NONE, 'Shows updates for packages from the lock file, regardless of what is currently in vendor dir'),
|
||||||
new InputOption('direct', 'D', InputOption::VALUE_NONE, 'Shows only packages that are directly required by the root package'),
|
new InputOption('direct', 'D', InputOption::VALUE_NONE, 'Shows only packages that are directly required by the root package'),
|
||||||
new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code when there are outdated packages'),
|
new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code when there are outdated packages'),
|
||||||
new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates. Use with the --outdated option.'),
|
new InputOption('major-only', 'M', InputOption::VALUE_NONE, 'Show only packages that have major SemVer-compatible updates.'),
|
||||||
new InputOption('patch-only', 'p', InputOption::VALUE_NONE, 'Show only packages that have patch SemVer-compatible updates. Use with the --outdated option.'),
|
new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates.'),
|
||||||
|
new InputOption('patch-only', 'p', InputOption::VALUE_NONE, 'Show only packages that have patch SemVer-compatible updates.'),
|
||||||
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text', ['json', 'text']),
|
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text', ['json', 'text']),
|
||||||
new InputOption('ignore', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore specified package(s). Use it with the --outdated option if you don\'t want to be informed about new versions of some packages.', null, $this->suggestInstalledPackage()),
|
new InputOption('ignore', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore specified package(s). Use it if you don\'t want to be informed about new versions of some packages.', null, $this->suggestInstalledPackage()),
|
||||||
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
|
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
|
||||||
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages). Use with the --outdated option'),
|
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages). Use with the --outdated option'),
|
||||||
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages). Use with the --outdated option'),
|
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages). Use with the --outdated option'),
|
||||||
|
@ -84,6 +85,9 @@ EOT
|
||||||
if ($input->getOption('strict')) {
|
if ($input->getOption('strict')) {
|
||||||
$args['--strict'] = true;
|
$args['--strict'] = true;
|
||||||
}
|
}
|
||||||
|
if ($input->getOption('major-only')) {
|
||||||
|
$args['--major-only'] = true;
|
||||||
|
}
|
||||||
if ($input->getOption('minor-only')) {
|
if ($input->getOption('minor-only')) {
|
||||||
$args['--minor-only'] = true;
|
$args['--minor-only'] = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,8 +91,9 @@ class ShowCommand extends BaseCommand
|
||||||
new InputOption('latest', 'l', InputOption::VALUE_NONE, 'Show the latest version'),
|
new InputOption('latest', 'l', InputOption::VALUE_NONE, 'Show the latest version'),
|
||||||
new InputOption('outdated', 'o', InputOption::VALUE_NONE, 'Show the latest version but only for packages that are outdated'),
|
new InputOption('outdated', 'o', InputOption::VALUE_NONE, 'Show the latest version but only for packages that are outdated'),
|
||||||
new InputOption('ignore', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore specified package(s). Use it with the --outdated option if you don\'t want to be informed about new versions of some packages.', null, $this->suggestInstalledPackage()),
|
new InputOption('ignore', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore specified package(s). Use it with the --outdated option if you don\'t want to be informed about new versions of some packages.', null, $this->suggestInstalledPackage()),
|
||||||
new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates. Use with the --outdated option.'),
|
new InputOption('major-only', 'M', InputOption::VALUE_NONE, 'Show only packages that have major SemVer-compatible updates. Use with the --latest or --outdated option.'),
|
||||||
new InputOption('patch-only', null, InputOption::VALUE_NONE, 'Show only packages that have patch SemVer-compatible updates. Use with the --outdated option.'),
|
new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates. Use with the --latest or --outdated option.'),
|
||||||
|
new InputOption('patch-only', null, InputOption::VALUE_NONE, 'Show only packages that have patch SemVer-compatible updates. Use with the --latest or --outdated option.'),
|
||||||
new InputOption('direct', 'D', InputOption::VALUE_NONE, 'Shows only packages that are directly required by the root package'),
|
new InputOption('direct', 'D', InputOption::VALUE_NONE, 'Shows only packages that are directly required by the root package'),
|
||||||
new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code when there are outdated packages'),
|
new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code when there are outdated packages'),
|
||||||
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text', ['json', 'text']),
|
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text', ['json', 'text']),
|
||||||
|
@ -158,8 +159,8 @@ EOT
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($input->getOption('patch-only') && $input->getOption('minor-only')) {
|
if (count(array_filter([$input->getOption('patch-only'), $input->getOption('minor-only'), $input->getOption('major-only')])) > 1) {
|
||||||
$io->writeError('The --patch-only option is not usable in combination with --minor-only');
|
$io->writeError('Only one of --major-only, --minor-only or --patch-only can be used at once');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -314,7 +315,7 @@ EOT
|
||||||
|
|
||||||
$latestPackage = null;
|
$latestPackage = null;
|
||||||
if ($input->getOption('latest')) {
|
if ($input->getOption('latest')) {
|
||||||
$latestPackage = $this->findLatestPackage($package, $composer, $platformRepo, $input->getOption('minor-only'), $input->getOption('patch-only'), $platformReqFilter);
|
$latestPackage = $this->findLatestPackage($package, $composer, $platformRepo, $input->getOption('major-only'), $input->getOption('minor-only'), $input->getOption('patch-only'), $platformReqFilter);
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
$input->getOption('outdated')
|
$input->getOption('outdated')
|
||||||
|
@ -422,6 +423,7 @@ EOT
|
||||||
|
|
||||||
$showAllTypes = $input->getOption('all');
|
$showAllTypes = $input->getOption('all');
|
||||||
$showLatest = $input->getOption('latest');
|
$showLatest = $input->getOption('latest');
|
||||||
|
$showMajorOnly = $input->getOption('major-only');
|
||||||
$showMinorOnly = $input->getOption('minor-only');
|
$showMinorOnly = $input->getOption('minor-only');
|
||||||
$showPatchOnly = $input->getOption('patch-only');
|
$showPatchOnly = $input->getOption('patch-only');
|
||||||
$ignoredPackages = array_map('strtolower', $input->getOption('ignore'));
|
$ignoredPackages = array_map('strtolower', $input->getOption('ignore'));
|
||||||
|
@ -440,7 +442,7 @@ EOT
|
||||||
if ($showLatest && $showVersion) {
|
if ($showLatest && $showVersion) {
|
||||||
foreach ($packages[$type] as $package) {
|
foreach ($packages[$type] as $package) {
|
||||||
if (is_object($package)) {
|
if (is_object($package)) {
|
||||||
$latestPackage = $this->findLatestPackage($package, $composer, $platformRepo, $showMinorOnly, $showPatchOnly, $platformReqFilter);
|
$latestPackage = $this->findLatestPackage($package, $composer, $platformRepo, $showMajorOnly, $showMinorOnly, $showPatchOnly, $platformReqFilter);
|
||||||
if ($latestPackage === null) {
|
if ($latestPackage === null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -468,6 +470,8 @@ EOT
|
||||||
|
|
||||||
// Determine if Composer is checking outdated dependencies and if current package should trigger non-default exit code
|
// Determine if Composer is checking outdated dependencies and if current package should trigger non-default exit code
|
||||||
$packageIsUpToDate = $latestPackage && $latestPackage->getFullPrettyVersion() === $package->getFullPrettyVersion() && (!$latestPackage instanceof CompletePackageInterface || !$latestPackage->isAbandoned());
|
$packageIsUpToDate = $latestPackage && $latestPackage->getFullPrettyVersion() === $package->getFullPrettyVersion() && (!$latestPackage instanceof CompletePackageInterface || !$latestPackage->isAbandoned());
|
||||||
|
// When using --major-only, and no bigger version than current major is found then it is considered up to date
|
||||||
|
$packageIsUpToDate = $packageIsUpToDate || ($latestPackage === null && $showMajorOnly);
|
||||||
$packageIsIgnored = \in_array($package->getPrettyName(), $ignoredPackages, true);
|
$packageIsIgnored = \in_array($package->getPrettyName(), $ignoredPackages, true);
|
||||||
if ($input->getOption('outdated') && ($packageIsUpToDate || $packageIsIgnored)) {
|
if ($input->getOption('outdated') && ($packageIsUpToDate || $packageIsIgnored)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1354,7 +1358,7 @@ EOT
|
||||||
/**
|
/**
|
||||||
* Given a package, this finds the latest package matching it
|
* Given a package, this finds the latest package matching it
|
||||||
*/
|
*/
|
||||||
private function findLatestPackage(PackageInterface $package, Composer $composer, PlatformRepository $platformRepo, bool $minorOnly, bool $patchOnly, PlatformRequirementFilterInterface $platformReqFilter): ?PackageInterface
|
private function findLatestPackage(PackageInterface $package, Composer $composer, PlatformRepository $platformRepo, bool $majorOnly, bool $minorOnly, bool $patchOnly, PlatformRequirementFilterInterface $platformReqFilter): ?PackageInterface
|
||||||
{
|
{
|
||||||
// find the latest version allowed in this repo set
|
// find the latest version allowed in this repo set
|
||||||
$name = $package->getName();
|
$name = $package->getName();
|
||||||
|
@ -1373,19 +1377,30 @@ EOT
|
||||||
$targetVersion = null;
|
$targetVersion = null;
|
||||||
if (0 === strpos($package->getVersion(), 'dev-')) {
|
if (0 === strpos($package->getVersion(), 'dev-')) {
|
||||||
$targetVersion = $package->getVersion();
|
$targetVersion = $package->getVersion();
|
||||||
|
|
||||||
|
// dev-x branches are considered to be on the latest major version always, do not look up for a new commit as that is deemed a minor upgrade (albeit risky)
|
||||||
|
if ($majorOnly) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($targetVersion === null && $minorOnly) {
|
if ($targetVersion === null) {
|
||||||
$targetVersion = '^' . $package->getVersion();
|
if ($majorOnly && Preg::isMatch('{^(\d+)\.}', $package->getVersion(), $match)) {
|
||||||
|
$targetVersion = '>='.($match[1] + 1).',<9999999-dev';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($targetVersion === null && $patchOnly) {
|
if ($minorOnly) {
|
||||||
|
$targetVersion = '^'.$package->getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($patchOnly) {
|
||||||
$trimmedVersion = Preg::replace('{(\.0)+$}D', '', $package->getVersion());
|
$trimmedVersion = Preg::replace('{(\.0)+$}D', '', $package->getVersion());
|
||||||
$partsNeeded = substr($trimmedVersion, 0, 1) === '0' ? 4 : 3;
|
$partsNeeded = substr($trimmedVersion, 0, 1) === '0' ? 4 : 3;
|
||||||
while (substr_count($trimmedVersion, '.') + 1 < $partsNeeded) {
|
while (substr_count($trimmedVersion, '.') + 1 < $partsNeeded) {
|
||||||
$trimmedVersion .= '.0';
|
$trimmedVersion .= '.0';
|
||||||
}
|
}
|
||||||
$targetVersion = '~' . $trimmedVersion;
|
$targetVersion = '~'.$trimmedVersion;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$candidate = $versionSelector->findBestCandidate($name, $targetVersion, $bestStability, $platformReqFilter);
|
$candidate = $versionSelector->findBestCandidate($name, $targetVersion, $bestStability, $platformReqFilter);
|
||||||
|
|
Loading…
Reference in New Issue