Skip to content

fix(lazy-async): resolve command before executing - #322

Merged
kazupon merged 1 commit into
mainfrom
fix/lazy-async
Sep 22, 2025
Merged

fix(lazy-async): resolve command before executing#322
kazupon merged 1 commit into
mainfrom
fix/lazy-async

Conversation

@kazupon

@kazupon kazupon commented Sep 22, 2025

Copy link
Copy Markdown
Owner

Description

Linked Issues

Additional context

Summary by CodeRabbit

  • Refactor
    • Streamlined command execution to resolve lazy-loaded commands earlier, ensuring consistent behavior and decorator application. No changes to CLI usage.
  • Tests
    • Reorganized and expanded test coverage for lazy-loaded commands, including a new scenario for configuration-driven command loading.
    • Added usage and snapshot validations across multiple command cases to improve confidence and prevent regressions.

@kazupon kazupon added the bug Includes new features label Sep 22, 2025
@coderabbitai

coderabbitai Bot commented Sep 22, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Refactors lazy command tests into describe blocks, adds a config-driven lazy-loading test with snapshots. In core CLI, shifts lazy-command resolution from executeCommand to cliCore, constructs context with the resolved command, and simplifies executeCommand to operate only on concrete Command instances.

Changes

Cohort / File(s) Summary
Tests: lazy command suite refactor and expansion
packages/gunshi/src/cli.test.ts
Reorganizes tests under describe('lazy command'); adds "basic" test covering multiple lazy subcommands; introduces "command loading" test validating config-driven lazy loading and usage snapshots.
CLI core: lazy resolution relocation and API change
packages/gunshi/src/cli/core.ts
Moves lazy-command resolution out of executeCommand into cliCore; commandContext now uses the resolved command; executeCommand signature narrowed to Command<G> only and no longer resolves lazily or accepts name. Call sites updated accordingly.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CLI as CLI Core
  participant Resolver as Lazy Resolver
  participant Exec as executeCommand
  Note over CLI: New flow (post-change)
  User->>CLI: invoke CLI with args
  CLI->>Resolver: resolve(command)
  Resolver-->>CLI: resolved Command
  CLI->>Exec: executeCommand(resolvedCmd, ctx, decorators)
  Exec-->>User: result/output
Loading
sequenceDiagram
  autonumber
  actor User
  participant CLI as CLI Core
  participant Exec as executeCommand
  Note over Exec: Old flow (pre-change)
  User->>CLI: invoke CLI with args
  CLI->>Exec: executeCommand(cmdOrLazy, ctx, name, decorators)
  Exec->>Exec: if Lazy → resolve()
  Exec-->>User: result/output
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

A rabbit taps the keys—hop hop!
Lazy commands now flip and pop.
Core resolves, exec runs clean,
Tests line up in tidy scene.
With configs loaded on the fly,
Snapshots wink—approving eye. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "fix(lazy-async): resolve command before executing" is concise and directly describes the primary change in the diff: lazy-command resolution was moved out of executeCommand and performed beforehand (reflected by cliCore computing a resolvedCommand and executeCommand signature changes). It is specific to the implemented fix, readable, and conveys the main intent for a teammate scanning the history.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/lazy-async

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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.

@pkg-pr-new

pkg-pr-new Bot commented Sep 22, 2025

Copy link
Copy Markdown

Open in StackBlitz

@gunshi/bone

npm i https://pkg.pr.new/@gunshi/bone@322

@gunshi/definition

npm i https://pkg.pr.new/@gunshi/definition@322

gunshi

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

@gunshi/plugin

npm i https://pkg.pr.new/@gunshi/plugin@322

@gunshi/plugin-completion

npm i https://pkg.pr.new/@gunshi/plugin-completion@322

@gunshi/plugin-dryrun

npm i https://pkg.pr.new/@gunshi/plugin-dryrun@322

@gunshi/plugin-global

npm i https://pkg.pr.new/@gunshi/plugin-global@322

@gunshi/plugin-i18n

npm i https://pkg.pr.new/@gunshi/plugin-i18n@322

@gunshi/plugin-renderer

npm i https://pkg.pr.new/@gunshi/plugin-renderer@322

@gunshi/resources

npm i https://pkg.pr.new/@gunshi/resources@322

@gunshi/shared

npm i https://pkg.pr.new/@gunshi/shared@322

commit: 140af2f

@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 (1)
packages/gunshi/src/cli.test.ts (1)

374-376: Minor inconsistency in property naming.

Line 374-376 uses options property instead of args property, which is inconsistent with the rest of the codebase pattern. All other commands in the test file use args for command arguments.

Apply this diff to maintain consistency:

