feat(extensions): add --force flag to extension add for overwrite reinstall#2530
feat(extensions): add --force flag to extension add for overwrite reinstall#2530grissiom wants to merge 4 commits into
Conversation
…nstall Add --force support to `specify extension add` that allows overwriting an already-installed extension without manually removing it first. - install_from_directory() and install_from_zip() accept force=True, automatically calling remove() before installation - The --force CLI flag works with all install modes (--dev, --from URL, bundled, and catalog) - Config files (*-config.yml) are preserved across force reinstall - Error message suggests --force when extension is already installed - 6 new tests covering unit and CLI force reinstall flows
There was a problem hiding this comment.
Pull request overview
Adds --force support to specify extension add so users can overwrite/reinstall an already-installed extension in one step, while preserving *-config.yml files across the reinstall.
Changes:
- Add
forceparameter toExtensionManager.install_from_directory()/install_from_zip()and plumb--forcethrough the CLI. - Preserve extension config files across force reinstalls via
.specify/extensions/.backup/<ext_id>restore logic. - Add unit + CLI tests for force reinstall behavior and updated duplicate-install error messaging.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/extensions.py |
Implements force reinstall path, updated duplicate install error text, and config backup restore. |
src/specify_cli/__init__.py |
Adds --force flag to specify extension add and passes it through to install routines. |
tests/test_extensions.py |
Adds tests for force reinstall flows (directory/zip) and CLI coverage for extension add --dev --force. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 3/3 changed files
- Comments generated: 3
|
Please address Copilot feedback |
- Remove unused `backup_config_dir` variable assignment (Ruff F841) - Defer `remove()` until after `_validate_install_conflicts()` to prevent data loss if validation fails mid-reinstall - Use `TemporaryDirectory` instead of `NamedTemporaryFile` in ZIP test to avoid Windows file-locking failures
|
@mnriem fixed the 3 comments, please review it again. Thanks~ |
| # Restore config files from backup when reinstalling with --force | ||
| if force: | ||
| backup_config_dir = self.extensions_dir / ".backup" / manifest.id | ||
| if backup_config_dir.exists(): | ||
| for cfg_file in backup_config_dir.iterdir(): |
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback
When --force is used but the extension is not already installed, the backup restore/cleanup should not run. Previously it could resurrect stale config files from a previous removal and delete the backup directory unnecessarily.
|
@mnriem Thank you for your review. The bug is fixed. Please review it again. Thanks~ |
| # validation failure doesn't leave the user with a half-uninstalled | ||
| # extension (configs stranded in .backup/). | ||
| did_remove = False | ||
| if force and self.registry.is_installed(manifest.id): |
| backup_config_dir = self.extensions_dir / ".backup" / manifest.id | ||
| if backup_config_dir.exists(): | ||
| for cfg_file in backup_config_dir.iterdir(): | ||
| if cfg_file.is_file(): |
| speckit_version = get_speckit_version() | ||
|
|
||
| if force: | ||
| console.print("[yellow]--force:[/yellow] Will overwrite if already installed\n") |
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback. If not applicable, please explain why
- Clear stale backup dir before remove() so only fresh backups are restored - Restore only config files (*-config.yml, *-config.local.yml) from backup - Remove trailing \n from --force console message (console.print adds newline)
355a649 to
1ed5439
Compare
|
Nice findings @mnriem , all issues fixed and please review it again. Thanks~ |
feat(extensions): add --force flag to extension add for overwrite reinstall
Add --force support to
specify extension addthat allows overwriting an already-installed extension without manually removing it first.Description
If the extension is updated, --force could eliminate the remove/install loop and simplify the workflow.
Testing
uv run specify --helpuv sync && uv run pytestAI Disclosure
Generated by Copilot(model: DeepSeek-V4).