1
0
Fork 0

`--patch-only` option for `show` and `outdated` commands (#10589)

Fixes #10503

Co-authored-by: Svyatoslav <tregubov.s@asteq.ru>
Co-authored-by: Jordi Boggiano <j.boggiano@seld.be>
pull/11010/head
Svyatoslav Tregubov 2022-03-15 17:52:04 +03:00 committed by GitHub
parent f125fc1d0a
commit f863855647
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 3 deletions

View File

@ -39,6 +39,7 @@ class OutdatedCommand extends BaseCommand
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('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates. Use with the --outdated option.'),
new InputOption('patch-only', 'p', InputOption::VALUE_NONE, 'Show only packages that have patch SemVer-compatible updates. Use with the --outdated option.'),
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'), new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or 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.'), 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.'),
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.'),
@ -84,6 +85,9 @@ EOT
if ($input->getOption('minor-only')) { if ($input->getOption('minor-only')) {
$args['--minor-only'] = true; $args['--minor-only'] = true;
} }
if ($input->getOption('patch-only')) {
$args['--patch-only'] = true;
}
if ($input->getOption('locked')) { if ($input->getOption('locked')) {
$args['--locked'] = true; $args['--locked'] = true;
} }

View File

@ -89,6 +89,7 @@ class ShowCommand extends BaseCommand
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.'), 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.'),
new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor 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 --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('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'), new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'),
@ -139,6 +140,12 @@ EOT
return 1; return 1;
} }
if ($input->getOption('patch-only') && $input->getOption('minor-only')) {
$io->writeError('The --patch-only option is not usable in combination with --minor-only');
return 1;
}
if ($input->getOption('tree') && $input->getOption('latest')) { if ($input->getOption('tree') && $input->getOption('latest')) {
$io->writeError('The --tree (-t) option is not usable in combination with --latest (-l)'); $io->writeError('The --tree (-t) option is not usable in combination with --latest (-l)');
@ -289,7 +296,7 @@ EOT
$latestPackage = null; $latestPackage = null;
if ($input->getOption('latest')) { if ($input->getOption('latest')) {
$latestPackage = $this->findLatestPackage($package, $composer, $platformRepo, $input->getOption('minor-only'), $platformReqFilter); $latestPackage = $this->findLatestPackage($package, $composer, $platformRepo, $input->getOption('minor-only'), $input->getOption('patch-only'), $platformReqFilter);
} }
if ( if (
$input->getOption('outdated') $input->getOption('outdated')
@ -398,6 +405,7 @@ EOT
$showAllTypes = $input->getOption('all'); $showAllTypes = $input->getOption('all');
$showLatest = $input->getOption('latest'); $showLatest = $input->getOption('latest');
$showMinorOnly = $input->getOption('minor-only'); $showMinorOnly = $input->getOption('minor-only');
$showPatchOnly = $input->getOption('patch-only');
$ignoredPackages = array_map('strtolower', $input->getOption('ignore')); $ignoredPackages = array_map('strtolower', $input->getOption('ignore'));
$indent = $showAllTypes ? ' ' : ''; $indent = $showAllTypes ? ' ' : '';
/** @var PackageInterface[] $latestPackages */ /** @var PackageInterface[] $latestPackages */
@ -414,7 +422,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, $platformReqFilter); $latestPackage = $this->findLatestPackage($package, $composer, $platformRepo, $showMinorOnly, $showPatchOnly, $platformReqFilter);
if ($latestPackage === null) { if ($latestPackage === null) {
continue; continue;
} }
@ -1288,7 +1296,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, PlatformRequirementFilterInterface $platformReqFilter): ?PackageInterface private function findLatestPackage(PackageInterface $package, Composer $composer, PlatformRepository $platformRepo, 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();
@ -1313,6 +1321,15 @@ EOT
$targetVersion = '^' . $package->getVersion(); $targetVersion = '^' . $package->getVersion();
} }
if ($targetVersion === null && $patchOnly) {
$trimmedVersion = Preg::replace('{(\.0)+$}D', '', $package->getVersion());
$partsNeeded = substr($trimmedVersion, 0, 1) === '0' ? 4 : 3;
while (substr_count($trimmedVersion, '.') + 1 < $partsNeeded) {
$trimmedVersion .= '.0';
}
$targetVersion = '~' . $trimmedVersion;
}
$candidate = $versionSelector->findBestCandidate($name, $targetVersion, $bestStability, $platformReqFilter); $candidate = $versionSelector->findBestCandidate($name, $targetVersion, $bestStability, $platformReqFilter);
while ($candidate instanceof AliasPackage) { while ($candidate instanceof AliasPackage) {
$candidate = $candidate->getAliasOf(); $candidate = $candidate->getAliasOf();