Skip to content

Add shim for removed reflex component CLI command - #7497

Merged
masenf merged 1 commit into
mainfrom
claude/beautiful-edison-jtk7eu
Oct 7, 2026
Merged

masenf merged 1 commit into
mainfrom
claude/beautiful-edison-jtk7eu

Conversation

@masenf

@masenf masenf commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Description

Replaces the removed reflex component command with a hidden shim that gracefully guides users to the new workflow instead of showing a "No such command" error.

Changes:

  1. reflex/reflex.py: Added a hidden component command that:

    • Accepts any subcommand and flags (e.g., reflex component init, build, share, install)
    • Exits with code 1 and logs an error message pointing users to:
    • Uses ignore_unknown_options=True to prevent Click from raising "No such command" errors
  2. tests/units/test_reflex.py: Updated and expanded tests:

    • Changed test_component_command_is_not_registered() to test_component_command_is_hidden() — verifies the command exists but is hidden from --help output
    • Added test_component_command_points_to_template() — ensures all old subcommands redirect with the helpful message
    • Added test_component_help_points_to_template() — verifies --help invocations show the pointer
    • Added test_component_command_dispatches_from_cli() — integration test confirming the shim works when invoked via subprocess
    • Updated CLI startup test to include component --help in the denied modules list
  3. news/+component-cli-shim.bugfix.md: Added changelog fragment documenting the user-facing improvement.

Test Plan

All new and modified tests pass:

  • Unit tests verify the command is hidden, accepts any arguments, and returns the helpful error message
  • Integration test confirms the shim works when invoked via the CLI entry point
  • Existing tests continue to pass

https://claude.ai/code/session_01CEngePWmkuAQ31xWPb1Q9L

View guided diff Turn on auto-fix

The custom components CLI was removed in 0.10, so every `reflex component`
subcommand failed with "No such command 'component'. Did you mean
'compile'?" and no hint about where the workflow moved.

Register a hidden `component` shim that accepts any subcommand and flags,
logs that the command was removed in Reflex 0.10, points at the wrapping
React docs and https://github.com/reflex-dev/component-template, and exits
1. `reflex component --help` prints the same pointer. The command stays out
of `reflex --help`, and the plural typo `reflex components` now suggests it.

Fixes #7490

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CEngePWmkuAQ31xWPb1Q9L
@masenf
masenf requested a review from a team as a code owner October 7, 2026 16:31

@cubic-dev-ai cubic-dev-ai 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.

No issues found across 3 files

View guided diff | Turn on auto-fix | Re-trigger cubic

@greptile-apps

greptile-apps Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Low risk] Adds a shim for a removed CLI command.

The PR appears safe to merge; no actionable issues were found.

What we checked:

  • Test runs only fixed arguments: The test runs the current Python interpreter with fixed arguments. It does not enable a shell or build a command from user input.

Summary

Adds a hidden reflex component shim that points users to the wrapping React docs and component template instead of rejecting the command.

  • Old subcommands and flags reach a fixed error message and exit with code 1.
  • Help shows the same guidance without listing the shim in top-level help.
  • Adds tests for argument handling, help, CLI dispatch, and lightweight startup.
  • No actionable issues found. Tests were inspected but not run.

Reviews (1) · Last reviewed commit: "Point reflex component at the component ..." · Reviewed by Greptile

@codspeed

codspeed Bot commented Oct 7, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 5.6%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 149 untouched benchmarks
⏩ 18 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
⚡ test_hydration_metadata[200] 2 ms 1.8 ms +5.6%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing claude/beautiful-edison-jtk7eu (aefcd44) with main (8239259)

Open in CodSpeed

Footnotes

  1. 18 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

masenf commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator Author

CI: unit-tests (ubuntu-latest, 3.14) is red on test_state_manager_lock_expire_contend, which this PR does not touch.

The step "Run unit tests w/ redis and OPLOCK_ENABLED" of the unit-tests run on aefcd44 (run 37652759387, job 112900156229) failed on exactly one test, tests/units/test_state.py::test_state_manager_lock_expire_contend, with LockExpiredError raised from await tasks[0] in the oplock branch (which expects the blocker to exit cleanly and the error to surface from the lease breaker instead). 12,461 other tests passed.

Why it is not this PR's:

  • The diff only registers a hidden component click command and adds CLI tests; the state manager is untouched.
  • The same test passed in the preceding "w/ redis" step of the same job, on every other leg of this run, and on main's identical leg at this PR's base commit 8239259.
  • Locally against a real Redis with CI timings (CI=1) it passes 12/12 across both oplock modes.

Root cause, a pre-existing race in the test's precondition: StateManagerRedis._create_lease_break_task returns None when _lock_updates_subscribed is not yet set (reflex/istate/manager/redis.py:783), and _ensure_lock_task_subscribed() is only awaited inside _wait_lock, i.e. when a first lock attempt fails. The blocker here takes an uncontended lock on a fresh manager, so nothing waits for the subscriber. If the subscriber task has not confirmed its psubscribe by then, the blocker falls into the "single update" fallback (redis.py:596), holds the lock for LOCK_EXPIRE_SLEEP (2.5 s) against a 2500 ms expiration, and the fenced save at exit raises. Delaying _subscribe_lock_updates by 1 s reproduces the identical traceback deterministically.

Proposed fix, verified locally (passes 3/3 with the delayed subscriber, with a normal subscriber in both modes, and with the mocked Redis), left out of this PR to keep it scoped to the CLI shim:

# tests/units/test_state.py, test_state_manager_lock_expire_contend, just before `tasks = [`
    if environment.REFLEX_OPLOCK_ENABLED.get():
        # The blocker leases the lock only once the lock-update subscriber is
        # ready; otherwise it falls back to one fenced write, which expires.
        await state_manager_redis._ensure_lock_task_subscribed()

I cannot re-run the failed job from here: the re-run request is rejected with 403 "Resource not accessible by integration", so a maintainer would need to re-run it, or say the word and I will carry the one-line test fix in this PR.

Update: the maintainer re-run (attempt 2) passed every step, including the oplock pass, and the unit-tests gate is green. The proposed test fix above still stands as a follow-up for the underlying race.


Generated by Claude Code

@masenf masenf left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

👍

@masenf masenf added the on deck PRs lined up to review / merge next label Oct 7, 2026
@masenf masenf added this to the v0.10.x milestone Oct 7, 2026

@FarhanAliRaza FarhanAliRaza 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.

Exercised the shim on this PR vs main: reflex component with no args, init, build --foo -x, share --bar=1, install and -h all print the pointer message and exit 1 (main: "No such command", exit 2). reflex component --help exits 0 with the same text, the command stays hidden from reflex --help, and init/cloud/--version are unaffected. The linked docs section and component template exist in the repo, tests/units/test_reflex.py passes (48), ruff is clean, and the news fragment is present.

Nit, non-blocking: -h isn't a help flag in reflex, so it hits the shim (exit 1) while --help exits 0.


Generated by Claude Code

masenf commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

Re the -h nit: left as is. No reflex command treats -h as help (click registers only --help, so reflex run -h is a usage error), and adding it only to this shim would be inconsistent; reflex component -h still prints the pointer, it just exits 1 like every other non-help invocation of the shim.


Generated by Claude Code

@masenf
masenf merged commit 8eafab9 into main Oct 7, 2026
160 of 161 checks passed
@masenf
masenf deleted the claude/beautiful-edison-jtk7eu branch October 7, 2026 18:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

on deck PRs lined up to review / merge next

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants