Skip to content

Refactor stylelint config detection in lint-style.js#79280

Open
USERSATOSHI wants to merge 6 commits into
WordPress:trunkfrom
USERSATOSHI:refactor/stylelint-cosmiconfig-detection
Open

Refactor stylelint config detection in lint-style.js#79280
USERSATOSHI wants to merge 6 commits into
WordPress:trunkfrom
USERSATOSHI:refactor/stylelint-cosmiconfig-detection

Conversation

@USERSATOSHI

@USERSATOSHI USERSATOSHI commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

What?

Closes #30842
Related #79226 (comment)

Extract stylelint configuration detection into a self-documenting hasResolvableConfig() utility function in packages/scripts/scripts/lint-style.js, using stylelint's own resolveConfig() API and checking err.code instead of the error message string.

Why?

The inline .then().catch() chain was harder to read and relied on matching the error message text, which could break if stylelint changes its wording. The extracted function is self-documenting, and checking err.code === 78 (stylelint's EXIT_CODE_INVALID_CONFIG) is the stable, intended API for classification.

How?

  1. Extract the stylelint resolveConfig logic into an async hasResolvableConfig() function with try/catch.
  2. Switch from err.message.includes('No configuration provided') to err.code === CONFIG_NOT_FOUND_CODE (value 78, stylelint's EXIT_CODE_INVALID_CONFIG).
  3. Keep main() async (already was).

Testing Instructions

  1. Run npm install to link the new dependency.
  2. Run npm run lint:css, verify same lint results as on trunk (no new warnings/errors).
  3. Temporarily add a .stylelintrc.ts to the project root, it should be auto-detected without code changes.
  4. Remove all stylelint config files, the bundled default config should be injected.

Use of AI Tools

No

@USERSATOSHI

Copy link
Copy Markdown
Contributor Author

cc: @manzoorwanijk @aduth , I did create this but if we use v7.0.0 of cosmiconfig based on lint error we need to maintain .mjs and .mts manually via searchPlaces v9.0.0 handle this in the async version

@aduth

aduth commented Jun 17, 2026

Copy link
Copy Markdown
Member

Is it an option to use require( 'stylelint' ).resolveConfig for this? So we defer to whatever internal mechanism (and whatever version of Cosmiconfig) they use for resolving the config. Not sure if that resolves the issue you're seeing. Alternatively, should we bump cosmiconfig project-wide?

@USERSATOSHI USERSATOSHI marked this pull request as ready for review June 18, 2026 07:26
@github-actions

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @musharafmaqbool.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: musharafmaqbool.

Co-authored-by: USERSATOSHI <tusharbharti@git.wordpress.org>
Co-authored-by: aduth <aduth@git.wordpress.org>
Co-authored-by: gziolo <gziolo@git.wordpress.org>
Co-authored-by: ockham <bernhard-reiter@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@USERSATOSHI

Copy link
Copy Markdown
Contributor Author

Hi @aduth, resolveConfig does work and I have updated the code to use it instead.

cc: @manzoorwanijk

@aduth aduth left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good 👍 I left a few comments

Comment thread package-lock.json

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't expect any lockfile changes in this pull request. Can we reset these? Might be leftovers from previous iterations using cosmiconfig.

Comment thread packages/scripts/scripts/lint-style.js Outdated
Comment on lines +35 to +48
const hasLintConfig =
hasArgInCLI( '--config' ) ||
( await stylelint
.resolveConfig( 'index.css', { cwd: process.cwd() } )
.then( ( config ) => config !== undefined )
.catch( ( err ) => {
// "No configuration provided" means no user config found;
// inject the bundled default.
// Other errors mean the config exists but is broken; let stylelint report them during linting.
if ( err.message?.includes( 'No configuration provided' ) ) {
return false;
}
return true;
} ) );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be cleaner to extract a utility function for this which would also be a bit more self-documenting as well.

Resulting code here looking more like:

Suggested change
const hasLintConfig =
hasArgInCLI( '--config' ) ||
( await stylelint
.resolveConfig( 'index.css', { cwd: process.cwd() } )
.then( ( config ) => config !== undefined )
.catch( ( err ) => {
// "No configuration provided" means no user config found;
// inject the bundled default.
// Other errors mean the config exists but is broken; let stylelint report them during linting.
if ( err.message?.includes( 'No configuration provided' ) ) {
return false;
}
return true;
} ) );
const hasLintConfig = hasArgInCLI( '--config' ) || await hasResolvableConfig();

Comment thread packages/scripts/scripts/lint-style.js Outdated
Comment on lines +41 to +44
// "No configuration provided" means no user config found;
// inject the bundled default.
// Other errors mean the config exists but is broken; let stylelint report them during linting.
if ( err.message?.includes( 'No configuration provided' ) ) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I was looking at this previously, I recall something about Stylelint providing an error.code that we could use, so that we don't have to look at the error message (which could change in future versions, for example). Could you check if that's available for us to use to make this more stable with future updates?

);

process.exit( result.status );
async function main() {

@aduth aduth Jun 18, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I right in thinking we should be able to safely use top-level await (added in Node.js v14.8.0) and avoid having to create a function wrapper for the logic?

If linters aren't happy with it, maybe we need to update linters. But my expectation is we should be able to use it in Node.js code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't top level await work only on esm file? since file is using require to import, nodejs will treat it as cjs file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think you're right. I overlooked that we're not using native ESM in this package. Curious if the CommonJS transpilation would support that, but not worth dwelling too much over.

@aduth aduth added [Type] Enhancement A suggestion for improvement. [Tool] WP Scripts /packages/scripts labels Jun 18, 2026
@USERSATOSHI USERSATOSHI requested a review from aduth June 19, 2026 06:44
@USERSATOSHI USERSATOSHI changed the title refactor: use cosmiconfig for stylint config resolution Refactor stylelint config detection in lint-style.js Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Tool] WP Scripts /packages/scripts [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scripts: Try using cosmiconf for locating tool configs

2 participants