diff --git a/CHANGELOG.md b/CHANGELOG.md index b8963f7..9cc62d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ All notable changes to `ichava/core` follow [Keep a Changelog](https://keepachan ### Fixed +- **A pack listed with the application boots again.** `PackConfigCache` resolved the cache store when it was built, and a pack's constants class builds it while the providers are still registering, before the store exists, so every pack failed to boot with `Target class [cache] does not exist` (found running the packs against #172). The store is now resolved when it is used. Core's own pack tests registered their fixture after boot, which is why none saw it; `tests/Feature/PackBootsInProviderListTest.php` lists the fixture with the application. - **`InformationService::discoverPackages()` finds the installed packs.** It globbed `vendor/*/ichava-*`, which matches no pack (packs install as `vendor/ichava/icon-sets-*`), and reported `registered` through `IconRegistry::has()`, which looks up an icon, not a package, so `ichava::ichava-core.info discover` listed nothing. It now asks `Composer\InstalledVersions` for every package of type `ichava-icon-set` and reports `registered` through `IconRegistry::isRegistered()`. The signature and return shape are unchanged. A pack is identified by its composer type and nothing else (owner, 2026-11-05): the `vendor/*/ichava-*` directory glob is removed, since no pack in the estate matched it, and the `platform/ichava` scan now keeps only a directory whose composer.json declares `ichava-icon-set`, keyed by that file's `name` instead of `ichava/`. A checkout there without the type is no longer listed. `tests/Feature/InstalledPackDiscoveryTest.php`. - **The installation guide no longer says core is on Packagist.** Nothing in the family is (`repo.packagist.org` answers 404 for core, every pack and the four `laranail/*` packages). `docs/installation.md` step 1 is now the one place that lists the repositories an application adds, `ichava/core` included; the README and every pack link to it. - **The US and UM flags keep their stars.** Both draw the fifty stars as one `` repeated by `marker-mid="url(#us-a)"`, and `resources/security/svg-policy.json` did not allow ``, so the sanitiser removed it and the reference pointed at nothing. The policy now allows `` and its geometry (`refX`, `refY`, `markerWidth`, `markerHeight`, `orient`, `markerUnits`), the same bytes as ichava/icon-sets-sync#91. Scripts, `on*` handlers and external `href` on or inside a marker are still stripped, and `marker-*` still take only `none` or `url(#fragment)`. `tests/fixtures/svg/presentation-vectors.json` gains 8 attribute rows and 6 whole-document rows, which `SvgPresentationParityTest` runs through the full sanitiser. diff --git a/src/Support/PackConfigCache.php b/src/Support/PackConfigCache.php index 39178bf..de59ea6 100644 --- a/src/Support/PackConfigCache.php +++ b/src/Support/PackConfigCache.php @@ -5,6 +5,8 @@ namespace Simtabi\Laranail\Ichava\Support; use Throwable; +use Illuminate\Contracts\Cache\Repository; +use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Cache\Factory as CacheFactory; /** @@ -19,7 +21,12 @@ { private const int TTL_SECONDS = 86_400; - public function __construct(private CacheFactory $cache) {} + /** + * The container, not the cache factory: a pack's constants class reads its + * config while the providers register, before the cache store exists, so + * the store is resolved on use and a failure falls back to reading the file. + */ + public function __construct(private Container $app) {} /** The cache key for the config.json in $directoryPath. */ public function key(string $directoryPath): string @@ -36,7 +43,7 @@ public function key(string $directoryPath): string public function remember(string $directoryPath, callable $load): mixed { try { - return $this->cache->store('file')->remember($this->key($directoryPath), self::TTL_SECONDS, $load(...)); + return $this->store()->remember($this->key($directoryPath), self::TTL_SECONDS, $load(...)); } catch (Throwable) { return $load(); } @@ -46,9 +53,16 @@ public function remember(string $directoryPath, callable $load): mixed public function forget(string $directoryPath): bool { try { - return $this->cache->store('file')->forget($this->key($directoryPath)); + return $this->store()->forget($this->key($directoryPath)); } catch (Throwable) { return false; } } + + private function store(): Repository + { + $factory = $this->app->make(CacheFactory::class); + + return $factory->store('file'); + } } diff --git a/tests/Feature/PackBootsInProviderListTest.php b/tests/Feature/PackBootsInProviderListTest.php new file mode 100644 index 0000000..f6c0042 --- /dev/null +++ b/tests/Feature/PackBootsInProviderListTest.php @@ -0,0 +1,20 @@ +extraProviders = [IconsServiceProvider::class]; + $this->refreshApplication(); + + expect(app(IconRegistry::class)->isRegistered('ichava/icon-sets-base-fixture'))->toBeTrue(); +});