Skip to content

feat: support camel to kebab style arguments - #138

Merged
kazupon merged 6 commits into
mainfrom
feat/kebab
May 26, 2025
Merged

feat: support camel to kebab style arguments#138
kazupon merged 6 commits into
mainfrom
feat/kebab

Conversation

@kazupon

@kazupon kazupon commented May 26, 2025

Copy link
Copy Markdown
Owner

Description

Linked Issues

close #136
kazupon/args-tokens#99

Additional context

Summary by CodeRabbit

  • Dependency Updates
    • Upgraded dependencies including args-tokens, @vitest/eslint-plugin, eslint-import-resolver-typescript, knip, tsdown, and vitepress-plugin-llms.
    • Downgraded gunshi019 from 0.24.0 to 0.19.0 and added it to ignore list in configuration.
  • Features & Enhancements
    • Introduced toKebab flag to enable conversion of argument names to kebab-case.
    • Added utility function for converting camelCase to kebab-case.
    • Updated command context to include toKebab property.
  • Tests
    • Added tests to verify correct rendering of command arguments with kebab-case formatting, both per-argument and globally.
  • Other Changes
    • Modified command definitions and argument handling to support optional kebab-case formatting.

@coderabbitai

coderabbitai Bot commented May 26, 2025

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@kazupon has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 16 minutes and 44 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 0cb588f and e970a04.

📒 Files selected for processing (3)
  • src/definition.ts (2 hunks)
  • src/renderer/usage.ts (4 hunks)
  • src/types.ts (2 hunks)

Walkthrough

The changes implement kebab-case conversion for command-line argument names, update usage rendering to reflect this, introduce a utility function for case conversion, modify tests to verify kebab-case output, update dependency versions, and alter CLI argument parsing to support short option grouping and kebab-case formatting.

Changes

File(s) Change Summary
.github/renovate.json Added "gunshi019" to ignoreDeps array to prevent Renovate from updating this dependency.
package.json Updated several dependency versions; downgraded gunshi019.
src/cli.ts Changed argument parsing to use shortGrouping: true and added toKebab parameter.
src/utils.ts Added kebabnize function to convert camelCase strings to kebab-case.
src/renderer/usage.ts Integrated kebabnize for kebab-case argument display; updated usage rendering logic accordingly.
src/renderer.test.ts Added tests for kebab-case argument rendering; updated command map typing and suppressed ESLint.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant UsageRenderer
    participant Utils

    User->>CLI: Provide command-line arguments
    CLI->>CLI: Parse arguments (shortGrouping: true)
    CLI->>UsageRenderer: Request usage/help output
    UsageRenderer->>Utils: kebabnize argument names (if toKebab)
    Utils-->>UsageRenderer: Return kebab-case names
    UsageRenderer-->>CLI: Rendered usage/help output
    CLI-->>User: Display usage/help
Loading

Poem

🥕
A hop and a skip, now kebab-case is here,
With dashes and hyphens, the output is clear.
Arguments transformed, the help text refined,
Dependencies updated, all neatly aligned.
The rabbit approves—what a hoppy new year!
🐇

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented May 26, 2025

Copy link
Copy Markdown

Deploying gunshi with  Cloudflare Pages  Cloudflare Pages

Latest commit: e970a04
Status: ✅  Deploy successful!
Preview URL: https://ad1f58cd.gunshi.pages.dev
Branch Preview URL: https://feat-kebab.gunshi.pages.dev

View logs

@kazupon kazupon added the feature Includes new features label May 26, 2025
@pkg-pr-new

pkg-pr-new Bot commented May 26, 2025

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/kazupon/gunshi@138

commit: e970a04

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (2)
src/renderer.test.ts (1)

55-56: Consider using a union type instead of any for better type safety.

While using any works for test purposes, you could maintain better type safety by defining a union type for the different argument structures used in your tests.

-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-const COMMANDS = new Map<string, Command<any> | LazyCommand<any>>()
+type TestArgs = Args & {
+  foo?: { type: 'string'; short?: string; description?: string };
+  bar?: { type: 'boolean'; short?: string; description?: string };
+  // Add other test argument types as needed
+};
+const COMMANDS = new Map<string, Command<TestArgs> | LazyCommand<TestArgs>>()
src/renderer/usage.ts (1)

273-291: Comprehensive kebab-case support across all option types!

The implementation correctly handles parameter placeholders and negatable options. The consistent use of the toKebab flag ensures backward compatibility.

Consider making the inline comments slightly more descriptive:

-      // Use kebab-case for parameter placeholders too if toKebab is true
+      // Convert parameter placeholders to kebab-case format when toKebab is enabled
       const displayName = schema.toKebab ? kebabnize(name) : name
-      // Use kebab-case for negated options too if toKebab is true
+      // Convert negatable option names to kebab-case format when toKebab is enabled
       const displayName = schema.toKebab ? kebabnize(name) : name
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c4386a and 4650cb6.

