Skip to content

[filename-case] Allow ignoring a directory segment without also skipping the filename check #3581

Description

@TitikshaBansal

Real-world use case

This issue came out of a real GitLab project. Full context and the exact reproduction discussion here: gitlab-org/.../contributors-gitlab-com#556.

Short version: the project follows the Rails/Vite convention of putting Vue components under app/javascript/…. Since eslint-plugin-unicorn v65 the filename-case rule started validating directory segments too, so the lowercase app folder began failing PascalCase enforcement. The project shipped checkDirectories: false as a workaround (MR !2348), but that also disables directory casing checks everywhere else — the maintainer flagged this as unideal and asked whether a directory-only skip is possible. Investigation confirmed the current API can't express it, hence this issue.

Problem

The ignore option in unicorn/filename-case is a full early-return: if any path segment matches an ignore regex, both the directory-name check and the filename check are skipped for that file.

This makes it impossible to express the following (fairly common) use case: "validate PascalCase on all .vue files under app/javascript/, but don't complain that the app directory itself is lowercase."

The app/ folder name is a Rails / Vite convention and can't be renamed. Since v65, filename-case also validates directory names, so the only way to silence the false positive today is checkDirectories: false — which disables directory casing enforcement everywhere, not just for the app segment.

Reproduction

eslint.config.js:

{
  files: ['app/javascript/**/*.vue'],
  rules: {
    'unicorn/filename-case': ['error', {
      cases: { pascalCase: true },
      checkDirectories: true,
      ignore: [/^app$/],
    }],
  },
}

Create app/javascript/pages/badly-named.vue. Expected: rule flags the kebab-case filename. Actual: rule passes silently, because pathSegments.some(segment => ignore.some(re => re.test(segment))) matches on the app segment and returns before the filename is validated.

Relevant source (rules/filename-case.js):

if (pathSegments.some(segment => ignore.some(regexp => regexp.test(segment)))) {
    return;  // skips directory AND filename checks
}
if (isCheckDirectories) { /* ... */ }

Proposal

Introduce a way to exempt directory segments from casing enforcement without also skipping the filename check on files inside them. Two possible shapes:

Option A — new ignoreDirectories option.

'unicorn/filename-case': ['error', {
  checkDirectories: true,
  ignoreDirectories: [/^app$/],  // only skips the directory segment check
  ignore: [/* still a full-rule bypass, unchanged */],
}]

Backwards compatible; ignore semantics preserved.

Option B — change ignore to skip only the directory check when checkDirectories: true.

Cleaner API but a breaking change. Users relying on ignore as a whole-file bypass (per #1406's original intent) would need to migrate.

Option A seems safer.

Related

Happy to send a PR if the maintainers are open to Option A.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions