Skip to content

Commit e640fe7

Browse files
committed
hooks in own file
1 parent 1bdcfff commit e640fe7

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

EXTENDING.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Extending mxdev with Hooks
2+
3+
The functionality of mxdev can be extended by hooks.
4+
This is useful to generate additional scripts or files or automate any other setup steps related to mxdev's domain.
5+
6+
## Configuration
7+
8+
Extension configuration settings end up in the `mx.ini` file.
9+
They can be added globally to the `settings` section, as dedicated config sections or package specific.
10+
To avoid naming conflicts, all hook-related settings and config sections must be prefixed with a namespace.
11+
12+
It is recommended to use the package name containing the hook as a namespace.
13+
14+
This looks like so:
15+
16+
```INI
17+
[settings]
18+
myextension-global_setting = 1
19+
20+
[myextension-section]
21+
setting = value
22+
23+
[foo.bar]
24+
myextension-package_setting = 1
25+
```
26+
27+
## Implementation
28+
29+
The extension is implemented as a subclass of `mxdev.Hook`:
30+
31+
```Python
32+
from mxdev import Hook
33+
from mxdev import State
34+
35+
class MyExtension(Hook):
36+
37+
namespace = "myextension"
38+
"""The namespace for this hook."""
39+
40+
def read(self, state: State) -> None:
41+
"""Gets executed after mxdev read operation."""
42+
# Access configuration from state
43+
# - state.configuration.settings: main [settings] section
44+
# - state.configuration.packages: package sections
45+
# - state.configuration.hooks: hook-related sections
46+
47+
# Example: Access your hook's settings
48+
global_setting = state.configuration.settings.get('myextension-global_setting')
49+
50+
# Example: Access hook-specific sections
51+
for section_name, section_config in state.configuration.hooks.items():
52+
if section_name.startswith('myextension-'):
53+
# Process your hook's configuration
54+
pass
55+
56+
def write(self, state: State) -> None:
57+
"""Gets executed after mxdev write operation."""
58+
# Generate additional files, scripts, etc.
59+
# Access generated requirements/constraints from:
60+
# - state.requirements
61+
# - state.constraints
62+
```
63+
64+
## State Object
65+
66+
The `State` object passed to hooks contains:
67+
68+
- **`state.configuration`**: Configuration object with:
69+
- `settings`: Dict of main [settings] section
70+
- `packages`: Dict of package sections
71+
- `hooks`: Dict of hook-related sections
72+
73+
- **`state.requirements`**: List of requirement lines (after write phase)
74+
75+
- **`state.constraints`**: List of constraint lines (after write phase)
76+
77+
## Registration
78+
79+
The hook must be registered as an entry point in the `pyproject.toml` of your package:
80+
81+
```TOML
82+
[project.entry-points.mxdev]
83+
myextension = "mypackage:MyExtension"
84+
```
85+
86+
Replace:
87+
- `myextension`: The name users will reference
88+
- `mypackage`: Your Python package name
89+
- `MyExtension`: Your Hook subclass
90+
91+
## Hook Lifecycle
92+
93+
1. **Read phase**: mxdev reads configuration and fetches sources
94+
- All hooks' `read()` methods are called
95+
96+
2. **Write phase**: mxdev writes requirements and constraints
97+
- All hooks' `write()` methods are called
98+
99+
## Namespace Convention
100+
101+
- Use your package name as namespace prefix
102+
- All settings: `namespace-setting_name`
103+
- All sections: `[namespace-section]`
104+
- This prevents conflicts with other hooks
105+
106+
## Example Use Cases
107+
108+
- Generate additional configuration files (e.g., buildout.cfg, docker-compose.yml)
109+
- Create wrapper scripts for development
110+
- Generate IDE project files
111+
- Export dependency graphs
112+
- Integrate with other tools (pytest, tox, pre-commit)
113+
114+
## Best Practices
115+
116+
1. **Fail gracefully**: If your hook can't complete, log warnings instead of raising exceptions
117+
2. **Document your settings**: Provide clear documentation for all configuration options
118+
3. **Use namespaces**: Always prefix settings with your namespace
119+
4. **Be minimal**: Don't add heavy dependencies to your hook package
120+
5. **Test thoroughly**: Hooks run after mxdev's core operations, ensure they don't break workflows
121+
122+
## See Also
123+
124+
- [mxdev main documentation](README.md)
125+
- [Hook base class source](src/mxdev/hooks.py)
126+
- [State object source](src/mxdev/state.py)

0 commit comments

Comments
 (0)