-      options: {
+      args: {
         qux: {
           type: 'number',
           short: 'q'
         }
       },
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 00e8e2a and 140af2f.

⛔ Files ignored due to path filters (1)
  • packages/gunshi/src/__snapshots__/cli.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (2)
  • packages/gunshi/src/cli.test.ts (1 hunks)
  • packages/gunshi/src/cli/core.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
packages/gunshi/src/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

packages/gunshi/src/**/*.ts: All source code is in TypeScript with strict mode enabled
Type safety is a core feature - maintain strict TypeScript types throughout

Files:

  • packages/gunshi/src/cli/core.ts
  • packages/gunshi/src/cli.test.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Use ES modules throughout the codebase
Follow existing code style (enforced by ESLint and Prettier)

Files:

  • packages/gunshi/src/cli/core.ts
  • packages/gunshi/src/cli.test.ts
🧠 Learnings (4)
📚 Learning: 2025-07-21T07:12:47.997Z
Learnt from: CR
PR: kazupon/gunshi#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T07:12:47.997Z
Learning: Applies to packages/gunshi/test/**/*.test.ts : Add tests for new features in the corresponding test file

Applied to files:

  • packages/gunshi/src/cli.test.ts
📚 Learning: 2025-07-21T07:12:47.997Z
Learnt from: CR
PR: kazupon/gunshi#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T07:12:47.997Z
Learning: Applies to packages/gunshi/test/**/*.test.ts : Use 'describe' and 'it' blocks for test organization

Applied to files:

  • packages/gunshi/src/cli.test.ts
📚 Learning: 2025-07-21T07:12:47.997Z
Learnt from: CR
PR: kazupon/gunshi#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T07:12:47.997Z
Learning: Applies to packages/gunshi/test/**/*.test.ts : Test files are in 'packages/gunshi/test/' with '.test.ts' extension

Applied to files:

  • packages/gunshi/src/cli.test.ts
📚 Learning: 2025-07-21T07:12:47.997Z
Learnt from: CR
PR: kazupon/gunshi#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T07:12:47.997Z
Learning: Applies to packages/gunshi/test/**/*.test.ts : Snapshot tests are used for renderer output validation

Applied to files:

  • packages/gunshi/src/cli.test.ts
🧬 Code graph analysis (2)
packages/gunshi/src/cli/core.ts (3)
packages/gunshi/src/utils.ts (2)
  • isLazyCommand (22-26)
  • resolveLazyCommand (36-88)
packages/gunshi/src/types.ts (3)
  • Command (485-536)
  • CommandContext (328-416)
  • CommandDecorator (600-602)
packages/gunshi/src/constants.ts (1)
  • NOOP (13-13)
packages/gunshi/src/cli.test.ts (5)
packages/gunshi/src/types.ts (3)
  • CommandRunner (576-578)
  • LazyCommand (542-551)
  • Command (485-536)
packages/gunshi/src/definition.ts (5)
  • CommandRunner (52-52)
  • LazyCommand (56-56)
  • Command (50-50)
  • lazy (174-197)
  • define (95-99)
packages/gunshi/src/cli/bone.ts (1)
  • cli (75-81)
packages/gunshi/src/cli/builtin.ts (1)
  • cli (78-85)
packages/gunshi/test/utils.ts (1)
  • defineMockLog (21-28)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test on Node.js 20
🔇 Additional comments (6)
packages/gunshi/src/cli/core.ts (4)

84-87: Proper lazy command resolution moved to cliCore.

The change moves lazy command resolution outside of executeCommand to the cliCore function. This is a good architectural improvement as it ensures commands are resolved early in the process and executeCommand operates on concrete commands only.


98-98: Pass resolved command to context construction.

The context now receives the resolved command instead of the potentially lazy command. This ensures type safety and consistency throughout the command execution pipeline.


104-104: executeCommand simplified to accept concrete Command only.

The function signature is cleaner now, accepting only resolved Command<G> instances. This eliminates the need for internal lazy resolution logic within executeCommand.


314-318: Clean function signature and implementation.

The executeCommand function is now simplified - it expects a concrete Command<G> and directly derives the base runner from cmd.run || NOOP. This removes the complexity of handling lazy commands within the execution phase.

packages/gunshi/src/cli.test.ts (2)

320-396: Test refactoring follows learnings and improves structure.

The lazy command tests are now properly organized under a describe block following the established pattern. The test coverage is comprehensive, testing both function-style and object-style lazy commands along with regular commands. The implementation correctly tests lazy loading behavior with proper async handling using setTimeout and promises.

Based on web search results, async functions create binding of new async function and return a Promise which will be resolved with the value returned or rejected with exception uncaught within the function. The test structure properly handles the asynchronous nature of lazy loading.


397-432: Good addition of config-driven lazy loading test.

This test case adds valuable coverage for dynamic lazy-loading scenarios using configuration. The test properly exercises the lazy utility with a loader function and validates both default and loaded command usage through snapshot testing. This aligns with the learnings about using snapshot tests for renderer output validation.

@kazupon
kazupon merged commit 365e5c1 into main Sep 22, 2025
9 checks passed
@kazupon
kazupon deleted the fix/lazy-async branch September 22, 2025 10:42
@coderabbitai coderabbitai Bot mentioned this pull request Dec 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Includes new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant