From 82f3dd8a1c0da05b60f6907765187007ef03531a Mon Sep 17 00:00:00 2001 From: Imani Manyara Date: Thu, 5 Nov 2026 02:20:50 -0500 Subject: [PATCH 1/2] Depend on ichava/core alone The provider extends core's IconPackServiceProvider and names its constants and component classes, so src/ imports no laranail type and composer.json requires php and ichava/core only. The type is ichava-icon-set, which core's discovery reads. CoreOnlyDependencyTest guards all three. --- composer.json | 6 +- src/Providers/IconsServiceProvider.php | 27 ++------- tests/Unit/CoreOnlyDependencyTest.php | 77 ++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 25 deletions(-) create mode 100644 tests/Unit/CoreOnlyDependencyTest.php diff --git a/composer.json b/composer.json index 113e4ea..1946ca0 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "ichava/icon-sets-ionicons", "description": "1,357 Ionicons SVGs (515 filled including 94 logos, 421 outline, 421 sharp) from ionicons 8.1.0, for Laravel 13 on the Ichava icon ecosystem.", - "type": "library", + "type": "ichava-icon-set", "keywords": [ "laravel", "blade", @@ -23,9 +23,7 @@ ], "require": { "php": "^8.4.1 || ^8.5", - "illuminate/support": "^13.0", - "ichava/core": "^0.1", - "laranail/package-tools": "^0.1.0" + "ichava/core": "^0.1" }, "repositories": [ { diff --git a/src/Providers/IconsServiceProvider.php b/src/Providers/IconsServiceProvider.php index 07b5fa9..6e25ab3 100644 --- a/src/Providers/IconsServiceProvider.php +++ b/src/Providers/IconsServiceProvider.php @@ -4,37 +4,22 @@ namespace Simtabi\Laranail\Ichava\IconSetsIonicons\Providers; -use Simtabi\Laranail\Package\Tools\Package; -use Simtabi\Laranail\Ichava\Services\IconRegistry; -use Simtabi\Laranail\Ichava\Support\ServiceProvider; -use Simtabi\Laranail\Package\Tools\Exceptions\InvalidPath; -use Simtabi\Laranail\Package\Tools\Exceptions\InvalidPackage; +use Simtabi\Laranail\Ichava\Support\IconPackServiceProvider; use Simtabi\Laranail\Ichava\IconSetsIonicons\Constants\IconsConstants; use Simtabi\Laranail\Ichava\IconSetsIonicons\View\Components\IconComponent; /** * Registers the Ionicons set with the Ichava registry on boot. */ -class IconsServiceProvider extends ServiceProvider +class IconsServiceProvider extends IconPackServiceProvider { - /** - * @throws InvalidPath - * @throws InvalidPackage - */ - public function configurePackage(Package $package): void + protected function constantsClass(): string { - $package - ->setName(IconsConstants::getVendorPackage()) - ->setPathFrom(source: $this, levelsUp: 2); + return IconsConstants::class; } - public function bootingPackage(): void + protected function componentClass(): string { - $this->loadBladeComponent(componentClass: IconComponent::class, packageName: 'icon-sets-ionicons'); - - $this->app->make(IconRegistry::class)->fromDirectory( - $this->package->basePath('resources/assets/svg'), - self::class, - ); + return IconComponent::class; } } diff --git a/tests/Unit/CoreOnlyDependencyTest.php b/tests/Unit/CoreOnlyDependencyTest.php new file mode 100644 index 0000000..21a6d36 --- /dev/null +++ b/tests/Unit/CoreOnlyDependencyTest.php @@ -0,0 +1,77 @@ + */ +function coreOnlyComposerJson(): array +{ + $composer = json_decode((string) file_get_contents(dirname(__DIR__, 2) . '/composer.json'), true, flags: JSON_THROW_ON_ERROR); + + return is_array($composer) ? $composer : []; +} + +it('requires php and ichava/core, and nothing else', function (): void { + $require = array_keys(coreOnlyComposerJson()['require'] ?? []); + sort($require); + + expect($require)->toBe(['ichava/core', 'php']); +}); + +it('declares the composer type core discovers packs by', function (): void { + expect(coreOnlyComposerJson()['type'] ?? null)->toBe('ichava-icon-set'); +}); + +it('imports no laranail namespace but ichava/core from src/', function (): void { + $inspected = 0; + $offenders = []; + + $files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator(dirname(__DIR__, 2) . '/src', FilesystemIterator::SKIP_DOTS), + ); + + foreach ($files as $file) { + if (! $file instanceof SplFileInfo || ! $file->isFile() || $file->getExtension() !== 'php') { + continue; + } + + $inspected++; + $source = (string) file_get_contents($file->getPathname()); + + // Every spelling: a `use` line, a fully qualified name, or a string with + // escaped backslashes. + preg_match_all('/Simtabi\\\\+Laranail\\\\+(\w+)(?:\\\\+(\w+))?/', $source, $matches, PREG_SET_ORDER); + + foreach ($matches as $match) { + if ($match[1] !== 'Ichava' || ($match[2] ?? '') === 'IconBrowser') { + $offenders[] = $file->getFilename() . ': ' . $match[0]; + } + } + } + + // Every pack has a provider, a constants class, an enum and a component. A + // walk that stops finding them must fail, not pass over an empty tree. + expect($inspected)->toBeGreaterThanOrEqual(4) + ->and($offenders)->toBe([]); +}); From e32d435625edeb69015ff37e7c6e3cf830d44027 Mon Sep 17 00:00:00 2001 From: Imani Manyara Date: Thu, 5 Nov 2026 02:20:50 -0500 Subject: [PATCH 2/2] Link core's repositories block instead of restating it --- CHANGELOG.md | 1 + README.md | 14 +------------- docs/architecture.md | 13 ++++++++----- docs/installation.md | 9 +++++---- 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53834d1..9bcad99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to `ichava/icon-sets-ionicons` follow [Keep a Changelog](htt ### Changed +- **This pack requires `ichava/core` and nothing else.** `composer.json` `require` is now `php` and `ichava/core`; `illuminate/support` and `laranail/package-tools` were dropped from it and still arrive through core. The provider extends core's `IconPackServiceProvider` and declares its constants class and component class, so `src/` imports no `laranail/*` namespace; it registers the same name, path, Blade component and icon directory as before. The composer `type` is `ichava-icon-set`, which core's pack discovery reads. The README and `docs/installation.md` no longer restate the `laranail/*` repositories: they link to core's installation guide, the one place that lists them, and no longer say the pack is on Packagist, which no Ichava package is yet. `tests/Unit/CoreOnlyDependencyTest.php` fails if any of it comes back. - **The upstream sync runs icon-sets-sync `06b17d7`** (icon-sets-sync#88), up from `5fa93a6`, which adds this pack's recipe, the `split-variants` and `exclude` transforms, and the `licence_sha256` pin on the upstream licence text. The `uses:` pin and `toolkit-ref` move together; the reusable workflow's inputs did not change between the two commits, so the caller's `with:` block is untouched. ## [0.1.0] - TBD diff --git a/README.md b/README.md index 5d0ab49..811f07d 100644 --- a/README.md +++ b/README.md @@ -11,19 +11,7 @@ Requires [`ichava/core`](https://github.com/ichava/core) `^0.1` on PHP `^8.4.1 | ## Install -The `laranail/*` packages core depends on are not on Packagist yet, and neither is this pack, so the **application's** `composer.json` names them: - -```json -{ - "repositories": [ - { "type": "vcs", "url": "https://github.com/ichava/icon-sets-ionicons" }, - { "type": "vcs", "url": "https://github.com/laranail/package-tools" }, - { "type": "vcs", "url": "https://github.com/laranail/console" }, - { "type": "vcs", "url": "https://github.com/laranail/enumerator" }, - { "type": "vcs", "url": "https://github.com/laranail/db-tools" } - ] -} -``` +This pack requires [`ichava/core`](https://github.com/ichava/core) and nothing else. Nothing in the Ichava family is on Packagist yet, so the **application's** `composer.json` first names the repositories: core's [installation guide](https://github.com/ichava/core/blob/main/docs/installation.md#1-point-composer-at-the-repositories) holds the one block that lists them, core's dependencies included, and this pack's line in it is `https://github.com/ichava/icon-sets-ionicons`. Then require the pack: diff --git a/docs/architecture.md b/docs/architecture.md index 15d6e2d..9220ae1 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -28,11 +28,14 @@ The pack registers its icon directory with core's `IconRegistry` during `booting core's singletons are bound. Core discovers installed packs at runtime. It has no list of them, so a pack is added by installing it and removed by removing it. -## It requires `laranail/package-tools` directly - -The provider writes `Package` into its own `configurePackage()` signature, so it depends on that -class whatever the dependency graph delivers transitively through core. **Require what you import** -is the rule; a transitive dependency is not a contract. +## It requires `ichava/core` only + +`composer.json` requires `php` and `ichava/core`, and nothing under `src/` names a class from any +other `Simtabi\Laranail` namespace. The provider extends core's `IconPackServiceProvider` and declares +its constants class and its component class; core writes the `laranail/package-tools` signature, so +the `laranail/*` packages reach this pack only through core. The composer `type` is +`ichava-icon-set`, which is how core's pack discovery finds it. `tests/Unit/CoreOnlyDependencyTest.php` +fails if any of that changes. ## Upstream diff --git a/docs/installation.md b/docs/installation.md index 471e434..439d8ba 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -9,10 +9,11 @@ Core is the engine; this pack is only icons and the provider that registers them ## The repositories block -Neither this pack nor the `laranail/*` packages core depends on are on Packagist yet, so Composer has to be told where to find them. -Composer reads `repositories` only from the root package, which is why the block belongs in the -**application's** `composer.json` and has to name the whole transitive closure rather than just this -pack. Core's [installation guide](https://github.com/ichava/core/blob/main/docs/installation.md) gives the full block. +This pack requires `ichava/core` and nothing else; the `laranail/*` packages are core's dependencies, +not this pack's. Nothing in the Ichava family is on Packagist yet, and Composer reads `repositories` +only from the root package, so the **application's** `composer.json` names core, core's dependencies +and this pack. Core's [installation guide](https://github.com/ichava/core/blob/main/docs/installation.md#1-point-composer-at-the-repositories) holds that block and is the one place that lists +it; this pack's line is `https://github.com/ichava/icon-sets-ionicons`. ## Require it