⛔ Files ignored due to path filters (2)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • src/__snapshots__/renderer.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (6)
  • .github/renovate.json (1 hunks)
  • package.json (3 hunks)
  • src/cli.ts (1 hunks)
  • src/renderer.test.ts (2 hunks)
  • src/renderer/usage.ts (3 hunks)
  • src/utils.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (9)
.github/renovate.json (1)

5-5: LGTM! Proper dependency management configuration.

The addition of gunshi019 to the ignoreDeps array correctly prevents Renovate from automatically upgrading this dependency, which aligns with the intentional downgrade in package.json from version 0.24.0 to 0.19.0.

src/cli.ts (1)

49-49: LGTM! Improves CLI option parsing behavior.

The change from optionGrouping to shortGrouping: true enables proper short option grouping (e.g., -abc instead of -a -b -c), which is a standard CLI convention that enhances user experience and complements the new kebab-case argument formatting feature.

src/utils.ts (1)

76-84: LGTM! Well-implemented kebab-case conversion utility.

The kebabnize function correctly converts camelCase strings to kebab-case using an appropriate regex pattern. The implementation handles the transformation efficiently and includes proper documentation.

Note: The function works well for typical camelCase identifiers like userNameuser-name, but may produce verbose output for strings with consecutive uppercase letters (e.g., someAPIsome-a-p-i). This is acceptable for command-line argument formatting where clarity is preferred.

package.json (3)

140-140: LGTM! Strategic version management for testing purposes.

The downgrade to npm:gunshi@0.19.0 (from 0.24.0) appears intentional, likely for compatibility testing or benchmarking against a previous version. This aligns with the Renovate ignore configuration to prevent automatic upgrades.


123-123: LGTM! Routine dependency maintenance updates.

These patch and minor version updates for development dependencies are appropriate and should provide bug fixes and improvements without breaking changes:

  • @vitest/eslint-plugin: ^1.2.0^1.2.1 (patch update)
  • eslint-import-resolver-typescript: ^4.3.5^4.4.1 (minor update)
  • knip: ^5.57.2^5.58.0 (minor update)
  • tsdown: ^0.12.2^0.12.3 (patch update)
  • vitepress-plugin-llms: ^1.3.3^1.3.4 (patch update)

Also applies to: 128-128, 143-143, 150-150, 157-157


114-114:

Details

✅ Verification successful

Verify the args-tokens upgrade supports the new kebab-case feature.

The upgrade from ^0.18.0 to ^0.19.0 appears to support the new shortGrouping option used in src/cli.ts. This is a strategic update that enables the kebab-case argument formatting feature.


🏁 Script executed:

#!/bin/bash
# Description: Verify that args-tokens v0.19.0 supports shortGrouping option
# Expected: Confirmation that the API supports the new option used in cli.ts

# Check the args-tokens package information and changelog
curl -s https://registry.npmjs.org/args-tokens/0.19.0 | jq '.version, .description'

# Search for recent commits or releases mentioning shortGrouping
curl -s "https://api.github.com/search/repositories?q=args-tokens+user:kazupon" | jq '.items[0].html_url' | xargs -I {} echo "Check repository: {}"

Length of output: 369


🏁 Script executed:

#!/bin/bash
# Search for “shortGrouping” in args-tokens v0.19.0 docs

echo ">> Checking README.md for shortGrouping"
curl -s https://raw.githubusercontent.com/kazupon/args-tokens/v0.19.0/README.md \
  | grep -C2 shortGrouping || echo "No match in README.md"

echo
echo ">> Checking CHANGELOG.md for shortGrouping"
curl -s https://raw.githubusercontent.com/kazupon/args-tokens/v0.19.0/CHANGELOG.md \
  | grep -C2 shortGrouping || echo "No match in CHANGELOG.md"

Length of output: 520


🏁 Script executed:

#!/bin/bash
# Clone args-tokens v0.19.0 and search for shortGrouping in source
git clone --depth 1 --branch v0.19.0 https://github.com/kazupon/args-tokens.git /tmp/args-tokens
echo ">> Searching for shortGrouping in code"
grep -R "shortGrouping" /tmp/args-tokens || echo "No shortGrouping found in code"

Length of output: 1226


Approve dependency updates; args-tokens v0.19.0 includes shortGrouping support

Verified that the shortGrouping option is defined and exercised in args-tokens v0.19.0 (see src/resolver.ts and tests), so the upgrade properly enables the kebab-case formatting feature in src/cli.ts. All other dependency bumps and the intentional gunshi019 downgrade look safe—approving these changes.

src/renderer.test.ts (1)

505-558: Well-structured test case for kebab-case functionality!

The test comprehensively covers various scenarios including negatable options and required arguments with the toKebab property. The examples clearly demonstrate the expected kebab-case output format.

src/renderer/usage.ts (2)

