0
# Application Controller
1
2
Central application controller that manages project state, configuration, environments, and command execution. Provides the main coordination layer for all hatch operations.
3
4
## Capabilities
5
6
### Application Class
7
8
Main application controller that orchestrates all hatch operations including environment management, configuration handling, and command execution.
9
10
```python { .api }
11
class Application:
12
"""
13
Main application controller managing project state and operations.
14
15
Inherits from Terminal class to provide output formatting and display capabilities.
16
"""
17
18
def __init__(self, exit_func, *args, **kwargs):
19
"""
20
Initialize application instance.
21
22
Args:
23
exit_func: Function to call on application exit
24
*args: Additional positional arguments passed to Terminal
25
**kwargs: Additional keyword arguments passed to Terminal
26
"""
27
28
@property
29
def config(self):
30
"""
31
Root configuration object.
32
33
Returns:
34
RootConfig: Application configuration
35
"""
36
37
@property
38
def plugins(self):
39
"""
40
Plugin manager instance.
41
42
Returns:
43
PluginManager: Plugin manager for discovering and loading plugins
44
"""
45
46
@property
47
def project(self):
48
"""
49
Current project instance.
50
51
Returns:
52
Project: Current project or None
53
"""
54
55
@project.setter
56
def project(self, value):
57
"""Set current project."""
58
59
@property
60
def data_dir(self) -> Path:
61
"""
62
Application data directory.
63
64
Returns:
65
Path to data directory
66
"""
67
68
@property
69
def cache_dir(self) -> Path:
70
"""
71
Application cache directory.
72
73
Returns:
74
Path to cache directory
75
"""
76
77
@property
78
def config_file(self):
79
"""
80
Configuration file handler.
81
82
Returns:
83
ConfigFile: Configuration file manager
84
"""
85
86
def get_environment(self, env_name: str | None = None):
87
"""
88
Get environment interface for specified environment.
89
90
Args:
91
env_name (str, optional): Environment name, defaults to current environment
92
93
Returns:
94
EnvironmentInterface: Environment instance
95
"""
96
97
def prepare_environment(self, environment):
98
"""
99
Prepare environment for execution including dependency installation.
100
101
Args:
102
environment: Environment interface to prepare
103
"""
104
105
def run_shell_commands(self, context):
106
"""
107
Execute shell commands in prepared environment.
108
109
Args:
110
context: Execution context with commands and environment
111
"""
112
113
def ensure_environment_plugin_dependencies(self) -> None:
114
"""Ensure environment plugin dependencies are installed."""
115
116
def get_python_manager(self, directory: str | None = None):
117
"""
118
Get Python installation manager.
119
120
Args:
121
directory (str, optional): Directory for Python installations
122
123
Returns:
124
PythonManager: Python installation manager
125
"""
126
127
def abort(self, text: str = '', code: int = 1, **kwargs):
128
"""
129
Abort application with error message and exit code.
130
131
Args:
132
text (str): Error message to display
133
code (int): Exit code
134
**kwargs: Additional formatting arguments
135
"""
136
137
def display_info(self, text: str, **kwargs):
138
"""
139
Display informational message.
140
141
Args:
142
text (str): Message to display
143
**kwargs: Formatting arguments
144
"""
145
146
def display_success(self, text: str, **kwargs):
147
"""
148
Display success message.
149
150
Args:
151
text (str): Success message
152
**kwargs: Formatting arguments
153
"""
154
155
def display_warning(self, text: str, **kwargs):
156
"""
157
Display warning message.
158
159
Args:
160
text (str): Warning message
161
**kwargs: Formatting arguments
162
"""
163
164
def display_error(self, text: str, **kwargs):
165
"""
166
Display error message.
167
168
Args:
169
text (str): Error message
170
**kwargs: Formatting arguments
171
"""
172
173
def display_waiting(self, text: str, **kwargs):
174
"""
175
Display waiting/progress message.
176
177
Args:
178
text (str): Progress message
179
**kwargs: Formatting arguments
180
"""
181
```
182
183
### Execution Context
184
185
Context object for managing command execution including environment settings, command sequences, and output handling.
186
187
```python { .api }
188
class ExecutionContext:
189
"""
190
Context for command execution with environment and command management.
191
192
Args:
193
environment: Environment interface for execution
194
shell_commands (list[str], optional): Commands to execute
195
env_vars (dict, optional): Additional environment variables
196
force_continue (bool): Whether to continue on command failure
197
show_code_on_error (bool): Whether to show exit codes on error
198
hide_commands (bool): Whether to hide command output
199
source (str): Source identifier for commands
200
"""
201
202
def __init__(
203
self,
204
environment,
205
*,
206
shell_commands: list[str] | None = None,
207
env_vars: dict[str, str] | None = None,
208
force_continue: bool = False,
209
show_code_on_error: bool = False,
210
hide_commands: bool = False,
211
source: str = 'cmd'
212
):
213
"""Initialize execution context."""
214
215
@property
216
def env(self):
217
"""Environment for command execution."""
218
219
@property
220
def shell_commands(self) -> list[str]:
221
"""Commands to execute."""
222
223
@property
224
def env_vars(self) -> dict[str, str]:
225
"""Environment variables for execution."""
226
227
@property
228
def force_continue(self) -> bool:
229
"""Whether to continue on command failure."""
230
231
@property
232
def show_code_on_error(self) -> bool:
233
"""Whether to show exit codes on error."""
234
235
@property
236
def hide_commands(self) -> bool:
237
"""Whether to hide command output."""
238
239
@property
240
def source(self) -> str:
241
"""Source identifier for commands."""
242
243
def add_shell_command(self, command: str | list[str]) -> None:
244
"""
245
Add shell command to execution context.
246
247
Args:
248
command (str | list[str]): Command to add (string or argument list)
249
"""
250
```
251
252
### Application Configuration
253
254
Configuration management for application-level settings including directories, verbosity, color output, and plugin configuration.
255
256
```python { .api }
257
class ApplicationConfig:
258
"""Application-level configuration settings."""
259
260
@property
261
def verbosity(self) -> int:
262
"""Verbosity level (-2 to 2)."""
263
264
@property
265
def quiet(self) -> bool:
266
"""Whether quiet mode is enabled."""
267
268
@property
269
def enable_color(self) -> bool:
270
"""Whether colored output is enabled."""
271
272
@property
273
def interactive(self) -> bool:
274
"""Whether interactive features are enabled."""
275
276
@property
277
def data_dir(self) -> Path:
278
"""Application data directory."""
279
280
@property
281
def cache_dir(self) -> Path:
282
"""Application cache directory."""
283
284
@property
285
def config_file_path(self) -> Path:
286
"""Configuration file path."""
287
```
288
289
### Environment Resolution
290
291
Environment discovery, validation, and selection logic for determining which environment to use for operations.
292
293
```python { .api }
294
def resolve_environment_name(
295
app: Application,
296
env_name: str | None = None,
297
command_env: str | None = None
298
) -> str:
299
"""
300
Resolve environment name from various sources.
301
302
Args:
303
app (Application): Application instance
304
env_name (str, optional): Explicitly specified environment
305
command_env (str, optional): Environment from command specification
306
307
Returns:
308
Resolved environment name
309
"""
310
311
def validate_environment_name(app: Application, env_name: str) -> bool:
312
"""
313
Validate that environment name exists in configuration.
314
315
Args:
316
app (Application): Application instance
317
env_name (str): Environment name to validate
318
319
Returns:
320
True if environment exists
321
"""
322
323
def get_available_environments(app: Application) -> list[str]:
324
"""
325
Get list of available environment names.
326
327
Args:
328
app (Application): Application instance
329
330
Returns:
331
List of available environment names
332
"""
333
```
334
335
### Command Processing
336
337
Command parsing, validation, and execution pipeline for processing user commands and script definitions.
338
339
```python { .api }
340
def parse_command_string(command: str) -> tuple[str | None, str]:
341
"""
342
Parse command string to extract environment and command.
343
344
Args:
345
command (str): Command string potentially prefixed with "env:"
346
347
Returns:
348
Tuple of (environment_name, command)
349
"""
350
351
def validate_command(app: Application, command: str) -> bool:
352
"""
353
Validate command syntax and availability.
354
355
Args:
356
app (Application): Application instance
357
command (str): Command to validate
358
359
Returns:
360
True if command is valid
361
"""
362
363
def prepare_command_environment(
364
app: Application,
365
env_name: str,
366
commands: list[str]
367
) -> ExecutionContext:
368
"""
369
Prepare execution context for command execution.
370
371
Args:
372
app (Application): Application instance
373
env_name (str): Environment name
374
commands (list[str]): Commands to execute
375
376
Returns:
377
Prepared execution context
378
"""
379
```
380
381
## Usage Examples
382
383
### Basic Application Setup
384
385
```python
386
from hatch.cli.application import Application
387
from hatch.project.core import Project
388
from pathlib import Path
389
390
# Create application instance
391
app = Application(
392
exit_func=lambda code: exit(code),
393
verbosity=1,
394
enable_color=True,
395
interactive=True
396
)
397
398
# Set project
399
app.project = Project(Path.cwd())
400
401
# Access configuration
402
config = app.config
403
print(f"Mode: {config.mode}")
404
print(f"Data dir: {app.data_dir}")
405
```
406
407
### Environment Management
408
409
```python
410
from hatch.cli.application import Application
411
412
app = Application(lambda code: exit(code))
413
414
# Get environment
415
env = app.get_environment("test")
416
417
# Check if environment exists
418
if not env.exists():
419
print("Creating environment...")
420
env.create()
421
422
# Prepare environment
423
app.prepare_environment(env)
424
425
# Run commands
426
context = ExecutionContext(
427
environment=env,
428
shell_commands=["python --version"]
429
)
430
app.run_shell_commands(context)
431
```
432
433
### Configuration Access
434
435
```python
436
from hatch.cli.application import Application
437
438
app = Application(lambda code: exit(code))
439
440
# Load configuration
441
app.config_file.load()
442
443
# Access configuration values
444
config = app.config
445
print(f"Default shell: {config.shell}")
446
print(f"Project mode: {config.mode}")
447
448
# Access project settings
449
if config.project:
450
print(f"Default project: {config.project}")
451
452
# Access plugin configuration
453
plugins = app.plugins
454
print(f"Available plugins: {list(plugins.list_name_plugin())}")
455
```
456
457
### Error Handling
458
459
```python
460
from hatch.cli.application import Application
461
from hatch.errors import HatchError
462
463
app = Application(lambda code: exit(code))
464
465
try:
466
# Attempt operation
467
env = app.get_environment("nonexistent")
468
env.create()
469
except HatchError as e:
470
app.display_error(f"Operation failed: {e}")
471
app.abort(code=1)
472
except Exception as e:
473
app.display_error(f"Unexpected error: {e}")
474
app.abort(code=2)
475
```
476
477
### Plugin Integration
478
479
```python
480
from hatch.cli.application import Application
481
482
app = Application(lambda code: exit(code))
483
484
# Initialize plugins
485
app.plugins.initialize()
486
487
# Get plugin manager
488
plugins = app.plugins
489
490
# Register plugins
491
env_plugins = plugins.hatch_register_environment()
492
publisher_plugins = plugins.hatch_register_publisher()
493
494
print(f"Environment plugins: {list(env_plugins.keys())}")
495
print(f"Publisher plugins: {list(publisher_plugins.keys())}")
496
```