Skip to content

feat: builtin options with plugin system - #155

Merged
kazupon merged 8 commits into
mainfrom
feat/plugin-system-1
May 31, 2025
Merged

kazupon merged 8 commits into
mainfrom
feat/plugin-system-1

Conversation

@kazupon

@kazupon kazupon commented May 31, 2025

Copy link
Copy Markdown
Owner

Description

This PR is the first step toward adopting a plugin architecture for gunshi.
Built-in options such as --help and --version will be implemented as plugins.
Taking #69 and #70 into consideration, I will make it possible to opt out of these options via cli options in the near future.

Linked Issues

#2

Additional context

Summary by CodeRabbit

  • New Features
    • Introduced a plugin system, allowing for extensible CLI functionality through plugins.
    • Added initial plugins for global options, completion, and dry-run support (with placeholder implementations for completion and dry-run).
  • Improvements
    • Enhanced CLI argument handling to support plugin-driven global options.
  • Chores
    • Updated configuration to temporarily ignore new plugin files in project checks.

@coderabbitai

coderabbitai Bot commented May 31, 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 19 minutes and 37 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 60da394 and 7305b4b.

📒 Files selected for processing (4)
  • knip.config.ts (1 hunks)
  • packages/gunshi/src/plugin.test.ts (1 hunks)
  • packages/gunshi/src/plugin.ts (1 hunks)
  • packages/gunshi/src/plugins/globals.ts (1 hunks)

Walkthrough

A plugin system was introduced to the Gunshi CLI. A new PluginContext class manages global options, and plugins can now register these options. The CLI flow was updated to initialize and apply plugins before argument parsing. Several new plugin modules were added, and type exports were adjusted to support the new architecture.

Changes

File(s) Change Summary
packages/gunshi/src/cli.ts Refactored CLI to initialize/apply plugins, manage PluginContext, and merge plugin-driven global options.
packages/gunshi/src/plugin.ts Introduced Plugin type and PluginContext class for plugin management and global option registration.
packages/gunshi/src/plugins/completion.ts,
dryrun.ts
Added placeholder plugin modules for completion and dry-run functionality.
packages/gunshi/src/plugins/globals.ts Added plugin to register built-in global options via PluginContext.
packages/gunshi/src/plugins/index.ts Aggregated plugins into an exported array for application in the CLI.
packages/gunshi/src/types.ts Exported Awaitable<T> type for use in plugin definitions.
knip.config.ts Temporarily added new plugin files to the Knip ignore list.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant PluginContext
    participant Plugins
    participant CommandParser

    User->>CLI: Run CLI with argv
    CLI->>PluginContext: Create instance
    CLI->>Plugins: Apply each plugin to PluginContext
    Plugins->>PluginContext: Register global options
    CLI->>CommandParser: Parse argv with PluginContext.globalOptions
    CommandParser->>CLI: Return parsed arguments
    CLI->>CLI: Execute command with merged options
Loading

Poem

In Gunshi’s warren, plugins hop in line,
With contexts and options, their powers combine.
Globals now register with a twitch of the nose,
Awaitable types, like carrots, they chose.
New modules appear, the system expands—
A rabbit’s delight in these clever new plans! 🐇✨

✨ 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.

@pkg-pr-new

pkg-pr-new Bot commented May 31, 2025

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/gunshi@155

commit: 7305b4b

@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: 3

🧹 Nitpick comments (5)
packages/gunshi/src/plugins/dryrun.ts (1)

11-15: Plugin structure looks good, placeholder implementation noted.

The plugin follows the correct Plugin type signature and integrates properly with the plugin system. The placeholder implementation is understandable for initial plugin architecture setup.

Note: The pipeline warning about the unused file is expected since this is a placeholder plugin not yet integrated into the CLI flow. Would you like me to help implement the dry-run functionality in a future iteration?

packages/gunshi/src/plugins/completion.ts (1)

11-15: Consistent plugin structure established.

