Skip to content

Conversation

RonnyPfannschmidt
Copy link
Contributor

@RonnyPfannschmidt RonnyPfannschmidt commented Oct 7, 2025

this experiment replaces the complete plugin system with a backward compat hack

the intermediates are a bit troublesome as i missconfigrued claude

RonnyPfannschmidt and others added 9 commits October 7, 2025 11:27
This introduces a new PluginFinder that loads plugins directly from
entrypoint groups (e.g., hatch.builder) as the primary mechanism,
with fallback to legacy hook-based discovery for backward compatibility.

The legacy path directly calls hook functions without instantiating
pluggy's PluginManager, since hooks simply return classes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Removes dependency on pluggy's PluginManager for internal plugin discovery.
The new registry uses PluginFinder to load plugins directly from entrypoints,
only falling back to legacy hook-based loading when needed.

This eliminates the need to instantiate pluggy unless legacy plugins exist.
The public API (plugin_manager.builder.get()) remains unchanged.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The hookimpl decorator now lazy-loads pluggy only when actually used,
avoiding the import cost for the common case (no legacy plugins).

Emits deprecation warnings each time used to guide external plugin
authors toward the new direct entrypoint approach.

Hookspec files updated with deprecation notes for historical reference.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Deletes all internal hooks.py modules that used @hookimpl decorators.
Built-in plugins will be registered via direct entrypoints instead.

The hatch/hatchling codebase is now free of @hookimpl usage internally,
though external plugins can still use the (now-deprecated) hook system.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Adds 18 total plugin registrations across 9 entrypoint groups:
- hatchling: 12 plugins across 5 groups (version_source, version_scheme,
  builder, build_hook, metadata_hook)
- hatch: 6 plugins across 4 groups (environment, environment_collector,
  publisher, template)

Plugins are now discovered directly via entrypoint groups rather than
through the deprecated hook system. This completes the migration away
from pluggy for internal plugin registration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Adds direct loading of built-in plugins when entrypoints aren't
available yet (e.g., during editable installs or bootstrap).

This allows hatchling to build itself without requiring the
entrypoints to be installed first.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Documents the new direct entrypoint group approach as the primary
plugin registration method. Marks the old hook-based system as
deprecated but still supported for backward compatibility.

Includes migration guide for external plugin authors moving from
@hookimpl decorators to direct entrypoint declarations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Built-in plugins should never fail to load - if they do, it indicates
a serious problem that should not be hidden. Let errors propagate
instead of silently warning.

Linting fixes applied by ruff:
- Made helper methods static since they don't use self
- Added noqa comments for intentional API compatibility parameters
- Fixed error message formatting in PluginManager
- Removed unnecessary pass statement
- Removed obsolete noqa comment in metadata spec
- Fixed unused argument warnings in version sources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Removes the external importlib_metadata dependency by using only
stdlib importlib.metadata (available in Python 3.8+).

Added Python 3.9 compatibility wrapper since entry_points() API
changed in Python 3.10 (dict-like return vs function with group param).

This keeps hatchling dependency-free for plugin discovery while
maintaining Python 3.9+ compatibility.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
RonnyPfannschmidt and others added 3 commits October 7, 2025 15:15
Instead of hardcoding plugin registration data in BUILTIN_PLUGINS,
read it directly from the source pyproject.toml files. This ensures
the single source of truth is the entrypoint declarations themselves.

Benefits:
- No duplication: plugin registration is only defined once
- Always in sync: changes to pyproject.toml are automatically picked up
- Maintainable: adding new plugins only requires updating pyproject.toml

The loader finds and parses both backend/pyproject.toml (hatchling)
and pyproject.toml (hatch) at runtime, extracting all hatch.*
entrypoint groups.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Removed HOOK_NAME_MAPPING dict and replaced it with a simple f-string
since the pattern is consistent: f"hatch_register_{plugin_type}"

This eliminates another hardcoded mapping that just duplicates a simple
naming convention.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Corrects the parent directory index from parents[4] to parents[3] to properly
locate backend/pyproject.toml. The incorrect path prevented built-in plugins
(like the regex version source) from being discovered during bootstrap/CI builds,
causing "Unknown plugin" errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@RonnyPfannschmidt RonnyPfannschmidt force-pushed the ronny-with-claude/from-pluggy-to-entrypoints branch from 404017c to 5ca391c Compare October 7, 2025 13:37
builtin_plugins[plugin_type] = {}
builtin_plugins[plugin_type].update(plugins)

except Exception: # noqa: BLE001, S110
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this be scoped down to specific Exceptions/Errors? It feels like what is in the try block is going to primarily throw OSError, KeyError, TOMLDecodeError, and maybe 1 or 2 others that are not coming to me right now.

RonnyPfannschmidt and others added 2 commits October 9, 2025 15:45
Replace broad `except Exception: pass` with specific error handling:
- FileNotFoundError: silently continue (expected when trying paths)
- OSError: warn but continue (I/O errors like permissions)
- Other errors: propagate (e.g., TOML parse errors now visible)

Also simplify dict initialization using setdefault().

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The exists() check on line 52 already ensures the file exists before
we try to open it. The FileNotFoundError handler was unreachable in
normal operation and would only trigger in race conditions, which
should propagate as unexpected errors rather than being silently ignored.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

Choose a reason for hiding this comment

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

This should not be committed, this is a settings file for Claude Code it looks like.

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.

2 participants