Skip to content

--ignore-pattern comma-split conflicts with gitignore brace expansion syntax #1496

Closed as not planned
unifiedjs/unified-args
#33

Description

@luo2430

Initial checklist

Thanks for this great tool! I ran into an issue with --ignore-pattern and wanted to share both the problem and two possible approaches to fix it.

Problem

--ignore-pattern values are parsed through commaParse (comma-separated-tokens), which splits on commas. This makes it impossible to use gitignore brace expansion like {a,b} in patterns.

Reproduction

remark . --ignore-pattern "**/{src,dist}/examples/**"

Expected: ignores src/examples/ and dist/examples/ under all directories.

Actual: nothing is ignored, because commaParse splits the value into two invalid patterns:

"**/{src"           ← broken
"dist}/examples/**" ← broken

Current solutions

Root cause

lib/parse-argv.js line 187-189:

const ignorePattern =
    parseIfString(joinIfArray(undefinedIfBoolean(config['ignore-pattern']))) ||
    []

The parseIfString → commaParse roundtrip exists to support --ignore-pattern "a,b" syntax. But --ignore-pattern already supports repeated flags:

--ignore-pattern a --ignore-pattern b  # already works

The comma-split is redundant and actively breaks valid gitignore syntax.

Two possible fixes

Fix A: unified-args (upstream)

Change one line in lib/parse-argv.js:

const ignorePattern = toArray(undefinedIfBoolean(config['ignore-pattern'])) || []

toArray is already in the file. Single values → [value], repeated flags → [value1, value2], no comma split. This fixes it at the root for all downstream CLI tools (remark-cli, retext-cli, rehype-cli). But it's technically breaking for anyone currently relying on --ignore-pattern "a,b" semantics.

Fix B: remark-cli (downstream workaround)

Pre-expand brace patterns in cli.js before handing off to unified-args:

// See remarkjs/remark for the full implementation
// --ignore-pattern "**/{a,b}/**"
//   → expands to:
// --ignore-pattern "**/a/**" --ignore-pattern "**/b/**"

No breaking change, no dependency on upstream. But only fixes remark-cli, not other tools that use unified-args.

Proposed solutions

I prefer Fix A:

  1. Fixes the root cause, not the symptom — the parser shouldn't treat commas as delimiters in values where commas are valid gitignore syntax.

  2. The impact is minimal — --ignore-pattern a --ignore-pattern b is already the established idiom (ESLint, Prettier, etc.), and anyone who happens to use the comma form would get a clean break rather than silently broken brace expansion.

  3. Only unified-args needs to change; otherwise every downstream CLI has to carry its own workaround.

Activity

  1. added
    👋 phase/newPost is being triaged automatically
    🤞 phase/openPost is being triaged manually
    and removed
    👋 phase/newPost is being triaged automatically
    on Jul 26, 2026
  2. wooorm commented on Sep 26, 2026

    @wooorm
    Member

    Yes, this is an external problem, unified-args should have this, as you say. I’ll close this here as this does not need changes here

  3. github-actions commented on Sep 26, 2026

    @github-actions
  4. added
    👎 phase/noPost cannot or will not be acted on
    and removed
    🤞 phase/openPost is being triaged manually
    on Sep 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    👀 no/externalThis makes more sense somewhere else👎 phase/noPost cannot or will not be acted on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions