From 7ec6960731852eb56c161125802b5a83b5bb162d Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Tue, 15 Sep 2026 07:51:07 +0200 Subject: [PATCH] Add Stylesheets::resolvedFiles() for the design guard to reuse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plan step 41 (ii): the design guard needs the set of files an application's CSS entry pulls in, transitively, to check whether a package tag's stylesheet is among them — reusing bundle()'s own import resolution and cache rather than re-implementing @import parsing. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9 --- src/Support/Stylesheets.php | 23 +++++++++++++++++++++++ tests/Feature/StylesheetsBundleTest.php | 11 +++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/Support/Stylesheets.php b/src/Support/Stylesheets.php index a9c174eb..5f0f1cac 100644 --- a/src/Support/Stylesheets.php +++ b/src/Support/Stylesheets.php @@ -92,6 +92,29 @@ final class Stylesheets self::$cache = []; } + /** + * Every file `$files` reaches, transitively, through the same `@import` resolution `bundle()` + * walks — real paths, `$files` themselves included — without concatenating anything. + * `DesignGuard::missingStylesheets()` (plan step 41) asks this: whether an application's CSS + * entry's import graph already reaches a given package stylesheet, which needs the file + * identities `bundle()` resolves, not the CSS it produces. Shares `bundle()`'s cache (and so + * its freshness rule) under the same key, `$base` fixed to `null`, since only `bundle()` ever + * populates it. + * + * @param list $files + * @return list + */ + public static function resolvedFiles(array $files): array + { + if ($files === []) { + return []; + } + + self::bundle($files); + + return array_keys(self::$cache[serialize([$files, null])]['files']); + } + /** * @param array $files every file a cached bundle inlined, with its mtime then */ diff --git a/tests/Feature/StylesheetsBundleTest.php b/tests/Feature/StylesheetsBundleTest.php index e768298e..bccb7e73 100644 --- a/tests/Feature/StylesheetsBundleTest.php +++ b/tests/Feature/StylesheetsBundleTest.php @@ -82,6 +82,17 @@ it('bundles all.css with every import resolved, foundation first, every componen ->and($foundationPosition)->toBeLessThan($earliestOtherPosition); }); +it('resolves the files an entry imports, transitively, without bundling any content', function () { + $files = Stylesheets::resolvedFiles([stylesheetsBundlePath('components/split-button.css')]); + + expect($files)->toContain( + stylesheetsBundlePath('components/split-button.css'), + stylesheetsBundlePath('components/button.css'), + stylesheetsBundlePath('components/menu.css'), + stylesheetsBundlePath('components/icon.css'), + ); +}); + it('keeps a file two others import once, at its first position', function () { $dir = sys_get_temp_dir().'/livewire-material-bundle-'.Str::random(8); File::makeDirectory($dir);