artisanpack-ui/code-style-pint
Laravel Pint preset that enforces ArtisanPack UI coding standards, matching the artisanpack-ui/code-style PHPCS rules. Publish a ready-made pint.json via artisan command, generate configs for packages with PintConfigBuilder, or opt into WordPress-style spacing with PHP-CS-Fixer.
Architecture fit. This is a configuration-distribution package, not a runtime library. It ships a pint.json stub, a PintConfigBuilder fluent API, an ArtisanPackUIPreset rule-set class, an artisan publish command (artisanpack:publish-pint-config), and an optional PHP-CS-Fixer stub for WordPress-style spacing. Architecturally it sits entirely in the dev-dependency layer and touches no production code paths — the blast radius of adopting it is limited to developer tooling and CI. That is a favorable risk profile for a TPM: it can be trialed, measured, and reverted without a release train. The one architectural wrinkle is that the package straddles two formatters (Pint/PHP-CS-Fixer) and two standards packages (this one plus artisanpack-ui/code-style PHPCS), so "the standard" is actually enforced by a pair of tools with different installation, invocation, and CI semantics. That bifurcation is the main thing a TPM must pin down before committing.
Integration feasibility. Technically straightforward: composer require --dev, run the publish command, run ./vendor/bin/pint. For package repositories (no artisan), the builder script or a direct stub copy works, and the docs supply a pint-setup.php recipe plus composer script aliases. The builder API has clear levers (enable/disable rule groups, add/remove rules, exclude paths) so teams can dial back contentious rules like yoda_style and declare_strict_types without forking. Feasibility is high; the friction is organizational, not technical — the preset is opinionated and will produce a large first-pass diff.
Technical risk. Several concrete concerns:
pint --test.Key questions.
laravel preset plus a handful of custom rules may deliver 90% of the value with zero third-party dependency.artisanpack-ui/code-style PHPCS package at the same time, or run Pint alone? Half the standard is unenforced without it.composer.json.Stack fit. Native to Laravel: Pint ships with the framework, the package publishes via artisan, and the preset's rules map cleanly onto PHP-CS-Fixer fixers that Laravel developers already encounter. The PHP-CS-Fixer path is only relevant if WordPress-style spacing is a real requirement; otherwise it is dead weight. Fit is good for a Laravel shop with an existing pint.json; poor for a polyglot repo or a non-Laravel PHP codebase, since there is no artisan and you fall back to a bootstrap script.
Migration path. Two viable routes, and the choice should be deliberate:
pint once, commit the resulting formatting diff as an isolated, review-free "style only" commit, add a pint --test gate to CI. Fast, clean, done in an afternoon.PintConfigBuilder and enable rule groups incrementally — formatting rules first (mechanical, low controversy), then structure rules (ordered_class_elements, ordered_imports, which generate the biggest diffs), then best practices last (declare_strict_types and yoda_style last, since these change semantics-adjacent code and provoke the most reviewer pushback). Land each group as its own PR. Realistically three to five PRs over two to three sprints for a mid-sized codebase.Either way, seed the effort with .git-blame-ignore-revs pointing at the formatting commits. This is cheap, and it is the single highest-leverage step for preserving git blame usefulness and defusing "you broke history" objections. Note that declare_strict_types will add declare(strict_types=1); to every file — that is not purely cosmetic and can surface latent TypeErrors at runtime in code paths that previously coerced. Treat that rule as a separate, tested increment, not part of the formatting sweep.
Compatibility. Requires Composer-installed Pint (present in any modern Laravel app). Confirm the Pint major version shipped by the Laravel version in use and verify every fixer named in the preset exists in that version before rollout — a quick pint --test on a single file will expose unknown-rule errors. PHP-CS-Fixer, if used, is a separate install with its own version drift. Editor integration (PhpStorm external tool, VS Code Laravel Pint extension) is conventional and low-risk. The Laravel Boost guideline override is a nice touch for AI-assisted workflows but should be treated as optional; it also means the package will quietly inject prompt guidance into assistants, which some orgs will want to review.
Sequencing.
--force into a branch, run pint --test to generate a diff-size report. This is the go/no-go gate and costs hours, not days.^1.0 on a 0-dependent package).yoda_style, declare_strict_types, assignment alignment via binary_operator_spaces) with the team before the sweep — retroactively removing a rule after 300 files are reformatted is wasted work..git-blame-ignore-revs.pint --test on PRs, plus PHPCS if adopted.composer pint / composer pint:test script aliases and a short contribution note in the repo README.Maintenance. Low ongoing burden in the steady state — a pinned pint.json is inert — but the ownership question is real. With one maintainer and no downstream users, upstream is unlikely to prioritize fixes for a rule that misfires in your codebase; your realistic fallback is to inline the offending rule override locally (which addRule/removeRule/exclude make easy) or fork. Budget for a Pint major-version review once per year alongside Laravel upgrades, plus a re-run of the preset against the upgraded fixer set. The vendored-stub escape hatch (cp stubs/pint.json.stub pint.json) is valuable: it means the package can be dropped entirely and the config survives, which materially de-risks the dependency.
Support. Community-only, MIT/GPL ambiguous, no vendor relationship, no SLA. Internal support burden is low in absolute terms because the failure modes are developer-visible and local (a formatter complains; you read the error). The absence of stars and dependents means you cannot lean on a Stack Overflow corpus for obscure rule interactions; expect to debug PHP-CS-Fixer fixer behavior directly. Assign one named owner per repo — a "style steward" — rather than treating it as nobody's problem.
Scaling. Scales fine across many repositories: the same pinned preset and the same CI job replicate cheaply, and the builder makes programmatic generation across a monorepo or package fleet trivial. The genuinely non-scaling part is human — a large formatting diff against a large, actively-developed repo creates a merge-conflict window where every open branch must rebase. Mitigate by scheduling the sweep at a low-velocity moment, announcing a code freeze window of hours (not days), and having the steward run the reformat and push rather than asking 15 developers to do it individually. The WordPress-spacing path scales worse: it introduces a second formatter, a second CI job, and divergent local workflows, so only take it on if there is a durable business reason.
Failure modes.
pint --test in CI plus a periodic spot-check that the ruleset still parses as expected.exclude to unblock a PR and never remove them; enforcement hollows out. Review the exclude list at each upgrade.declare_strict_types late can surface runtime TypeErrors in weakly-tested paths. Treat as a tested increment, never a drive-by.--force clobbers local customizations; default to non-forced publishes and diff before committing.Ramp-up. Minimal for developers: composer pint and composer pint:test are self-explanatory, and Pint is already familiar Laravel tooling. A half-page in the repo README plus editor integration covers it. The real ramp-up cost sits with the steward: understanding PintConfigBuilder composition, PHP-CS-Fixer fixer semantics, and how to negotiate rule relaxations with the team. That is roughly a day of focused work. For wider org adoption, one 30-minute walkthrough covering the CI gate, the blame-ignore file, and "what to do when Pint disagrees with your PR" is sufficient. Overall: cheap to adopt, cheap to reverse, but the 0-dependent status means you are the pilot — plan the initial spike accordingly and do not treat the preset as validated until it has survived one real codebase.
How can I help you explore Laravel packages today?