Skip to content

Conversation

@adamroyle
Copy link
Contributor

Summary

When parsing cli args, 'mri' returns an array for duplicate args, which causes unexpected results. All current arguments assume single values only. Tailwind v3 works the same way.

Test plan

Updated tests.

@adamroyle adamroyle requested a review from a team as a code owner December 7, 2025 13:24
@coderabbitai
Copy link

coderabbitai bot commented Dec 7, 2025

Walkthrough

The CLI argument parser was modified to collapse multi-valued flag arrays to their last element before handling the default marker \_\_IO_DEFAULT_VALUE\_\_ (which is then converted to -). Two tests were added to verify last-wins behavior for repeated flags: one for repeated --output and one for the alias -o when a dash (-) value is used.

Pre-merge checks

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and clearly summarizes the main change: ensuring only the last value is used when parsing duplicate CLI arguments.
Description check ✅ Passed The description is directly related to the changeset, explaining the problem (mri returns arrays for duplicate args) and the solution (use only the last value), and mentions test updates.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/@tailwindcss-cli/src/utils/args.test.ts (1)

20-34: Duplicate-argument test looks good; consider adding a '-' case

This test correctly locks in the “last value wins” behavior for repeated flags and matches the new normalization logic in args().

Given the special handling of '-' via the __IO_DEFAULT_VALUE__ sentinel, consider adding a companion test where the final duplicate is '-' to protect that behavior:

it('should respect "-" when it is the last duplicate value', () => {
  expect(
    args(
      {
        '--output': { type: 'string', description: 'Output file' },
      },
      ['--output', 'output.css', '--output', '-'],
    ),
  ).toMatchInlineSnapshot(`
    {
      "--output": "-",
      "_": [],
    }
  `)
})

This would catch regressions where '-' stops being normalized correctly in the duplicate-flag scenario.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1ee7bb9 and 018a16c.

📒 Files selected for processing (2)
  • packages/@tailwindcss-cli/src/utils/args.test.ts (1 hunks)
  • packages/@tailwindcss-cli/src/utils/args.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/@tailwindcss-cli/src/utils/args.test.ts (1)
packages/@tailwindcss-cli/src/utils/args.ts (1)
  • args (70-116)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/@tailwindcss-cli/src/utils/args.ts (1)

79-91: Excellent fix! The ordering now correctly handles the sentinel conversion.

The refactored logic properly addresses the issue from the past review comment:

  1. Arrays are collapsed to their last element first (lines 82-84)
  2. The sentinel __IO_DEFAULT_VALUE__ is converted to - afterward (lines 86-88)

This ensures that when - is the last duplicate value (e.g., --output output.css --output -), it's correctly preserved as - in the final result.

Optional: Consider a non-mutating approach for array access.

While .pop() works correctly here, it mutates the array. A more idiomatic approach would be:

-    if (key !== '_' && Array.isArray(value)) {
-      value = value.pop()
-    }
+    if (key !== '_' && Array.isArray(value)) {
+      value = value[value.length - 1]
+    }

This is purely stylistic since the mutation doesn't affect the final result (we reassign parsed[key] anyway). The non-mutating approach is slightly clearer about intent: "get the last element" vs "remove and get the last element."

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 985946e and 0abd119.

📒 Files selected for processing (2)
  • packages/@tailwindcss-cli/src/utils/args.test.ts (1 hunks)
  • packages/@tailwindcss-cli/src/utils/args.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/@tailwindcss-cli/src/utils/args.test.ts (1)
packages/@tailwindcss-cli/src/utils/args.ts (1)
  • args (70-122)
🔇 Additional comments (2)
packages/@tailwindcss-cli/src/utils/args.test.ts (2)

20-34: LGTM! Good test coverage for duplicate argument handling.

This test correctly verifies that when the same flag is provided multiple times, the last value wins.


36-50: Excellent test for the sentinel value edge case.

This test properly verifies the fix for the ordering issue mentioned in the past review comment. When - (which becomes __IO_DEFAULT_VALUE__ internally) appears as the last duplicate value, it should be correctly converted back to - after the array is collapsed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
CHANGELOG.md (1)

25-25: Clarify “duplicate CLI arguments” behavior (spell out last‑wins).

Explicitly stating “last value wins” reduces ambiguity and helps users understand what changed at a glance.

- - Correctly handle duplicate CLI arguments ([#19416](https://github.com/tailwindlabs/tailwindcss/pull/19416))
+ - Duplicate CLI arguments now use the last value (last‑wins), matching v3 ([#19416](https://github.com/tailwindlabs/tailwindcss/pull/19416))
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between faf5a6e and e55f639.

📒 Files selected for processing (1)
  • CHANGELOG.md (1 hunks)

@thecrypticace thecrypticace merged commit 563a016 into tailwindlabs:main Dec 7, 2025
7 checks passed
@thecrypticace
Copy link
Contributor

Thanks!

RatStar811

This comment was marked as spam.

@adamroyle adamroyle deleted the fix/cli-args branch December 11, 2025 06:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants