Skip to content

Register base-protection health check for conda doctor --fix#88

Open
jezdez wants to merge 50 commits intomainfrom
fix-base-task
Open

Register base-protection health check for conda doctor --fix#88
jezdez wants to merge 50 commits intomainfrom
fix-base-task

Conversation

@jezdez
Copy link
Member

@jezdez jezdez commented Dec 17, 2025

Registers a base-protection health check that integrates with conda doctor.

Fixes #74.

Requires: conda >= 26.1.0 (health check fixer API from conda/conda#15530)

What it does

  • conda doctor - shows if base environment is protected or not
  • conda doctor --fix - offers to protect your base environment

When fixing, the health check:

  1. Clones your base environment to a new default environment
  2. Resets base to essentials only
  3. Freezes base to prevent accidental modifications
  4. Sets the default activation environment to the new default

Usage

# Check base protection status
conda doctor

# Run fix to protect base environment
conda doctor --fix

# Run only this specific check
conda doctor base-protection
conda doctor base-protection --fix

Changes

  • Registers base-protection health check via conda_health_checks hook
  • Health check reports protection status in conda doctor output
  • Fix capability handles the full protection workflow
  • Updated README with new CLI syntax
  • Bumped minimum conda version to 26.1.0

…elp text

Fix #74.

- Introduced `conda migrate base` for base environment migration.
- Added `--list` option to display available migration tasks.
- Updated documentation and README to reflect new command structure.
- Enhanced tests for new functionality and help commands.
- Remove standalone 'conda migrate' subcommand
- Expose base environment protection via 'conda fix base' using conda's
  new fix task plugin framework
- Rename main_migrate.py to main_fix_base.py and clean up unused code
- Update README to document both 'conda self' and 'conda fix base'
- Update tests to use 'conda fix' instead of 'conda migrate'
- Improve test coverage and type hints

The 'conda self' subcommand for managing base environment packages
remains unchanged. The base protection task is now accessed via
'conda fix base' which uses conda's plugin-based fix task system.
- Update plugin.py: CondaFixTask -> CondaHealthFix
- Update plugin.py: conda_fix_tasks -> conda_health_fixes
- Update main_fix_base.py docstrings
- Update README.md terminology
- Update tests for new UI text and error handling
- Rename news file

This aligns with the conda plugin API rename for better
symmetry with 'health checks' from conda doctor.
The CondaHealthFix type only exists in conda versions with the fix
subcommand. Wrap the import in try/except so conda-self works with
older conda versions (just without the fix base feature).
The base environment protection functionality remains available via
conda self commands. The conda_health_fixes hook has been removed from
conda in favor of the simpler conda doctor --fix approach.
Register a health check with conda doctor that:
- Checks if the base environment is protected (frozen)
- Offers to fix by protecting the base environment

The health check only runs when checking the base environment and
provides verbose output explaining why protection is recommended.

Implementation split: hookimpl in plugin.py, functions in health_check.py
Import health check status marks from conda instead of defining locally.
- Move health_check.py to health_checks/base_protection.py
- Add health_checks/__init__.py with plugins list
- Move @hookimpl decorator into base_protection module
- Update plugin.py to import health_checks for registration
Keep the implementation in health_checks/base_protection.py but
define the hookimpl in plugin.py with a lazy import to avoid
import-time side effects.
- Keep main_fix_base.py as internal implementation for health check fix
- Update README to document using 'conda doctor --fix' for base protection
- Remove protect subcommand registration that was never completed
- Delete main_fix_base.py
- Move all protection workflow logic into health_checks/base_protection.py
- The fix is now self-contained in the health check module
- Fix SUCCESS_MESSAGE to show activation command instead of claiming auto-activation
- Simplify variable names and reduce redundancy
- Shorten warning messages
- Use pathlib.Path for cleaner path handling
- Set id='base-protection' for cleaner CLI usage
- Update README with new --list and --fix id syntax
@jezdez jezdez marked this pull request as draft January 20, 2026 17:30
jezdez added 15 commits January 26, 2026 13:33
- Update CondaHealthCheck to use `fixer` parameter with ConfirmCallback
- Replace confirm_yn() calls with confirm() callback passed by framework
- Add separate `fix` description parameter for --list output
- Bump conda dependency to >=26.1.0
- Add conda-canary channel testing to CI to catch compatibility issues early
The new health check API is on conda main but not released. Keep the
existing version requirement for stable channels and test with
conda-canary for the unreleased API.
The new health check API (fixer with ConfirmCallback) is only available
in conda-canary builds. Only run tests with conda-canary until the
required conda version is released.

The full test matrix is preserved in comments for easy restoration.
conda-canary may not have Python 3.13 builds for all platforms.
Use Python 3.12 and restrict platform solving to linux-64 only.
Pixi tries to solve all environments for all platforms, which fails
with conda-canary. Use setup-miniconda directly with conda-canary
channel for simpler, more reliable canary testing.
- Test is_base_environment and is_base_protected helper functions
- Test check action for base environment detection
- Test fix fixer early exit conditions
- Test plugin registration (skipped on older conda without fixer API)
- Add fallback for OK_MARK/X_MARK constants not in stable conda
- Convert class-based tests to function-based tests
- Use pytest fixtures (fake_base_env, protected_base_env) instead of mocks
- Use native pytest fixtures (tmp_path, monkeypatch, capsys)
- Restructure fix() to defer imports until after confirm callback
The fixer API (with ConfirmCallback) requires conda >= 26.1.0.
On older conda versions, only the check action is registered,
allowing the plugin to work without the fix functionality.
- Make version assertions more flexible in test_update_all (canary
  builds have different version string formats)
- Skip integration tests (test_reset, test_reset_migrate) for canary
  builds due to dependency resolution issues with package constraints
- Shorten summary string in plugin.py
- Move Path import to TYPE_CHECKING block
- Fix line length in test comment
- Use try/except in plugin.py instead of checking __dataclass_fields__
- Use hasattr() in test instead of __dataclass_fields__
- More Pythonic EAFP style
- Skip test_remove_nonessential_plugin (dependency resolution issues)
- Skip test_update_all (version mismatch between module and installed)
@jezdez
Copy link
Member Author

jezdez commented Jan 26, 2026

This is on hold until the conda 26.1.0 release has happened with the require plugin hook.

- Bump conda dependency to >=26.1.0 in pixi config
- Restore full test matrix now that health check API is released
- Remove backwards compatibility code from plugin.py
@jezdez
Copy link
Member Author

jezdez commented Feb 4, 2026

Updated for conda 26.1.0 release:

  • Bumped conda dependency to >=26.1.0
  • Restored full test matrix (pixi-based)
  • Simplified plugin.py by removing backwards compatibility code

Ready for review.

@jezdez jezdez marked this pull request as ready for review February 4, 2026 13:48
@danyeaw danyeaw moved this from In Progress 🏗️ to In review 🔍 in conda Roadmap and Sprint Planning Feb 4, 2026
- Change macos-latest to use conda-forge instead of defaults
- Remove macOS platforms from pixi config when testing defaults
  (conda 26.1.0 not available on defaults channel for macOS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extensible migration/fix tasks via conda doctor health checks

1 participant