Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/<directory>`. 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 `<marker>` repeated by `marker-mid="url(#us-a)"`, and `resources/security/svg-policy.json` did not allow `<marker>`, so the sanitiser removed it and the reference pointed at nothing. The policy now allows `<marker>` 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.
Expand Down
20 changes: 17 additions & 3 deletions src/Support/PackConfigCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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
Expand All @@ -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();
}
Expand All @@ -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');
}
}
20 changes: 20 additions & 0 deletions tests/Feature/PackBootsInProviderListTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

use Simtabi\Laranail\Ichava\Services\IconRegistry;
use Simtabi\Laranail\Ichava\Tests\Fixtures\BasePack\Providers\IconsServiceProvider;

/*
* A pack listed beside core boots: its constants class is read while the
* providers register, before the cache store is ready, so nothing on that
* path may resolve the cache at construction. Every other pack test
* registers the fixture after boot, which is how this went unseen.
*/

it('boots a pack provider registered with the application, not after it', function (): void {
$this->extraProviders = [IconsServiceProvider::class];
$this->refreshApplication();

expect(app(IconRegistry::class)->isRegistered('ichava/icon-sets-base-fixture'))->toBeTrue();
});
Loading