0
# CLI System
1
2
Foliant's command-line interface provides the primary way to build documentation projects. Built on the `cliar` library, it features an extensible architecture that supports custom CLI commands and interactive backend selection.
3
4
## Capabilities
5
6
### Main Entry Point
7
8
The primary entry point for the Foliant CLI that dynamically inherits from all available CLI extensions.
9
10
```python { .api }
11
def entry_point():
12
"""
13
Main entry point for the foliant command.
14
Creates and runs the dynamic Foliant CLI class.
15
"""
16
17
class Foliant(*get_available_clis().values()):
18
"""
19
Dynamic CLI class that inherits from all available CLI extensions.
20
Primary interface for the foliant command-line tool.
21
"""
22
def _root(self, version=False):
23
"""
24
Root command handler.
25
26
Parameters:
27
- version (bool): Show version and exit if True
28
"""
29
```
30
31
### Base CLI Class
32
33
Foundation class for all CLI extensions providing logging and common functionality.
34
35
```python { .api }
36
class BaseCli(Cliar):
37
"""
38
Base CLI class that all CLI extensions must inherit from.
39
Provides logging setup and common CLI functionality.
40
"""
41
def __init__(self, logs_dir=None):
42
"""
43
Initialize base CLI with logging configuration.
44
45
Parameters:
46
- logs_dir (str, optional): Directory to store log files
47
"""
48
```
49
50
### Make Command
51
52
Core CLI command for building documentation with various backends and output formats.
53
54
```python { .api }
55
class Cli(BaseCli):
56
"""Main CLI class for the make command."""
57
58
def make(self, target, backend='', project_path=Path('.'),
59
config_file_name='foliant.yml', logs_dir='',
60
quiet=False, keep_tmp=False, debug=False):
61
"""
62
Build documentation target with specified backend.
63
64
Parameters:
65
- target (str): Output format (html, pdf, docx, etc.)
66
- backend (str): Backend to use (mkdocs, pandoc, etc.)
67
- project_path (Path): Path to Foliant project directory
68
- config_file_name (str): Configuration file name
69
- logs_dir (str): Directory for log files
70
- quiet (bool): Hide output except results
71
- keep_tmp (bool): Preserve temporary directory after build
72
- debug (bool): Enable debug logging
73
74
Returns:
75
str: Path to generated output
76
"""
77
78
@staticmethod
79
def validate_backend(backend: str, target: str) -> bool:
80
"""
81
Validate that backend exists and supports target format.
82
83
Parameters:
84
- backend (str): Backend name to validate
85
- target (str): Target format to check
86
87
Returns:
88
bool: True if valid
89
90
Raises:
91
BackendError: If backend not found or doesn't support target
92
"""
93
94
@staticmethod
95
def get_matching_backend(target: str, available_backends: Dict[str, Tuple[str]]) -> str:
96
"""
97
Find backend that supports target format, with user prompt if multiple.
98
99
Parameters:
100
- target (str): Target format to find backend for
101
- available_backends (dict): Available backends and their targets
102
103
Returns:
104
str: Selected backend name
105
106
Raises:
107
BackendError: If no matching backend found or user cancels
108
"""
109
110
def get_config(self, project_path: Path, config_file_name: str,
111
quiet=False, debug=False) -> dict:
112
"""
113
Parse and validate project configuration.
114
115
Parameters:
116
- project_path (Path): Project directory path
117
- config_file_name (str): Configuration file name
118
- quiet (bool): Suppress output
119
- debug (bool): Enable debug mode
120
121
Returns:
122
dict: Parsed configuration
123
124
Raises:
125
ConfigError: If configuration parsing fails
126
"""
127
128
def clean_registry(self, project_path):
129
"""
130
Clean multiproject cache registry files.
131
132
Parameters:
133
- project_path (str): Project directory path
134
"""
135
```
136
137
### Backend Validator
138
139
Interactive validation for backend selection prompts.
140
141
```python { .api }
142
class BackendValidator(Validator):
143
"""Validator for interactive backend selection prompt."""
144
145
def __init__(self, available_backends: List[str]):
146
"""
147
Initialize validator with available backends.
148
149
Parameters:
150
- available_backends (list): List of available backend names
151
"""
152
153
def validate(self, document):
154
"""
155
Validate user's backend selection.
156
157
Parameters:
158
- document: Input document from prompt_toolkit
159
160
Raises:
161
ValidationError: If backend not in available list
162
"""
163
```
164
165
### Exception Classes
166
167
```python { .api }
168
class ConfigError(Exception):
169
"""Raised when configuration parsing fails."""
170
171
class BackendError(Exception):
172
"""Raised when backend validation or selection fails."""
173
```
174
175
## Usage Examples
176
177
### Basic Command Execution
178
179
```python
180
from foliant.cli.make import Cli
181
from pathlib import Path
182
183
# Create CLI instance
184
cli = Cli()
185
186
# Simple HTML build
187
result = cli.make('html')
188
print(f"Documentation built at: {result}")
189
190
# PDF build with specific backend
191
result = cli.make('pdf', backend='pandoc')
192
193
# Build with full options
194
result = cli.make(
195
target='html',
196
backend='mkdocs',
197
project_path=Path('/path/to/docs'),
198
config_file_name='custom.yml',
199
quiet=True,
200
debug=False
201
)
202
```
203
204
### Backend Validation
205
206
```python
207
from foliant.cli.make import Cli
208
209
# Validate backend supports target
210
try:
211
Cli.validate_backend('pandoc', 'pdf') # Returns True
212
Cli.validate_backend('mkdocs', 'pdf') # Raises BackendError
213
except BackendError as e:
214
print(f"Backend validation failed: {e}")
215
216
# Find matching backend
217
from foliant.utils import get_available_backends
218
219
available = get_available_backends()
220
backend = Cli.get_matching_backend('html', available)
221
print(f"Selected backend: {backend}")
222
```
223
224
### Configuration Parsing
225
226
```python
227
from foliant.cli.make import Cli
228
from pathlib import Path
229
230
cli = Cli()
231
232
try:
233
config = cli.get_config(
234
project_path=Path('.'),
235
config_file_name='foliant.yml',
236
debug=True
237
)
238
print(f"Project title: {config.get('title', 'Untitled')}")
239
except ConfigError as e:
240
print(f"Config error: {e}")
241
```