mi/puli-metadata-file-locator-bundle
Symfony bundle that integrates Puli's metadata file locator, letting you resolve and locate package resource files through Puli's metadata-driven path system. It wires the locator into Symfony's service container so bundles and libraries can discover assets and configuration reliably.
Architecture fit. The framing says "Laravel/PHP package," but this is a Symfony bundle, not a Laravel library — a distinction that materially changes the recommendation. MiPuliMetadataFileLocatorBundle exists for exactly one seam: it decorates Symfony's file_locator so that MetadataFileLocator consumers (validator, serializer, Doctrine, translation, routing loaders) resolve logical Puli resource paths — /acme/blog/doctrine — instead of filesystem paths or @AcmeBundle notation. In Laravel there is no MetadataFileLocator, no bundle kernel, and no compiler pass to hook into; the integration point does not exist. Even within Symfony the fit has decayed: Symfony deprecated its Puli integration in 3.3 and removed it in 4.0, and Puli itself is abandoned upstream. This is a bridge for a stack that stopped existing several years ago.
Integration feasibility. Low-to-none outside a maintained Symfony 2.8/3.x application. Adoption pulls puli/manager, puli/discovery, and the Puli Composer plugin into the graph, plus a puli.json manifest bound at container compile time. Expect Composer to refuse resolution alongside Symfony 5/6/7 or Laravel 9/10/11 on transitive symfony/* constraints and PHP version floors. The only credible entry point is an existing app already running Puli.
Technical risk. High, and lifecycle-driven rather than code-quality-driven. Zero stars, zero dependents, zero forks means no external validation, no downstream bug reports, and no one else hardening this path. The bundle sits on a compile-time hot path, so its failure surface is container compilation and "file not found" exceptions — a poor place to carry an unmaintained dependency. Any CVE in the Puli tree becomes permanently ours.
Key questions.
%kernel.project_dir%, Laravel's resource_path() / vendor:publish, or a small custom FileLocatorInterface decorator satisfy the requirement outright?Stack fit. Poor for Laravel, conditional for legacy Symfony. Laravel's native mechanisms — service providers, config publishing, resource_path(), extra.laravel package discovery — already cover "find package-provided config" without a resource abstraction, and there is no idiomatic place to register a Puli-backed locator. Introducing Puli would create a parallel discovery mechanism competing with Laravel's own.
Migration path. Two realistic routes. (1) Legacy Symfony already on Puli: install alongside the existing setup, register the bundle in AppKernel near FrameworkBundle, bind resources in puli.json, then confirm via debug:container file_locator that the service class has actually changed and that both Puli and filesystem paths resolve. (2) Greenfield or Laravel: do not adopt. Use an explicit ordered path list resolved by the framework's native locator; if package-contributed metadata is genuinely required, implement a thin locator (~200–400 LOC) with unit tests rather than inheriting an abandoned dependency tree.
Compatibility. Assume PHP 5.5–7.x-era constraints and Symfony <4; verify against the actual composer.json before any commitment. Expect conflicts with modern PHPUnit, modern symfony/*, and static-analysis tooling. The Puli Composer plugin also mutates install behaviour, which is a CI reproducibility concern independent of runtime compatibility.
Sequencing. Timebox a one-to-two-day spike in an isolated branch: resolve dependencies, boot a minimal kernel, prove one validator metadata file loads through Puli, and confirm the path-not-found failure mode is observable. Gate the decision on that spike. Run the native-path prototype in parallel so a credible fallback exists before commitment. Critically, do not sequence this ahead of a framework upgrade — if Symfony 4+ or a Laravel migration is on the roadmap, that work deletes this bundle anyway, so the migration leads and this is reassessed afterward.
Maintenance. Effectively a fork-and-own decision from day one. Budget for dependency pinning, a vendored copy or private Composer repository, and periodic review of Puli's transitive tree. The zero-dependents signal means no one else is paying this tax; the full burden lands on our team.
Support. No upstream channel, no issue triage, no security advisories. Internal escalation means reading Puli's source. Document the metadata resolution order explicitly — it will not be obvious to anyone joining later, and the bundle itself gives no diagnostics when resolution misfires.
Scaling. No meaningful request-path throughput impact; metadata resolves and caches at container compile/warmup. The scaling concern is organizational: every new package and environment must correctly declare Puli resources, and that convention erodes quietly as teams turn over. The abstraction's value decays faster than the code does.
Failure modes. Composer resolution failure on any framework upgrade; container compile failure when the Puli repository is unbound or puli.json is malformed; silent fallback to filesystem paths that passes tests while defeating the abstraction's entire purpose; cache-warmup divergence between environments producing "works locally, fails in CI"; and abandoned-dependency exposure with no patch path. The silent-fallback case is the most dangerous because it is invisible until someone depends on the indirection.
Ramp-up. The bundle is small; the cost is Puli's mental model — repositories, bindings, package-relative paths, puli build versus puli status — which is undocumented tribal knowledge for an abandoned tool. Estimate days rather than hours for a new engineer to debug an unfamiliar resolution failure, and assume that knowledge walks out the door with whoever introduced it.
How can I help you explore Laravel packages today?