fix:repo cleanup

This commit is contained in:
2025-11-08 20:09:07 +00:00
parent f1da93791d
commit dedcc73567
1204 changed files with 121800 additions and 16971 deletions
+21
View File
@@ -2,6 +2,24 @@
All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
## [4.2.0] - 2025-09-14
### Changed
* [#3](https://github.com/sebastianbergmann/cli-parser/pull/3): Print most similar options when reporting unknown options
## [4.1.0] - 2025-09-13
### Changed
* [#2](https://github.com/sebastianbergmann/cli-parser/pull/2): Print similar options when reporting ambiguous options
## [4.0.0] - 2025-02-07
### Removed
* This component is no longer supported on PHP 8.2
## [3.0.2] - 2024-07-03
### Changed
@@ -42,6 +60,9 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
* Initial release
[4.2.0]: https://github.com/sebastianbergmann/cli-parser/compare/4.1.0...4.2.0
[4.1.0]: https://github.com/sebastianbergmann/cli-parser/compare/4.0.0...4.1.0
[4.0.0]: https://github.com/sebastianbergmann/cli-parser/compare/3.0...4.0.0
[3.0.2]: https://github.com/sebastianbergmann/cli-parser/compare/3.0.1...3.0.2
[3.0.1]: https://github.com/sebastianbergmann/cli-parser/compare/3.0.0...3.0.1
[3.0.0]: https://github.com/sebastianbergmann/cli-parser/compare/2.0...3.0.0
+1 -1
View File
@@ -1,6 +1,6 @@
BSD 3-Clause License
Copyright (c) 2020-2024, Sebastian Bergmann
Copyright (c) 2020-2025, Sebastian Bergmann
All rights reserved.
Redistribution and use in source and binary forms, with or without
+1 -1
View File
@@ -1,4 +1,4 @@
[![Latest Stable Version](https://poser.pugx.org/sebastian/cli-parser/v/stable.png)](https://packagist.org/packages/sebastian/cli-parser)
[![Latest Stable Version](https://poser.pugx.org/sebastian/cli-parser/v)](https://packagist.org/packages/sebastian/cli-parser)
[![CI Status](https://github.com/sebastianbergmann/cli-parser/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/cli-parser/actions)
[![codecov](https://codecov.io/gh/sebastianbergmann/cli-parser/branch/main/graph/badge.svg)](https://codecov.io/gh/sebastianbergmann/cli-parser)
+4 -4
View File
@@ -17,14 +17,14 @@
},
"prefer-stable": true,
"require": {
"php": ">=8.2"
"php": ">=8.3"
},
"require-dev": {
"phpunit/phpunit": "^11.0"
"phpunit/phpunit": "^12.0"
},
"config": {
"platform": {
"php": "8.2.0"
"php": "8.3.0"
},
"optimize-autoloader": true,
"sort-packages": true
@@ -36,7 +36,7 @@
},
"extra": {
"branch-alias": {
"dev-main": "3.0-dev"
"dev-main": "4.2-dev"
}
}
}
+56 -15
View File
@@ -19,17 +19,19 @@ use function current;
use function explode;
use function is_array;
use function is_int;
use function is_string;
use function key;
use function levenshtein;
use function next;
use function preg_replace;
use function reset;
use function rtrim;
use function sort;
use function str_ends_with;
use function str_starts_with;
use function strlen;
use function strstr;
use function substr;
use function usort;
final class Parser
{
@@ -42,11 +44,11 @@ final class Parser
* @throws RequiredOptionArgumentMissingException
* @throws UnknownOptionException
*
* @return array{0: list<array{0: non-empty-string, 1: ?non-empty-string}>, 1: list<non-empty-string>}
* @return array{0: list<array{0: string, 1: ?string}>, 1: list<string>}
*/
public function parse(array $argv, string $shortOptions, ?array $longOptions = null): array
{
if (empty($argv)) {
if ($argv === []) {
return [[], []];
}
@@ -111,8 +113,8 @@ final class Parser
}
/**
* @param list<array{0: non-empty-string, 1: ?non-empty-string}> $options
* @param list<string> $argv
* @param list<array{0: string, 1: ?string}> $options
* @param list<string> $argv
*
* @throws RequiredOptionArgumentMissingException
*/
@@ -125,7 +127,7 @@ final class Parser
$optionArgument = null;
if ($argument[$i] === ':' || ($spec = strstr($shortOptions, $option)) === false) {
throw new UnknownOptionException('-' . $option);
throw new UnknownOptionException('-' . $option, []);
}
if (strlen($spec) > 1 && $spec[1] === ':') {
@@ -142,8 +144,6 @@ final class Parser
throw new RequiredOptionArgumentMissingException('-' . $option);
}
assert(is_string($optionArgument));
next($argv);
}
}
@@ -153,9 +153,9 @@ final class Parser
}
/**
* @param list<string> $longOptions
* @param list<array{0: non-empty-string, 1: ?non-empty-string}> $options
* @param list<string> $argv
* @param list<string> $longOptions
* @param list<array{0: string, 1: ?string}> $options
* @param list<string> $argv
*
* @throws AmbiguousOptionException
* @throws OptionDoesNotAllowArgumentException
@@ -170,12 +170,19 @@ final class Parser
$optionArgument = null;
if (count($list) > 1) {
/** @phpstan-ignore offsetAccess.notFound */
$optionArgument = $list[1];
}
$optionLength = strlen($option);
$similarOptions = [];
foreach ($longOptions as $i => $longOption) {
$similarOptions[] = [
levenshtein($longOption, $option),
'--' . rtrim($longOption, '='),
];
$opt_start = substr($longOption, 0, $optionLength);
if ($opt_start !== $option) {
@@ -184,12 +191,25 @@ final class Parser
$opt_rest = substr($longOption, $optionLength);
if ($opt_rest !== '' && $i + 1 < $count && $option[0] !== '=' && str_starts_with($longOptions[$i + 1], $option)) {
throw new AmbiguousOptionException('--' . $option);
if ($opt_rest !== '' &&
$i + 1 < $count &&
$option[0] !== '=' &&
/** @phpstan-ignore offsetAccess.notFound */
str_starts_with($longOptions[$i + 1], $option)
) {
$candidates = [];
foreach ($longOptions as $aLongOption) {
if (str_starts_with($aLongOption, $option)) {
$candidates[] = '--' . rtrim($aLongOption, '=');
}
}
throw new AmbiguousOptionException('--' . $option, $candidates);
}
if (str_ends_with($longOption, '=')) {
if (!str_ends_with($longOption, '==') && !strlen((string) $optionArgument)) {
if (!str_ends_with($longOption, '==') && (string) $optionArgument === '') {
if (false === $optionArgument = current($argv)) {
throw new RequiredOptionArgumentMissingException('--' . $option);
}
@@ -206,6 +226,27 @@ final class Parser
return;
}
throw new UnknownOptionException('--' . $option);
throw new UnknownOptionException('--' . $option, $this->formatSimilarOptions($similarOptions));
}
/**
* @param list<array{int, string}> $similarOptions
*
* @return array<string>
*/
private function formatSimilarOptions(array $similarOptions): array
{
usort($similarOptions, static function (array $a, array $b)
{
return $a[0] <=> $b[0];
});
$similarFormatted = [];
foreach (array_slice($similarOptions, 0, 5) as [$distance, $label]) {
$similarFormatted[] = $label;
}
return $similarFormatted;
}
}
@@ -9,17 +9,22 @@
*/
namespace SebastianBergmann\CliParser;
use function implode;
use function sprintf;
use RuntimeException;
final class AmbiguousOptionException extends RuntimeException implements Exception
{
public function __construct(string $option)
/**
* @param array<string> $candiates
*/
public function __construct(string $option, array $candiates)
{
parent::__construct(
sprintf(
'Option "%s" is ambiguous',
'Option "%s" is ambiguous. Similar options are: %s',
$option,
implode(', ', $candiates),
),
);
}
@@ -9,18 +9,30 @@
*/
namespace SebastianBergmann\CliParser;
use function implode;
use function sprintf;
use RuntimeException;
final class UnknownOptionException extends RuntimeException implements Exception
{
public function __construct(string $option)
/**
* @param array<string> $similarOptions
*/
public function __construct(string $option, array $similarOptions)
{
parent::__construct(
sprintf(
'Unknown option "%s"',
$option,
),
$message = sprintf(
'Unknown option "%s"',
$option,
);
if ($similarOptions !== []) {
$message = sprintf(
'Unknown option "%s". Most similar options are %s',
$option,
implode(', ', $similarOptions),
);
}
parent::__construct($message);
}
}