0
# Build Management
1
2
The build management system controls the Sphinx documentation build process with support for pre/post-build commands, error handling, and integration with the file watching system.
3
4
## Capabilities
5
6
### Builder Class
7
8
The main class responsible for executing Sphinx builds when files change.
9
10
```python { .api }
11
class Builder:
12
def __init__(
13
self,
14
sphinx_args,
15
*,
16
url_host,
17
pre_build_commands,
18
post_build_commands
19
):
20
"""
21
Initialize builder with Sphinx arguments and command hooks.
22
23
Parameters:
24
- sphinx_args: list[str] - Arguments to pass to sphinx-build
25
- url_host: str - Host:port string for server URL display
26
- pre_build_commands: list[list[str]] - Commands to run before build
27
- post_build_commands: list[list[str]] - Commands to run after successful build
28
"""
29
30
def __call__(self, *, changed_paths):
31
"""
32
Execute build process when files change.
33
34
Parameters:
35
- changed_paths: Sequence[Path] - Paths of files that changed (triggers rebuild)
36
37
Returns:
38
- None
39
40
Side Effects:
41
- Runs pre-build commands
42
- Executes sphinx-build with configured arguments
43
- Runs post-build commands (only if build succeeds)
44
- Prints status messages and server URL
45
- Handles build errors gracefully
46
"""
47
```
48
49
### Build Process Flow
50
51
The build process follows a specific sequence:
52
53
1. **Change Detection**: Display changed file paths (up to 5 files shown)
54
2. **Pre-build Commands**: Execute all configured pre-build commands in order
55
3. **Sphinx Build**: Run sphinx-build with provided arguments
56
4. **Post-build Commands**: Execute post-build commands only if build succeeds
57
5. **Status Display**: Show server URL for user convenience
58
59
**Usage Example:**
60
61
```python
62
from sphinx_autobuild.build import Builder
63
from pathlib import Path
64
65
# Initialize builder
66
builder = Builder(
67
sphinx_args=['-b', 'html', 'docs', '_build/html'],
68
url_host='127.0.0.1:8000',
69
pre_build_commands=[['echo', 'Starting build']],
70
post_build_commands=[['echo', 'Build complete']]
71
)
72
73
# Trigger build
74
changed_files = [Path('docs/index.rst'), Path('docs/api.rst')]
75
builder(changed_paths=changed_files)
76
```
77
78
### Command Execution
79
80
Handles pre-build and post-build command execution with error management.
81
82
```python { .api }
83
def _run_commands(self, commands, log_context):
84
"""
85
Execute a list of commands in sequence.
86
87
Parameters:
88
- commands: list[list[str]] - List of commands to execute
89
- log_context: str - Context string for logging ('pre-build' or 'post-build')
90
91
Returns:
92
- int - Return code (0 for success, non-zero for failure)
93
94
Error Handling:
95
- Prints error message and traceback on command failure
96
- Returns early on first command failure
97
- Server continues running even after command failures
98
"""
99
```
100
101
### Sphinx Integration
102
103
Integrates with different versions of Sphinx, handling version-specific argument formats.
104
105
**Sphinx Version Compatibility:**
106
- **Sphinx ≥7.2.3**: Uses `python -m sphinx build` command format
107
- **Sphinx <7.2.3**: Uses `python -m sphinx` command format
108
109
**Build Arguments:**
110
The builder accepts all standard sphinx-build arguments:
111
112
```python
113
# Common Sphinx arguments
114
sphinx_args = [
115
'-b', 'html', # Builder type
116
'-E', # Don't use saved environment
117
'-a', # Write all files
118
'-v', # Verbose output
119
'-W', # Turn warnings into errors
120
'-d', '_build/doctrees', # Doctree directory
121
'docs', # Source directory
122
'_build/html' # Output directory
123
]
124
```
125
126
## Usage Examples
127
128
### Basic Build Management
129
130
```python
131
from sphinx_autobuild.build import Builder
132
133
# Simple builder with no extra commands
134
builder = Builder(
135
sphinx_args=['docs', '_build/html'],
136
url_host='localhost:8000',
137
pre_build_commands=[],
138
post_build_commands=[]
139
)
140
141
# Trigger rebuild
142
builder(changed_paths=[])
143
```
144
145
### Advanced Build Configuration
146
147
```python
148
from sphinx_autobuild.build import Builder
149
import shlex
150
151
# Complex builder with multiple commands
152
pre_build = [
153
['python', 'scripts/generate_api.py'],
154
['python', '-c', 'print("API docs generated")']
155
]
156
157
post_build = [
158
['python', 'scripts/validate_links.py'],
159
shlex.split('find _build -name "*.html" -exec echo "Generated: {}" \\;')
160
]
161
162
builder = Builder(
163
sphinx_args=['-b', 'html', '-E', '-v', 'docs', '_build/html'],
164
url_host='192.168.1.100:8080',
165
pre_build_commands=pre_build,
166
post_build_commands=post_build
167
)
168
```
169
170
### Integration with File Watcher
171
172
```python
173
from sphinx_autobuild.build import Builder
174
from sphinx_autobuild.server import RebuildServer
175
from sphinx_autobuild.filter import IgnoreFilter
176
from pathlib import Path
177
178
# Create builder
179
builder = Builder(
180
sphinx_args=['docs', '_build/html'],
181
url_host='127.0.0.1:8000',
182
pre_build_commands=[],
183
post_build_commands=[]
184
)
185
186
# Create file watcher that uses builder as callback
187
watch_dirs = [Path('docs')]
188
ignore_filter = IgnoreFilter([], [])
189
server = RebuildServer(watch_dirs, ignore_filter, builder)
190
```
191
192
## Error Handling
193
194
### Build Failures
195
196
When Sphinx build fails:
197
- Error message with exit code is displayed
198
- Server continues serving existing content
199
- User is advised to fix errors or stop server
200
- Pre-build command failures prevent Sphinx execution
201
- Post-build commands only run after successful builds
202
203
### Command Failures
204
205
Pre/post-build command failures:
206
- Error details and traceback are printed
207
- Descriptive error messages with context
208
- Server continues operating
209
- Subsequent commands in the list are skipped
210
211
### Common Error Scenarios
212
213
```python
214
# Command not found
215
pre_build_commands = [['nonexistent-command', 'arg']]
216
# Output: "Pre-build command exited with exit code: 127"
217
218
# Sphinx syntax error
219
# Output: "Sphinx exited with exit code: 2"
220
# Server continues serving stale content
221
222
# Permission denied
223
post_build_commands = [['chmod', '000', '/protected/file']]
224
# Output: "Post-build command exited with exit code: 1"
225
```
226
227
## Performance Considerations
228
229
- **Incremental Builds**: Sphinx's incremental building is preserved
230
- **Command Caching**: No caching of command results - each change triggers full command sequence
231
- **File Path Limiting**: Only first 5 changed paths are displayed to avoid spam
232
- **Process Isolation**: Commands run in separate processes for stability