10-10: LGTM!

The import follows the existing pattern and integrates cleanly with other utility imports.


258-265: Clean implementation of kebab-case transformation!

The conditional transformation based on schema.toKebab is well-implemented and maintains backward compatibility. The comment clearly explains the purpose.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/definition.ts (1)

2-2: Fix the typo in the comment.

The word "deifinition" should be "definition".

- * The entry for command deifinition.
+ * The entry for command definition.
src/renderer.test.ts (1)

55-56: Consider a more type-safe approach instead of using any.

While the ESLint disable comment acknowledges the issue, using any reduces type safety. Consider creating a more specific union type or using generics to maintain type safety while accommodating the test requirements.

-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-const COMMANDS = new Map<string, Command<any> | LazyCommand<any>>()
+const COMMANDS = new Map<string, Command<Args> | LazyCommand<Args>>()

If this change causes type issues, consider creating a test-specific interface that extends the base types.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4650cb6 and 50eaf70.

⛔ Files ignored due to path filters (1)
  • src/__snapshots__/renderer.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (6)
  • src/context.ts (1 hunks)
  • src/definition.test.ts (2 hunks)
  • src/definition.ts (1 hunks)
  • src/renderer.test.ts (2 hunks)
  • src/renderer/usage.ts (4 hunks)
  • src/types.ts (2 hunks)
🧰 Additional context used
🪛 GitHub Check: Spell check with Typos
src/types.ts

[warning] 292-292:
"conext" should be "context" or "connect" or "connects".

🪛 GitHub Actions: Typos
src/types.ts

[error] 292-292: conext should be context, connect, connects

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (9)
src/context.ts (1)

221-221: LGTM!

The toKebab property is correctly propagated from the command to the context, following the same pattern as other properties.

src/definition.test.ts (1)

29-29: Good test coverage for the new feature!

The test properly verifies that the toKebab property propagates correctly through lazy command definitions.

Also applies to: 48-48

src/definition.ts (1)

47-47: LGTM!

The toKebab property is correctly propagated to the lazy command loader, following the established pattern.

src/renderer.test.ts (2)

505-558: Comprehensive test coverage for individual argument kebab-case conversion.

The test effectively covers various argument types (string, boolean with negatable, number, required) with individual toKebab flags. The test data includes proper examples showing the expected kebab-case output format.


560-610: Good test coverage for command-level kebab-case conversion.

This test validates that the command-level toKebab property works correctly, with one argument (bazQux) explicitly setting toKebab: true to test override behavior. The test demonstrates that command-level settings can be overridden at the argument level.

src/renderer/usage.ts (4)

10-10: Good addition of kebab-case utility import.

The import of kebabnize function provides the necessary utility for case conversion.


257-265: Well-implemented kebab-case conversion in option pair generation.

The function correctly handles kebab-case conversion by checking both the passed toKebab parameter and the schema-level toKebab property. The logic prioritizes schema-level settings, which provides good flexibility.


273-291: Comprehensive kebab-case handling for all option types.

The implementation correctly handles:

  • Option keys with kebab-case conversion
  • Parameter placeholders with consistent case conversion
  • Negatable boolean options with proper --no- prefix handling

The logic ensures consistent kebab-case formatting across all option representations.


359-359: Consistent kebab-case application in negatable option generation.

The update ensures that negatable options also respect the kebab-case formatting when generating help text for negated boolean flags.

Comment thread src/types.ts
Comment on lines +290 to +294
/**
* Whether to convert the camel-case style argument name to kebab-case.
* This conext value is set from {@link Command.toKebab} option.
*/
toKebab?: boolean

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix the typo in the documentation.

The word "conext" on line 292 should be "context".

   /**
    * Whether to convert the camel-case style argument name to kebab-case.
-   * This conext value is set from {@link Command.toKebab} option.
+   * This context value is set from {@link Command.toKebab} option.
    */
   toKebab?: boolean
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Whether to convert the camel-case style argument name to kebab-case.
* This conext value is set from {@link Command.toKebab} option.
*/
toKebab?: boolean
/**
* Whether to convert the camel-case style argument name to kebab-case.
* This context value is set from {@link Command.toKebab} option.
*/
toKebab?: boolean
🧰 Tools
🪛 GitHub Check: Spell check with Typos

[warning] 292-292:
"conext" should be "context" or "connect" or "connects".

🪛 GitHub Actions: Typos

[error] 292-292: conext should be context, connect, connects

🤖 Prompt for AI Agents
In src/types.ts around lines 290 to 294, the documentation comment contains a
typo where "conext" should be "context". Correct the typo by replacing "conext"
with "context" to improve clarity and accuracy of the documentation.

Comment thread src/types.ts
@kazupon
kazupon merged commit 66c5b6f into main May 26, 2025
@kazupon
kazupon deleted the feat/kebab branch May 26, 2025 10:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Includes new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

case conversion

1 participant