0
# Command Line Interface
1
2
YAPF provides comprehensive command-line tools for formatting Python code, including the main `yapf` formatter and the `yapf-diff` utility for formatting only changed lines in patches. The CLI supports various options for batch processing, parallel execution, and integration with development workflows.
3
4
## Capabilities
5
6
### Main Command Line Interface
7
8
The primary YAPF command-line interface for formatting Python files and directories.
9
10
```python { .api }
11
def main(argv):
12
"""
13
Main command-line entry point for YAPF.
14
15
Args:
16
argv (list): Command-line arguments including program name
17
18
Returns:
19
int: Exit code (0 for success, non-zero for error)
20
With --diff: 0 if no changes, non-zero if changes found
21
22
Raises:
23
YapfError: If none of the supplied files were Python files
24
"""
25
26
def run_main():
27
"""
28
Console script entry point with exception handling.
29
30
Calls main() with sys.argv and handles YapfError exceptions
31
by printing error messages and exiting with code 1.
32
"""
33
```
34
35
### Batch File Processing
36
37
Format multiple files with various processing options.
38
39
```python { .api }
40
def FormatFiles(filenames, lines, style_config=None, no_local_style=False,
41
in_place=False, print_diff=False, parallel=False,
42
quiet=False, verbose=False, print_modified=False):
43
"""
44
Format multiple files with comprehensive options.
45
46
Args:
47
filenames (list): List of file paths to reformat
48
lines (list): List of (start, end) tuples for line ranges to format
49
style_config (str): Style name or path to configuration file
50
no_local_style (bool): Don't search for directory-local style config
51
in_place (bool): Modify files in place
52
print_diff (bool): Show diff instead of formatted code
53
parallel (bool): Use parallel processing for multiple files
54
quiet (bool): Output nothing and set return value only
55
verbose (bool): Print filenames while processing
56
print_modified (bool): Print names of modified files
57
58
Returns:
59
bool: True if any source code was changed
60
"""
61
```
62
63
## Command Line Usage
64
65
### Basic Formatting
66
67
```bash
68
# Format a single file to stdout
69
yapf my_script.py
70
71
# Format multiple files to stdout
72
yapf file1.py file2.py module.py
73
74
# Read from stdin
75
cat my_script.py | yapf
76
77
# Format all .py files in current directory
78
yapf *.py
79
```
80
81
### In-Place Editing
82
83
```bash
84
# Format file in place
85
yapf -i my_script.py
86
yapf --in-place my_script.py
87
88
# Format multiple files in place
89
yapf -i *.py
90
91
# Format all Python files in a directory recursively
92
yapf -r -i my_project/
93
yapf --recursive --in-place my_project/
94
```
95
96
### Diff Output
97
98
```bash
99
# Show diff of changes
100
yapf -d my_script.py
101
yapf --diff my_script.py
102
103
# Show diff for multiple files
104
yapf -d *.py
105
106
# Use with git to see changes
107
git diff --name-only | xargs yapf -d
108
```
109
110
### Style Configuration
111
112
```bash
113
# Use specific predefined style
114
yapf --style=pep8 my_script.py
115
yapf --style=google my_script.py
116
yapf --style=facebook my_script.py
117
yapf --style=yapf my_script.py
118
119
# Use custom style file
120
yapf --style=/path/to/.style.yapf my_script.py
121
yapf --style=./pyproject.toml my_script.py
122
123
# Disable local style discovery
124
yapf --no-local-style --style=pep8 my_script.py
125
```
126
127
### Line Range Formatting
128
129
```bash
130
# Format specific lines (1-indexed)
131
yapf -l 1-10 my_script.py # Lines 1 to 10
132
yapf -l 5-5 my_script.py # Line 5 only
133
yapf -l 1-10 -l 20-30 my_script.py # Multiple ranges
134
135
# Cannot use line ranges with multiple files
136
yapf -l 1-10 file1.py file2.py # ERROR
137
```
138
139
### Processing Options
140
141
```bash
142
# Parallel processing for multiple files
143
yapf -p *.py
144
yapf --parallel -i my_project/*.py
145
146
# Quiet mode (only set exit code)
147
yapf -q my_script.py
148
yapf --quiet -i *.py
149
150
# Verbose mode (show filenames being processed)
151
yapf -vv -i my_project/
152
yapf --verbose --in-place my_project/
153
154
# Print names of modified files
155
yapf -m -i *.py
156
yapf --print-modified --in-place *.py
157
```
158
159
### Exclusion Patterns
160
161
```bash
162
# Exclude specific patterns
163
yapf -r -i --exclude='*_pb2.py' my_project/
164
yapf -r -i --exclude='test_*.py' --exclude='*_test.py' src/
165
166
# Multiple exclusion patterns
167
yapf -r -i \
168
--exclude='*_pb2.py' \
169
--exclude='*_test.py' \
170
--exclude='vendor/*' \
171
my_project/
172
```
173
174
### Help and Version
175
176
```bash
177
# Show version
178
yapf -v
179
yapf --version
180
181
# Show help
182
yapf -h
183
yapf --help
184
185
# Show style help with current settings
186
yapf --style-help
187
yapf --style=google --style-help
188
```
189
190
## yapf-diff Utility
191
192
Format only changed lines in diff patches, useful for formatting code in pull requests or commits.
193
194
### Usage
195
196
```bash
197
# Format lines changed in git diff
198
git diff -U0 --no-color HEAD^ | yapf-diff -i
199
200
# Format lines changed in current working directory
201
git diff -U0 --no-color | yapf-diff -i
202
203
# Format staged changes
204
git diff -U0 --no-color --cached | yapf-diff -i
205
206
# Format changes in SVN
207
svn diff --diff-cmd=diff -x-U0 | yapf-diff -p0 -i
208
209
# Show diff instead of applying changes
210
git diff -U0 --no-color HEAD^ | yapf-diff
211
212
# Specify number of prefix components to strip
213
git diff -U0 --no-color HEAD^ | yapf-diff -p1 -i
214
```
215
216
### Integration Examples
217
218
```bash
219
# Pre-commit hook
220
#!/bin/bash
221
git diff -U0 --no-color --cached | yapf-diff -i -p1
222
223
# Format current branch changes
224
git diff -U0 --no-color main... | yapf-diff -i
225
226
# Format specific commit
227
git show --format="" -U0 --no-color <commit> | yapf-diff -p1 -i
228
```
229
230
## Programmatic Usage
231
232
### Command Line Integration
233
234
```python
235
import yapf
236
import sys
237
238
# Call main function directly
239
exit_code = yapf.main(['yapf', '-i', 'my_script.py'])
240
241
# Use run_main for console script behavior
242
sys.argv = ['yapf', '--style=google', '-d', 'my_script.py']
243
yapf.run_main() # Will print diff and exit
244
```
245
246
### Batch Processing
247
248
```python
249
from yapf import FormatFiles
250
251
# Format multiple files
252
files = ['file1.py', 'file2.py', 'module.py']
253
changed = FormatFiles(
254
filenames=files,
255
lines=None,
256
style_config='google',
257
in_place=True,
258
verbose=True
259
)
260
261
print(f"Modified files: {changed}")
262
263
# Format with parallel processing
264
changed = FormatFiles(
265
filenames=files,
266
lines=None,
267
style_config='pep8',
268
in_place=True,
269
parallel=True,
270
print_modified=True
271
)
272
273
# Format specific line ranges
274
lines = [(1, 10), (20, 30)] # Format lines 1-10 and 20-30
275
changed = FormatFiles(
276
filenames=['single_file.py'],
277
lines=lines,
278
style_config='facebook',
279
print_diff=True
280
)
281
```
282
283
### Custom CLI Tools
284
285
```python
286
import argparse
287
from yapf import FormatFiles
288
from yapf.yapflib import file_resources
289
290
def custom_formatter():
291
"""Custom formatting tool with project-specific defaults."""
292
parser = argparse.ArgumentParser(description='Custom Python formatter')
293
parser.add_argument('files', nargs='+', help='Files to format')
294
parser.add_argument('--style', default='google', help='Formatting style')
295
parser.add_argument('--check', action='store_true',
296
help='Check if files need formatting')
297
298
args = parser.parse_args()
299
300
# Get all Python files
301
python_files = file_resources.GetCommandLineFiles(
302
args.files,
303
recursive=True,
304
exclude_patterns=['*_pb2.py', 'test_*.py']
305
)
306
307
# Format files
308
changed = FormatFiles(
309
filenames=python_files,
310
lines=None,
311
style_config=args.style,
312
in_place=not args.check,
313
print_diff=args.check,
314
verbose=True
315
)
316
317
if args.check and changed:
318
print("Files need formatting!")
319
return 1
320
321
return 0
322
323
if __name__ == '__main__':
324
exit(custom_formatter())
325
```
326
327
## Integration Patterns
328
329
### Pre-commit Hooks
330
331
#### Git pre-commit hook
332
333
```bash
334
#!/bin/bash
335
# .git/hooks/pre-commit
336
337
# Format staged Python files
338
git diff --cached --name-only --diff-filter=ACMR | \
339
grep '\.py$' | \
340
xargs yapf -i
341
342
# Add formatted files back to staging
343
git diff --cached --name-only --diff-filter=ACMR | \
344
grep '\.py$' | \
345
xargs git add
346
```
347
348
#### Pre-commit framework
349
350
```yaml
351
# .pre-commit-config.yaml
352
repos:
353
- repo: https://github.com/google/yapf
354
rev: v0.43.0
355
hooks:
356
- id: yapf
357
args: [--style=google]
358
- id: yapf
359
name: yapf-diff
360
entry: yapf-diff
361
language: python
362
files: \.py$
363
minimum_pre_commit_version: 0.15.0
364
```
365
366
### CI/CD Integration
367
368
```bash
369
# Check formatting in CI
370
yapf -r -d my_project/
371
if [ $? -ne 0 ]; then
372
echo "Code is not properly formatted"
373
exit 1
374
fi
375
376
# Format check with specific style
377
yapf -r -d --style=google src/
378
```
379
380
### Editor Integration
381
382
#### VS Code settings
383
384
```json
385
{
386
"python.formatting.provider": "yapf",
387
"python.formatting.yapfArgs": ["--style=google"],
388
"editor.formatOnSave": true
389
}
390
```
391
392
#### Vim configuration
393
394
```vim
395
" Format current file with YAPF
396
nnoremap <leader>f :!yapf -i %<CR>
397
398
" Format selection
399
vnoremap <leader>f :!yapf<CR>
400
```
401
402
## Exit Codes
403
404
- `0`: Success (no errors)
405
- `1`: Error occurred (syntax error, file not found, etc.)
406
- With `--diff` or `--quiet`: `0` if no changes needed, non-zero if changes found
407
408
## Common Workflows
409
410
### Format entire project
411
412
```bash
413
# Initial formatting
414
yapf -r -i --style=google my_project/
415
416
# Check if formatting needed
417
yapf -r -d my_project/
418
echo "Exit code: $?"
419
```
420
421
### Format only changed files
422
423
```bash
424
# Format files modified in last commit
425
git diff --name-only HEAD~1 | grep '\.py$' | xargs yapf -i
426
427
# Format unstaged changes
428
git diff --name-only | grep '\.py$' | xargs yapf -i
429
```
430
431
### Format with exclusions
432
433
```bash
434
# Exclude generated and test files
435
yapf -r -i \
436
--exclude='*_pb2.py' \
437
--exclude='*_test.py' \
438
--exclude='test_*.py' \
439
--exclude='migrations/*.py' \
440
my_project/
441
```