CodeVetter · Repo Unpack · Behavior traces
prettier/prettier
Three user-visible flows were walked in source. CLI startup validates Node, builds a Context from argv/plugins, then dispatches to version/help/support/config-path/file-info, stdin, or formatFiles. Formatting a file expands globs, resolves per-file options, optionally hits cache, then runs the parse→doc→string pipeline. Persistence is either in-place write via mockable.writeFormattedFile, stdout, or a check/list-different exit code.
- CLI startup order: bin/prettier.cjs run() → version check against engines.node → shouldEnableExperimentalCli → import src/cli/index.js → cli.run(process.argv.slice(2)).
- src/cli/index.js run(): parseArgvWithoutPlugins for log-level → new Context → context.init() (parse --plugin, getContextOptions, parseArgv, filePatterns=argv._) → main(context) with mutually exclusive flag checks.
- main() dispatch: --version prints prettier.version; --help uses createUsage/createDetailedUsage; --support-info → printSupportInfo; --find-config-path → logResolvedConfigPathOrDie; --file-info → logFileInfoOrDie; else stdin if no patterns and (stdin not TTY or --stdin-filepath); else formatFiles; else usage + exitCode 1.
- formatFiles: createIsIgnoredFromContextOrDie → optional FormatResultsCache → for await expandPatterns → skip ignored in write/check/list-different/debug-check → getOptionsForFile → fs.readFile utf8 → cache hit returns input unchanged else format() → maybe mockable.writeFormattedFile → set/remove cache → check summary + exitCode 1 if unformatted and not --write.
- format() inner function: debugPrintDoc → __debug.printToDoc then formatDoc; debugPrintComments → formatWithCursor.comments JSON; debugPrintAst → JSON.stringify(ast); debugCheck double-formats and compares massaged ASTs; else performance loop or prettier.formatWithCursor.
- API format path: prettier.format → formatWithCursor(cursorOffset:-1) → withPlugins loads loadBuiltinPlugins()+loadPlugins(plugins) → core.formatWithCursor → coreFormat: parseText → printAstToDoc → printDocToStringWithoutNormalizeOptions.
- Parser/printer resolve loops plugins.findLast so later plugins override builtins (comment: temporarily solution, see #13729). Missing parser/printer throws ConfigError; in PRETTIER_TARGET=universal the message says plugins must be added to the standalone bundle.
- JS print dispatch in printWithoutParentheses tries printAngular, printJsx, printFlow, printTypescript, then printEstree in order, returning the first defined Doc.
- JS babel parser is createParser(createParse(...)) over @babel/parser with errorRecovery, a long plugin list (doExpressions, decorators, pipelineOperator combinations, etc.), then postprocess. Tests for those plugins live in tests/format/js/babel-plugins/ and are generated by scripts/update-babel-plugin-tests.js.
- oxc parser uses oxc-parser parseSync with preserveParens:true, maps labels to Prettier loc errors via index-to-position, and shares postprocess/createParser with other JS parsers.
- Playground flow: PrettierFormat setup() watches code/options/version → worker.format → WorkerApi posts to /worker.mjs?version=… → worker replies {uid, message, error}. Website README requires yarn build:website so UMD bundles exist in static/lib/.
- Config persistence is not a write of Prettier state: --write overwrites source files; --cache writes .prettier-cache JSON via file-entry-cache.reconcile(); clearConfigCache clears prettier-config, editorconfig, and plugin import caches.