feat(cli): Project configuration API (replaces loadConfig)#3277
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
PR Analysis Report📚 Storybook PreviewView Storybook for this PR 🧪 Sandbox PreviewView Sandbox for this PR No new or modified components detected. Bundle Size Summary
Accessibility AuditStatus: No accessibility violations detected. Generated by PR Enrichment workflow | Storybook | Sandbox | View full report |
Introduce the Project class as a single, lazy, memoized entry point for reading resolved project configuration and discovery (components, templates, codemods) plus integration issue routing. Add a small pluggable cache (InMemoryConfigCache) keyed by a config content hash + cwd + discovery kind.
Route every config/discovery read through Project.load: discover, doctor, layout, template, component, swizzle, and the component/template command wrappers. findConfigPath now lives in lib/project.mjs as the single home. Removes lib/config.mjs (loadConfig) with no shim.
Upgrade now treats an integration definition error (bad manifest/export, duplicate ids, missing root) as skip-and-warn rather than a hard failure, while an execution-time codemod throw still aborts the run. Adds a variadic --skip-codemod flag to exclude named codemods (core transform name or integration codemod id) so users can re-run past a failed codemod.
afdc265 to
47c92aa
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Introduces a
Projectclass as the single API for reading resolved projectconfiguration, replacing
loadConfigentirely. Previously nine+ call siteseach loaded the config and then independently fanned out to discovery helpers
(component ownership, templates, integration codemods). This centralizes all of
that behind one class.
The
Projectclass (packages/cli/src/lib/project.mjs)Project.load(cwd, { cache })is the async factory (constructors can't beasync). It does exactly what
loadConfigdid — find the config sibling of thenearest
package.json, import + validate it, load the configured integrations— and nothing more. Discovery is lazy and memoized.
config/integrations/loadedIntegrations/cwd— the raw surface.components()/templates()/codemods(from, to)— memoized discoverythat wraps the existing discovery functions (never reimplements them).
issuesUrl(ref)— routes core toconfig.issuesUrl(or the default tracker)and an integration package to its manifest
issuesUrl.issues()— the accumulated, deduped integration issues; when calleddirectly it also validates any configured integration not yet visited by a
discovery call, so the set is always complete on demand.
Lazy + memoized + skip-and-warn
load()does not validate integrations. As each discovery method runs itguards per-integration work so one broken integration never throws out of
discovery — its contributions are skipped and any issue is collected into a
private set (the skip + warn policy). Memoization runs through a small pluggable
cache.
Pluggable cache
A tiny
ConfigCacheinterface (get/set) with an in-memory default. Cachekeys are derived from a config-file content hash + cwd + discovery kind
(+args), e.g.
codemods:<from>..<to>. The in-memory cache never busts, but thehash is computed regardless so a future file-backed, hash-busting cache drops
in with no API change.
Migrating callers + removing
loadConfigEvery caller now routes through
Project.load:discover,doctor,layout,template,component,swizzle, and thecomponent/templatecommandwrappers.
findConfigPathnow lives inlib/project.mjsas the single home.lib/config.mjs(loadConfig) is removed with no shim. Each command's existingoutput/behavior is unchanged.
Upgrade error policy +
--skip-codemodmissing root) now skip that integration's codemods and warn, instead of
hard-failing the upgrade. This reverses the previous hard-fail behavior.
abort the upgrade so a partial write never proceeds.
--skip-codemod <name...>flag excludes named codemods by thesame identifier the run loop matches (core transform
name, integrationcodemod
id), so a user who hits an execution failure can re-run past it.Tests
project.test.mjs: load/config/integrations, discovery results,memoization (no re-walk), issue collection + dedupe, broken-integration skip,
issuesUrl routing, shared-cache reuse.
config-cache.test.mjs: cache get/set, content-hash stability/variance,key derivation.
upgrade.integration-policy.test.mjs: broken integration is skipped (nota hard fail), a healthy integration codemod runs, and
--skip-codemodexcludes a named codemod.
updated where they referenced
loadConfigdirectly or the old hard-failpolicy.
Full CLI suite: 1583 passing.