The completion plugin follows the same correct pattern as other plugins in the system. The placeholder implementation aligns with the incremental approach to building the plugin architecture.

Like the dry-run plugin, this is appropriately flagged as unused since it's a placeholder. Would you like assistance implementing shell completion functionality in the future?

packages/gunshi/src/plugin.ts (2)

32-34: Remove the unnecessary constructor.

The constructor is currently empty with only a TODO comment. Since no initialization logic is present, it can be removed entirely.

Apply this diff to remove the unnecessary constructor:

-  constructor() {
-    // TODO:
-  }
🧰 Tools
🪛 Biome (1.9.4)

[error] 32-34: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)


48-49: Complete the plugin context hooks implementation.

The TODO comment indicates that additional hooks are planned but not yet implemented. Consider defining the interface for these hooks to establish the plugin architecture more completely.

Would you like me to help design the additional plugin hooks interface or open an issue to track this implementation?

packages/gunshi/src/cli.ts (1)

39-40: Consider making the plugin list configurable.

The current implementation hardcodes the builtins plugin. Consider making the plugin list configurable to support future extensibility.

Consider this approach for better extensibility:

+  const plugins = cliOptions.plugins || [builtins]
-  for (const plugin of [builtins]) {
+  for (const plugin of plugins) {
     await plugin()(pluginContext)
   }

This would require updating the CliOptions type to include an optional plugins field.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f72a752 and 870c60b.

📒 Files selected for processing (6)
  • packages/gunshi/src/cli.ts (5 hunks)
  • packages/gunshi/src/plugin.ts (1 hunks)
  • packages/gunshi/src/plugins/builtins.ts (1 hunks)
  • packages/gunshi/src/plugins/completion.ts (1 hunks)
  • packages/gunshi/src/plugins/dryrun.ts (1 hunks)
  • packages/gunshi/src/types.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
packages/gunshi/src/plugins/dryrun.ts (1)
packages/gunshi/src/plugin.ts (1)
  • Plugin (24-24)
packages/gunshi/src/plugins/completion.ts (1)
packages/gunshi/src/plugin.ts (1)
  • Plugin (24-24)
packages/gunshi/src/plugins/builtins.ts (2)
packages/gunshi/src/plugin.ts (1)
  • Plugin (24-24)
packages/gunshi/src/constants.ts (1)
  • COMMON_ARGS (37-48)
packages/gunshi/src/plugin.ts (1)
packages/gunshi/src/types.ts (1)
  • Awaitable (10-10)
🪛 GitHub Actions: CI
packages/gunshi/src/plugins/dryrun.ts

[warning] 1-1: Unused file detected by knip.

packages/gunshi/src/plugins/completion.ts

[warning] 1-1: Unused file detected by knip.

🪛 Biome (1.9.4)
packages/gunshi/src/plugin.ts

[error] 32-34: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

🔇 Additional comments (4)
packages/gunshi/src/types.ts (1)

10-10: Essential type export for plugin system.

Exporting Awaitable<T> enables the plugin system to use this type definition across modules, which is necessary for the Plugin type definition in packages/gunshi/src/plugin.ts.

packages/gunshi/src/plugins/builtins.ts (1)

13-19: Excellent implementation of plugin architecture objectives.

This plugin successfully converts built-in options (--help and --version from COMMON_ARGS) into the new plugin system, directly fulfilling the PR's main objective. The implementation correctly:

  • Follows the established Plugin type pattern
  • Iterates through all common arguments using Object.entries
  • Registers each as a global option via ctx.addGlobalOption
  • Enables modular management of built-in options

This change enables the future work mentioned in the PR description where users can opt out of built-in options through CLI settings.

packages/gunshi/src/plugin.ts (1)

40-42: Good defensive programming practice.

Creating a new Map instance in the getter prevents external code from mutating the internal state, which is excellent for maintaining data integrity.

packages/gunshi/src/cli.ts (1)

61-61: Good variable renaming for clarity.

Renaming ctx to commandContext improves code readability and reduces potential confusion with the new PluginContext.

Also applies to: 75-75, 81-81, 87-87, 95-95, 99-99

Comment thread packages/gunshi/src/plugin.ts
Comment thread packages/gunshi/src/cli.ts Outdated
Comment thread packages/gunshi/src/cli.ts
kazupon and others added 2 commits May 31, 2025 14:04
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@cloudflare-workers-and-pages

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

Copy link
Copy Markdown

Deploying gunshi with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7305b4b
Status: ✅  Deploy successful!
Preview URL: https://92d672f7.gunshi.pages.dev
Branch Preview URL: https://feat-plugin-system-1.gunshi.pages.dev

View logs

@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: 1

🧹 Nitpick comments (1)
packages/gunshi/src/plugins/globals.ts (1)

13-17: Consider adding error handling for robustness.

The function correctly implements the plugin pattern for registering global options. However, it doesn't handle potential errors from ctx.addGlobalOption(), which can throw errors for invalid option names or duplicate registrations.

While this might be acceptable for built-in options that should be well-defined, consider adding basic error handling for better robustness:

export default function globals(ctx: PluginContext) {
  for (const [name, schema] of Object.entries(COMMON_ARGS)) {
-    ctx.addGlobalOption(name, schema)
+    try {
+      ctx.addGlobalOption(name, schema)
+    } catch (error) {
+      throw new Error(`Failed to register global option '${name}': ${error.message}`)
+    }
  }
}

Alternatively, if you prefer to keep it simple since these are built-in options, the current implementation is acceptable.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 769f159 and 60da394.

⛔ Files ignored due to path filters (2)
  • packages/gunshi/src/__snapshots__/cli.test.ts.snap is excluded by !**/*.snap
  • packages/gunshi/src/__snapshots__/generator.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (6)
  • knip.config.ts (1 hunks)
  • packages/gunshi/src/cli.ts (5 hunks)
  • packages/gunshi/src/plugins/completion.ts (1 hunks)
  • packages/gunshi/src/plugins/dryrun.ts (1 hunks)
  • packages/gunshi/src/plugins/globals.ts (1 hunks)
  • packages/gunshi/src/plugins/index.ts (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • knip.config.ts
  • packages/gunshi/src/plugins/index.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/gunshi/src/plugins/completion.ts
  • packages/gunshi/src/plugins/dryrun.ts
  • packages/gunshi/src/cli.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/gunshi/src/plugins/globals.ts (2)
packages/gunshi/src/plugin.ts (1)
  • PluginContext (29-55)
packages/gunshi/src/constants.ts (1)
  • COMMON_ARGS (37-48)
🪛 GitHub Check: Spell check with Typos
packages/gunshi/src/plugins/globals.ts

[warning] 11-11:
"globa" should be "global".

⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Type Checking on Node.js 20
  • GitHub Check: Build on Node.js 20
  • GitHub Check: Lint on Node.js 20
  • GitHub Check: Spell check with Typos
  • GitHub Check: release
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (1)
packages/gunshi/src/plugins/globals.ts (1)

6-17: LGTM! Clean plugin implementation.

The overall design effectively converts built-in options into a plugin architecture. The function cleanly separates global options registration from the main CLI logic and follows the established plugin pattern. The integration with COMMON_ARGS and PluginContext is well-structured.

🧰 Tools
🪛 GitHub Check: Spell check with Typos

[warning] 11-11:
"globa" should be "global".

Comment thread packages/gunshi/src/plugins/globals.ts
@kazupon kazupon added the feature Includes new features label May 31, 2025
@kazupon
kazupon merged commit ac60aa5 into main May 31, 2025
@kazupon
kazupon deleted the feat/plugin-system-1 branch May 31, 2025 05:46
@coderabbitai coderabbitai Bot mentioned this pull request Aug 12, 2025
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.

1 participant