refactor(mode): replace config-based mode setting with runtime detection#196
Open
ayeshurun wants to merge 22 commits intomicrosoft:mainfrom
Open
refactor(mode): replace config-based mode setting with runtime detection#196ayeshurun wants to merge 22 commits intomicrosoft:mainfrom
ayeshurun wants to merge 22 commits intomicrosoft:mainfrom
Conversation
This script benchmarks the startup performance of the CLI by measuring module import times, CLI invocation times, and heavy dependency loading. It allows comparisons against a baseline branch or tag.
Co-authored-by: ayeshurun <98805507+ayeshurun@users.noreply.github.com>
- Move runtime mode into Context class (singleton instance methods) - Graduated deprecation: 'config set mode interactive' still launches REPL with warning - Graduated deprecation: 'config get mode' returns runtime mode with warning - Add regression tests: runtime mode (6), config deprecation (7), init defaults (4), MAP removal (6), session-per-request (3), context persistence mock updates (10) - Consolidate test files into test_fab_context.py, test_config.py, test_fab_state_config.py Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolved conflicts in main.py and test_fab_state_config.py. Re-removed ItemType.MAP, _shared_session/_get_session, and MAP references in command_support.yaml, fab_item.py, and test conftest that upstream re-introduced. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
aviatco
reviewed
Mar 24, 2026
added 3 commits
March 25, 2026 12:47
aviatco
reviewed
Mar 26, 2026
…ntions - Use mock_repl fixture in TestConfig instead of inline with-patch - Add _success suffix to all TestRuntimeMode test names - Fix test_init_defaults_no_mode_key_succeeds -> _success Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove duplicate mode deprecation tests from TestConfig (kept in TestConfigModeDeprecated which has better coverage) - Remove mock_repl fixture from TestConfig (no longer needed) - Drop mock_questionary_print from tests that only need mock_print_warning and mock_repl - Add actual assertions to previously no-op tests (mock_print_done, mock_questionary_print) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Refactors Fabric CLI mode handling to remove the persisted mode setting and instead determine REPL vs command-line behavior at runtime, while keeping backward compatibility for config get/set mode and updating docs/tests accordingly.
Changes:
- Introduces a runtime-mode flag on the
Contextsingleton and updates REPL startup/exit to toggle it. - Removes
modefrom persisted config keys/defaults and adds a config migration to delete legacymode. - Deprecates
config get/set mode(warn + no-op / runtime value), updates docs and test suites.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/fabric_cli/core/fab_context.py |
Adds runtime mode storage/accessors; switches context persistence gating to runtime mode. |
src/fabric_cli/core/fab_interactive.py |
Sets runtime mode when entering REPL and resets on exit. |
src/fabric_cli/core/fab_constant.py |
Removes mode from config-valid-values and defaults. |
src/fabric_cli/core/fab_state_config.py |
Adds migration logic to remove legacy mode from existing config. |
src/fabric_cli/commands/config/fab_config_set.py |
Deprecates config set mode and optionally launches REPL for interactive. |
src/fabric_cli/commands/config/fab_config_get.py |
Deprecates config get mode and returns runtime mode. |
src/fabric_cli/main.py |
Removes post-login auto-REPL behavior based on stored config mode. |
src/fabric_cli/parsers/fab_config_parser.py |
Updates examples away from mode. |
tests/conftest.py |
Resets Context runtime mode between tests to prevent leakage. |
tests/test_core/test_fab_context.py |
Adds unit tests for runtime mode behavior and config removal assertions. |
tests/test_core/test_context_persistence.py |
Updates persistence tests to rely on runtime mode instead of config mode. |
tests/test_core/test_fab_state_config.py |
Adds migration tests for removing legacy mode in init_defaults(). |
tests/test_core/test_fab_config_completers.py |
Updates completer tests to avoid mode. |
tests/test_commands/test_config.py |
Updates command tests for deprecation behavior and non-mode config set/get. |
docs/essentials/modes.md |
Rewrites docs to describe runtime-detected REPL vs command-line. |
docs/essentials/settings.md |
Removes mode from persisted settings documentation. |
.github/instructions/test.instructions.md |
Updates documented test naming convention/examples. |
.changes/unreleased/optimization-20260322-103653.yaml |
Adds changelog entry for the optimization/refactor. |
Comments suppressed due to low confidence (1)
tests/test_core/test_fab_state_config.py:79
- There’s a redundant local
import jsoninsidetest_init_defaults_no_write_when_unchangedeven though the module now importsjsonat the top. Removing the inner import will reduce noise and keep imports consistent.
def test_init_defaults_no_write_when_unchanged(self, tmp_path, monkeypatch):
"""Test that init_defaults skips writing when config already has all defaults."""
import json
from fabric_cli.core import fab_constant
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix init_defaults() to set changed=True after deleting mode key and also clean up legacy fab_mode key - Update test_context_persistence comments to reflect that REPL mode (not disabled persistence) is why file ops are skipped - Use tmp_path instead of tempfile.mkdtemp() in _create_temp_config for automatic cleanup - Rename double-underscore test names to single underscore in test_core - Update PR description: Context singleton (not fab_constant) exposes runtime mode helpers Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📥 Pull Request
✨ Description of new changes
The CLI mode (
interactive/command_line) was persisted in~/.config/fab/config.jsonand requiredfab config set mode interactiveto enter REPL. Mode is now determined purely at runtime - no config entry, no explicit switching.What changed
Runtime detection -
Contextsingleton exposesset_runtime_mode()/get_runtime_mode().InteractiveCLIsetsFAB_MODE_INTERACTIVEon start and resets it on exit. Everything else readsget_runtime_mode()instead of the config file.Config migration -
init_defaults()silently removes the legacymodekey (andfab_mode) from existingconfig.jsonon first run.Backward compat -
config get modeandconfig set mode <value>now print a deprecation warning and return cleanly instead of erroring.Context persistence -
_should_use_context_file()now callsget_runtime_mode()instead offab_state_config.get_config(FAB_MODE). Context files are still skipped in REPL (in-memory context is sufficient).main.py- removed the post-login block that auto-started REPL whenmode=interactivewas stored in config.Docs -
modes.mdrewritten to reflect the new runtime model;moderow removed fromsettings.md.Entry points now
fabfab <command>Original prompt