From e053dc42a5389d3ca171d4d11ab0598a8cded51c Mon Sep 17 00:00:00 2001 From: Julio cavallari Date: Wed, 12 Mar 2025 17:52:24 -0300 Subject: [PATCH 1/3] feat(presets)!: It makes possible to use several presets at the same time --- README.md | 6 +- peck.json | 5 +- src/Config.php | 20 +++--- src/Support/PresetProvider.php | 31 +++++++--- .../Console/OutputTest/it_may_fail.snap | 2 +- tests/Fixtures/invalid-presets-peck.json | 11 ++++ tests/Unit/Checkers/FileSystemCheckerTest.php | 62 ++++--------------- tests/Unit/ConfigTest.php | 8 +++ tests/Unit/Support/PresetProviderTest.php | 19 +++--- 9 files changed, 83 insertions(+), 81 deletions(-) create mode 100644 tests/Fixtures/invalid-presets-peck.json diff --git a/README.md b/README.md index ad829a87..20764dc3 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Here's an example configuration: ```json { - "preset": "laravel", + "preset": ["laravel"], "ignore": { "words": [ "config", @@ -105,7 +105,9 @@ You can also specify the path to the configuration file using the `--config` opt In order to make it easier to get started with Peck, we've included a few presets that you can use to ignore common words in your project. The following presets are available: -- `laravel` +- `laravel` - Ignores common Laravel words such as `inertia`, `jetstream`, etc. +- `iso3166` - Ignores all ISO 3166 country codes in alpha-2 and alpha-3 format (e.g., `US`, `USA`, `GB`, `GBR`, etc.) +- `iso4217` - Ignores all ISO 4217 currency codes (e.g., `USD`, `EUR`, `GBP`, etc.) ## Command Options diff --git a/peck.json b/peck.json index eaa17abf..6752724a 100644 --- a/peck.json +++ b/peck.json @@ -1,5 +1,8 @@ { - "preset": "base", + "presets": [ + "iso3166", + "iso4217" + ], "ignore": { "words": [ "php" diff --git a/src/Config.php b/src/Config.php index dabbd366..cf058ae9 100644 --- a/src/Config.php +++ b/src/Config.php @@ -7,6 +7,7 @@ use Closure; use Peck\Support\PresetProvider; use Peck\Support\ProjectPath; +use RuntimeException; final class Config { @@ -30,11 +31,12 @@ final class Config * * @param array $whitelistedWords * @param array $whitelistedPaths + * @param array $presets */ public function __construct( public array $whitelistedWords = [], public array $whitelistedPaths = [], - public ?string $preset = null, + public array $presets = [], ) { $this->whitelistedWords = array_map(strtolower(...), $whitelistedWords); } @@ -86,7 +88,7 @@ public static function instance(): self /** * @var array{ - * preset?: string, + * presets?: string[], * ignore?: array{ * words?: array, * paths?: array @@ -95,10 +97,14 @@ public static function instance(): self */ $jsonAsArray = json_decode($contents, true) ?: []; + if (! is_array($jsonAsArray['presets'] ?? [])) { + throw new RuntimeException('The presets must be an array with all the presets you want to use.'); + } + return self::$instance = new self( $jsonAsArray['ignore']['words'] ?? [], $jsonAsArray['ignore']['paths'] ?? [], - $jsonAsArray['preset'] ?? null, + $jsonAsArray['presets'] ?? [], ); } @@ -116,10 +122,10 @@ public static function init(): bool return (bool) file_put_contents($filePath, json_encode([ ...match (true) { class_exists('\Illuminate\Support\Str') => [ - 'preset' => 'laravel', + 'presets' => ['laravel'], ], default => [ - 'preset' => 'base', + 'presets' => ['base'], ], }, 'ignore' => [ @@ -150,7 +156,7 @@ public function isWordIgnored(string $word): bool { return in_array(strtolower($word), [ ...$this->whitelistedWords, - ...array_map(strtolower(...), PresetProvider::whitelistedWords($this->preset)), + ...array_map(strtolower(...), PresetProvider::whitelistedWords($this->presets)), ]); } @@ -162,7 +168,7 @@ private function persist(): void $filePath = ProjectPath::get().'/'.self::JSON_CONFIGURATION_NAME; file_put_contents($filePath, json_encode([ - ...$this->preset !== null ? ['preset' => $this->preset] : [], + 'presets' => $this->presets, 'ignore' => [ 'words' => $this->whitelistedWords, 'paths' => $this->whitelistedPaths, diff --git a/src/Support/PresetProvider.php b/src/Support/PresetProvider.php index a29ed3ac..e33f36e0 100644 --- a/src/Support/PresetProvider.php +++ b/src/Support/PresetProvider.php @@ -18,20 +18,27 @@ /** * Returns the whitelisted words for the given preset. * + * @param array|null $presets * @return array */ - public static function whitelistedWords(?string $preset): array + public static function whitelistedWords(?array $presets = []): array { - if ($preset === null || ! self::stubExists($preset)) { - return []; - } - - return [ + /** @var array */ + $words = [ ...self::getWordsFromStub('base'), - ...self::getWordsFromStub('iso4217'), - ...self::getWordsFromStub('iso3166'), - ...self::getWordsFromStub($preset), ]; + + array_map( + static function (string $preset) use (&$words): void { + $words = [ + ...$words, + ...self::getWordsFromStub($preset), + ]; + }, + $presets ?? [], + ); + + return $words; } /** @@ -39,8 +46,12 @@ public static function whitelistedWords(?string $preset): array * * @return array */ - private static function getWordsFromStub(string $preset): array + public static function getWordsFromStub(string $preset): array { + if (! self::stubExists($preset)) { + return []; + } + $path = sprintf('%s/%s.stub', self::PRESET_STUBS_DIRECTORY, $preset); return array_values(array_filter(array_map('trim', explode("\n", (string) file_get_contents($path))))); diff --git a/tests/.pest/snapshots/Console/OutputTest/it_may_fail.snap b/tests/.pest/snapshots/Console/OutputTest/it_may_fail.snap index c8d0969e..033d4fbb 100644 --- a/tests/.pest/snapshots/Console/OutputTest/it_may_fail.snap +++ b/tests/.pest/snapshots/Console/OutputTest/it_may_fail.snap @@ -1,4 +1,4 @@ - .............⨯⨯⨯.⨯....⨯⨯.⨯⨯⨯⨯⨯⨯....⨯⨯ + .............⨯⨯⨯.⨯.....⨯⨯.⨯⨯⨯⨯⨯⨯....⨯⨯ Misspelling ./tests/Fixtures/FolderWithTypoos: 'typoos' ./tests/Fixtures/FolderWithTypoos diff --git a/tests/Fixtures/invalid-presets-peck.json b/tests/Fixtures/invalid-presets-peck.json new file mode 100644 index 00000000..31729376 --- /dev/null +++ b/tests/Fixtures/invalid-presets-peck.json @@ -0,0 +1,11 @@ +{ + "presets": "base", + "ignore": { + "words": [ + "php" + ], + "paths": [ + "tests" + ] + } +} diff --git a/tests/Unit/Checkers/FileSystemCheckerTest.php b/tests/Unit/Checkers/FileSystemCheckerTest.php index 5c9a2b7f..def20816 100644 --- a/tests/Unit/Checkers/FileSystemCheckerTest.php +++ b/tests/Unit/Checkers/FileSystemCheckerTest.php @@ -89,67 +89,27 @@ 'onFailure' => fn (): null => null, ]); - expect($issues)->toHaveCount(8) - ->and($issues[0]->file)->toEndWith('tests/Fixtures/EnumsToTest') + expect($issues)->toHaveCount(3) + ->and($issues[0]->file)->toEndWith('tests/Fixtures/FolderWithTypoos') ->and($issues[0]->line)->toBe(0) - ->and($issues[0]->misspelling->word)->toBe('enums') + ->and($issues[0]->misspelling->word)->toBe('typoos') ->and($issues[0]->misspelling->suggestions)->toBe([ - 'enemas', - 'animus', - 'emus', - 'ems', - ])->and($issues[1]->file)->toEndWith('tests/Fixtures/EnumsToTest/BackendEnumWithTypoErrors.php') - ->and($issues[1]->line)->toBe(0) - ->and($issues[1]->misspelling->word)->toBe('backend') - ->and($issues[1]->misspelling->suggestions)->toBe([ - 'backed', - 'bookend', - 'blackened', - 'beckoned', - ])->and($issues[2]->file)->toEndWith('tests/Fixtures/EnumsToTest/BackendEnumWithTypoErrors.php') - ->and($issues[2]->line)->toBe(0) - ->and($issues[2]->misspelling->word)->toBe('enum') - ->and($issues[2]->misspelling->suggestions)->toBe([ - 'enema', - 'enemy', - 'emu', - 'anime', - ])->and($issues[3]->file)->toEndWith('tests/Fixtures/EnumsToTest/FolderThatShouldBeIgnored/EnumWithTypoErrors.php') - ->and($issues[3]->line)->toBe(0) - ->and($issues[3]->misspelling->word)->toBe('enum') - ->and($issues[3]->misspelling->suggestions)->toBe([ - 'enema', - 'enemy', - 'emu', - 'anime', - ])->and($issues[4]->file)->toEndWith('tests/Fixtures/EnumsToTest/UnitEnumWithTypoErrors.php') - ->and($issues[4]->line)->toBe(0) - ->and($issues[4]->misspelling->word)->toBe('enum') - ->and($issues[4]->misspelling->suggestions)->toBe([ - 'enema', - 'enemy', - 'emu', - 'anime', - ])->and($issues[5]->file)->toEndWith('tests/Fixtures/FolderWithTypoos') - ->and($issues[5]->line)->toBe(0) - ->and($issues[5]->misspelling->word)->toBe('typoos') - ->and($issues[5]->misspelling->suggestions)->toBe([ 'typos', 'types', 'tops', 'poos', - ])->and($issues[6]->file)->toEndWith('tests/Fixtures/FolderWithTypoos/FileWithTppyo.php') - ->and($issues[6]->line)->toBe(0) - ->and($issues[6]->misspelling->word)->toBe('tppyo') - ->and($issues[6]->misspelling->suggestions)->toBe([ + ])->and($issues[1]->file)->toEndWith('tests/Fixtures/FolderWithTypoos/FileWithTppyo.php') + ->and($issues[1]->line)->toBe(0) + ->and($issues[1]->misspelling->word)->toBe('tppyo') + ->and($issues[1]->misspelling->suggestions)->toBe([ 'typo', 'Tokyo', 'typos', 'topi', - ])->and($issues[7]->file)->toEndWith('tests/Fixtures/FolderWithTypoos/FolderThatShouldBeIgnored/FileThatShoudBeIgnoredBecauseItsInsideWhitelistedFolder.php') - ->and($issues[7]->line)->toBe(0) - ->and($issues[7]->misspelling->word)->toBe('shoud') - ->and($issues[7]->misspelling->suggestions)->toBe([ + ])->and($issues[2]->file)->toEndWith('tests/Fixtures/FolderWithTypoos/FolderThatShouldBeIgnored/FileThatShoudBeIgnoredBecauseItsInsideWhitelistedFolder.php') + ->and($issues[2]->line)->toBe(0) + ->and($issues[2]->misspelling->word)->toBe('shoud') + ->and($issues[2]->misspelling->suggestions)->toBe([ 'should', 'shroud', 'shod', diff --git a/tests/Unit/ConfigTest.php b/tests/Unit/ConfigTest.php index 780e7217..5673bbd2 100644 --- a/tests/Unit/ConfigTest.php +++ b/tests/Unit/ConfigTest.php @@ -59,3 +59,11 @@ 'tests', ]); }); + +it('should throw an runtime exception if the presets are not an array', function (): void { + Config::resolveConfigFilePathUsing( + fn (): string => 'tests/Fixtures/invalid-presets-peck.json', + ); + + Config::instance(); +})->throws(RuntimeException::class, 'The presets must be an array with all the presets you want to use.'); diff --git a/tests/Unit/Support/PresetProviderTest.php b/tests/Unit/Support/PresetProviderTest.php index bb1d2df4..d3152c95 100644 --- a/tests/Unit/Support/PresetProviderTest.php +++ b/tests/Unit/Support/PresetProviderTest.php @@ -4,18 +4,19 @@ use Peck\Support\PresetProvider; -it('returns an empty array when the preset is null', function (): void { - expect(PresetProvider::whitelistedWords(null))->toBe([]); +it('returns only words from base preset when presets are not given', function (): void { + expect(PresetProvider::whitelistedWords())->toBe(PresetProvider::getWordsFromStub('base')); }); -it('returns an empty array when the preset is invalid', function (): void { - expect(PresetProvider::whitelistedWords('invalid'))->toBe([]); +it('returns only words from base preset when all given presets are invalids', function (): void { + expect(PresetProvider::whitelistedWords(['invalid-one', 'invalid-two']))->toBe(PresetProvider::getWordsFromStub('base')); }); -it('returns the whitelisted words for the given preset', function (): void { - expect(PresetProvider::whitelistedWords('laravel'))->toContain( - 'http', - 'laravel', - 'fillable', +it('returns the whitelisted words for the given and base presets', function (): void { + expect(PresetProvider::whitelistedWords(['laravel', 'iso3166', 'iso4217']))->toContain( + 'apa', + 'USD', + 'USA', + 'https' ); }); From 527fd1f70c63386e93edb736a9500395da9344a8 Mon Sep 17 00:00:00 2001 From: Julio Cavallari <53496995+julio-cavallari@users.noreply.github.com> Date: Fri, 21 Mar 2025 14:43:59 -0300 Subject: [PATCH 2/3] Update README.md Co-authored-by: Constantin Ross --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 20764dc3..c93b1aa1 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Here's an example configuration: ```json { - "preset": ["laravel"], + "presets": ["laravel"], "ignore": { "words": [ "config", From a7e7ce7acf04f56c245ae13d35758fce1b915264 Mon Sep 17 00:00:00 2001 From: Constantin Ross Date: Sat, 24 May 2025 10:38:20 +0200 Subject: [PATCH 3/3] Update tests/Unit/ConfigTest.php Co-authored-by: Bolaji Ajani --- tests/Unit/ConfigTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/ConfigTest.php b/tests/Unit/ConfigTest.php index 5673bbd2..52c792c3 100644 --- a/tests/Unit/ConfigTest.php +++ b/tests/Unit/ConfigTest.php @@ -60,7 +60,7 @@ ]); }); -it('should throw an runtime exception if the presets are not an array', function (): void { +it('throws a runtime exception if the presets value is not an array', function (): void { Config::resolveConfigFilePathUsing( fn (): string => 'tests/Fixtures/invalid-presets-peck.json', );