From 01f56e73f930e2ae18adb6263d715eccc2c678a1 Mon Sep 17 00:00:00 2001 From: Imani Manyara Date: Thu, 5 Nov 2026 02:18:35 -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 fdf4060..095e510 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "ichava/icon-sets-bootstrap", "description": "2,078 Bootstrap Icons (v1.13.2) for Laravel 13 on the Ichava icon ecosystem. Artwork MIT, by The Bootstrap Authors.", - "type": "library", + "type": "ichava-icon-set", "keywords": [ "icons", "svg", @@ -22,9 +22,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 03c0291..d80685e 100644 --- a/src/Providers/IconsServiceProvider.php +++ b/src/Providers/IconsServiceProvider.php @@ -4,37 +4,22 @@ namespace Simtabi\Laranail\Ichava\IconSetsBootstrap\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\IconSetsBootstrap\Constants\IconsConstants; use Simtabi\Laranail\Ichava\IconSetsBootstrap\View\Components\IconComponent; /** * Registers the Bootstrap Icons 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-bootstrap'); - - $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 fae0b2152e7ac7835e6d41bdf09e846fb43ab3b8 Mon Sep 17 00:00:00 2001 From: Imani Manyara Date: Thu, 5 Nov 2026 02:18:35 -0500 Subject: [PATCH 2/2] Link core's repositories block instead of restating it --- CHANGELOG.md | 1 + README.md | 13 +------------ docs/architecture.md | 13 ++++++++----- docs/installation.md | 9 +++++---- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a35ee00..12f9c9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to `ichava/icon-sets-bootstrap` follow [Keep a Changelog](ht ### 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 42c4f2b..057aeb4 100644 --- a/README.md +++ b/README.md @@ -11,18 +11,7 @@ Requires [`ichava/core`](https://github.com/ichava/core) `^0.1` on PHP `^8.4.1 | ## Install -`ichava/core` and this pack come from Packagist. The `laranail/*` packages core depends on are not on Packagist yet, so the **application's** `composer.json` names them: - -```json -{ - "repositories": [ - { "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-bootstrap`. Then require the pack: diff --git a/docs/architecture.md b/docs/architecture.md index 1f03edf..5e98fa4 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -23,11 +23,14 @@ that do not exist yet, and logging there raises `Log [ichava] not defined`. 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 cbe178f..c5b338f 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 -The `ichava/*` packages are on Packagist, but the `laranail/*` packages core depends on are not 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-bootstrap`. ## Require it