-
Notifications
You must be signed in to change notification settings - Fork 559
feat(build-tools): add Biome 2.x configuration reader #25969
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat(build-tools): add Biome 2.x configuration reader #25969
Conversation
… interface Co-authored-by: tylerbutler <[email protected]>
… remove package-lock.json Co-authored-by: tylerbutler <[email protected]>
…dd nested extends tests Co-authored-by: tylerbutler <[email protected]>
…igs without extends Co-authored-by: tylerbutler <[email protected]>
Co-authored-by: tylerbutler <[email protected]>
… + find-up Co-authored-by: tylerbutler <[email protected]>
…hift performance Co-authored-by: tylerbutler <[email protected]>
…ing logic Co-authored-by: tylerbutler <[email protected]>
Co-authored-by: tylerbutler <[email protected]>
…consolidate getClosestBiomeConfigPath Co-authored-by: tylerbutler <[email protected]>
Co-authored-by: tylerbutler <[email protected]>
Co-authored-by: tylerbutler <[email protected]>
… in Biome 2.x Co-authored-by: tylerbutler <[email protected]>
…patterns Co-authored-by: tylerbutler <[email protected]>
| "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout", | ||
| "format": "npm run format:biome", | ||
| "format:biome": "biome check --write .", | ||
| "json-schema-to-typescript:biome2ConfigTypes": "json2ts --input node_modules/biome2/configuration_schema.json --output src/common/biome2ConfigTypes.d.ts", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't work until we update to biome 2. I tried adding it with an npm alias but that cause v2 to get triggered when running format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds support for Biome 2.x configuration format to the build tools, enabling fluid-build to correctly determine file scope for caching when Biome 2.x is used. The implementation introduces version detection, a new config reader for the unified includes field syntax with negation patterns, and shared utilities to reduce code duplication between Biome 1.x and 2.x implementations.
Key changes:
- Automatic version detection from package.json or CLI with fallback to Biome 1.x
- Support for Biome 2.x's unified
includesfield with negation patterns and re-inclusion support - Automatic parent config discovery via
rootfield and directory tree walking - Refactored shared utilities for config loading and extends resolution
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/common/biomeVersion.ts |
New file implementing Biome version detection from package.json and CLI |
src/common/biomeConfigUtils.ts |
New file with shared utilities for config loading, extends resolution, and file filtering |
src/common/biome2Config.ts |
New file implementing Biome 2.x config reader with unified includes field support |
src/common/biome2ConfigTypes.d.ts |
Auto-generated TypeScript definitions for Biome 2.x configuration schema |
src/common/biomeConfig.ts |
Refactored to use shared utilities, added BiomeConfigReader interface and createBiomeConfigReader factory |
src/fluidBuild/tasks/leaf/biomeTasks.ts |
Updated to use createBiomeConfigReader for automatic version detection |
src/test/biomeConfig.test.ts |
Updated to use renamed BiomeConfigReaderV1 class |
src/test/biome2Config.test.ts |
New comprehensive test suite for Biome 2.x functionality |
src/test/data/biome2/* |
New test data files for Biome 2.x config scenarios |
package.json |
Added script for generating biome2ConfigTypes (references non-existent package) |
|
|
||
| /** | ||
| * Loads a Biome 2.x configuration file _without_ following any 'extends' values. You probably want to use | ||
| * {@link loadBiome2Configs} instead of this function. |
Copilot
AI
Dec 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring references {@link loadBiome2Configs} (with an 's'), but the actual function is named loadBiome2Config (without the 's'). This should be corrected to {@link loadBiome2Config}.
| * {@link loadBiome2Configs} instead of this function. | |
| * {@link getAllBiome2ConfigPaths} instead of this function. |
| export function detectBiomeVersionFromCli(cwd?: string): BiomeVersionInfo | undefined { | ||
| try { | ||
| const output = execSync("npx biome --version", { | ||
| cwd, | ||
| encoding: "utf8", | ||
| stdio: ["pipe", "pipe", "pipe"], | ||
| }); | ||
|
|
||
| // Output format is "Version: X.Y.Z" or just "X.Y.Z" | ||
| const versionMatch = output.match(/(\d+\.\d+\.\d+)/); | ||
| if (versionMatch) { | ||
| const version = versionMatch[1]; | ||
| const major = semver.major(version); | ||
| if (major === 1 || major === 2) { | ||
| return { | ||
| version, | ||
| majorVersion: major as BiomeMajorVersion, | ||
| }; | ||
| } | ||
| } | ||
| } catch { | ||
| // Biome CLI not available or failed | ||
| } | ||
| return undefined; | ||
| } | ||
|
|
||
| /** | ||
| * Detects the Biome version by reading the package.json of the @biomejs/biome package. | ||
| * | ||
| * @param startDir - The directory to start searching from. Will look for node_modules/@biomejs/biome/package.json. | ||
| * @returns The Biome version information, or undefined if the package is not found. | ||
| */ | ||
| export async function detectBiomeVersionFromPackage( | ||
| startDir: string, | ||
| ): Promise<BiomeVersionInfo | undefined> { | ||
| // Try to find the biome package.json by walking up the directory tree | ||
| let currentDir = startDir; | ||
| const root = path.parse(currentDir).root; | ||
|
|
||
| while (currentDir !== root) { | ||
| const biomePkgPath = path.join( | ||
| currentDir, | ||
| "node_modules", | ||
| "@biomejs", | ||
| "biome", | ||
| "package.json", | ||
| ); | ||
| try { | ||
| const content = await readFile(biomePkgPath, "utf8"); | ||
| const pkg = JSON.parse(content) as { version?: string }; | ||
| if (pkg.version) { | ||
| const major = semver.major(pkg.version); | ||
| if (major === 1 || major === 2) { | ||
| return { | ||
| version: pkg.version, | ||
| majorVersion: major as BiomeMajorVersion, | ||
| }; | ||
| } | ||
| } | ||
| } catch { | ||
| // Package not found at this level, continue searching | ||
| } | ||
| currentDir = path.dirname(currentDir); | ||
| } | ||
|
|
||
| return undefined; | ||
| } | ||
|
|
||
| /** | ||
| * Detects the Biome version, trying multiple methods: | ||
| * 1. First, try to read the version from the installed @biomejs/biome package | ||
| * 2. Fall back to running the Biome CLI | ||
| * | ||
| * @param startDir - The directory to start searching from. | ||
| * @returns The Biome version information, or undefined if Biome cannot be detected. | ||
| */ | ||
| export async function detectBiomeVersion( | ||
| startDir: string, | ||
| ): Promise<BiomeVersionInfo | undefined> { | ||
| // Try package.json first (faster and more reliable) | ||
| const fromPackage = await detectBiomeVersionFromPackage(startDir); | ||
| if (fromPackage) { | ||
| return fromPackage; | ||
| } | ||
|
|
||
| // Fall back to CLI detection | ||
| return detectBiomeVersionFromCli(startDir); | ||
| } |
Copilot
AI
Dec 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The version detection functions (detectBiomeVersion, detectBiomeVersionFromPackage, detectBiomeVersionFromCli) lack test coverage. These functions contain logic that could fail in various ways (e.g., package.json not found, CLI not available, invalid version format) and would benefit from unit tests.
Consider adding tests that cover:
- Successful version detection from package.json
- Successful version detection from CLI
- Fallback behavior when package.json method fails
- Handling of invalid version strings
- Behavior when Biome is not installed
| export async function createBiomeConfigReader( | ||
| directoryOrConfigFile: string, | ||
| gitRepo: GitRepo, | ||
| forceVersion?: BiomeMajorVersion, | ||
| ): Promise<BiomeConfigReader> { | ||
| let majorVersion: BiomeMajorVersion; | ||
|
|
||
| if (forceVersion !== undefined) { | ||
| majorVersion = forceVersion; | ||
| } else { | ||
| // Auto-detect the Biome version | ||
| const versionInfo = await detectBiomeVersion(directoryOrConfigFile); | ||
| majorVersion = versionInfo?.majorVersion ?? 1; // Default to 1.x if detection fails | ||
| } | ||
|
|
||
| if (majorVersion === 2) { | ||
| return Biome2ConfigReader.create(directoryOrConfigFile, gitRepo); | ||
| } | ||
|
|
||
| // Default to Biome 1.x reader | ||
| return BiomeConfigReaderV1.create(directoryOrConfigFile, gitRepo); | ||
| } |
Copilot
AI
Dec 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The createBiomeConfigReader factory function lacks test coverage. This is a key new API that automatically detects the Biome version and returns the appropriate reader. Tests should verify:
- Correct reader selection based on detected version (1.x vs 2.x)
- Behavior when version detection fails (should default to 1.x)
- Force version parameter override functionality
- Integration with both
BiomeConfigReaderV1andBiome2ConfigReader
Description
Biome 2.x changed configuration format from separate
include/ignorefields to a unifiedincludesfield with negation patterns (e.g.,["**", "!node_modules/**"]). This adds support for the new format so fluid-build can correctly determine file scope for caching.New files:
biome2ConfigTypes.d.ts- Type definitions for Biome 2.x config format (includingrootfield)biome2Config.ts- Reader that parses unifiedincludesfield with negation supportbiomeVersion.ts- Version detection from package.json or CLIbiomeConfigUtils.ts- Shared utilities for config loading and extends resolutionChanges to
biomeConfig.ts:BiomeConfigReaderInterface- Common interface for both readerscreateBiomeConfigReader()- Factory with auto-detectionbiomeConfigUtils.tsKey features:
rootfield for automatic parent config discovery (walks up directory tree untilroot: trueis found)extendsdeclarations and automatic parent config mergingincludesfield and separates include/ignore patternsUsage:
Import directly from source modules:
Reviewer Guidance
BiomeConfigReaderInterfacefor interoperabilitybiomeConfigUtils.tsreduce code duplication between 1.x and 2.x implementations:loadRawBiomeConfigFile<T>()- Generic JSON5 config loadingresolveExtendsChainGeneric<T>()- Shared extends chain resolution with optionalincludeConfigPathparameter.jsoncextension (notbiome.jsonc) to avoid Biome 1.x schema validation errors during checkspkg-b/config.jsonc→pkg-a/config.jsonc→baseconfig.jsonc) to verify config inheritance chains work correctlyroot: true/root: false) to verify automatic parent config discovery and merging