or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdcomplexity.mdhalstead.mdindex.mdmaintainability.mdraw-metrics.mdvisitors.md

cli.mddocs/

0

# Command Line Interface

1

2

Comprehensive CLI with four analysis commands (cc, raw, mi, hal) supporting multiple output formats, configuration files, and batch processing capabilities. Designed for integration with CI/CD pipelines, code quality tools, and automated analysis workflows.

3

4

## Capabilities

5

6

### Main CLI Program

7

8

Central program instance and configuration management for all radon commands.

9

10

```python { .api }

11

# Main program instance (mando.Program)

12

program = Program(version=radon.__version__)

13

14

class Config:

15

"""

16

Configuration object for analysis parameters.

17

18

Stores analysis settings and provides access to configuration values

19

through attribute access and keyword parameters.

20

"""

21

22

def __init__(self, **kwargs):

23

"""

24

Create configuration with keyword parameters.

25

26

Parameters:

27

- **kwargs: Configuration values as keyword arguments

28

"""

29

30

@classmethod

31

def from_function(cls, func):

32

"""

33

Create Config object from function defaults.

34

35

Extracts default parameter values from a function's signature

36

to create a configuration object.

37

38

Parameters:

39

- func: Function with default parameters

40

41

Returns:

42

Config: Configuration object with function defaults

43

"""

44

45

class FileConfig:

46

"""

47

File-based configuration reader supporting multiple formats.

48

49

Reads configuration from setup.cfg, radon.cfg, pyproject.toml,

50

and environment variables.

51

"""

52

53

def get_value(self, key, type, default):

54

"""

55

Get configuration value with type conversion.

56

57

Parameters:

58

- key (str): Configuration key name

59

- type: Target type (int, bool, str)

60

- default: Default value if key not found

61

62

Returns:

63

Converted configuration value or default

64

"""

65

66

@staticmethod

67

def file_config():

68

"""

69

Read configuration from various file sources.

70

71

Checks for configuration in:

72

- Environment variable RADONCFG

73

- radon.cfg in current directory

74

- pyproject.toml [tool.radon] section

75

- setup.cfg [radon] section

76

- ~/.radon.cfg in user home directory

77

78

Returns:

79

configparser.ConfigParser: Merged configuration

80

"""

81

82

@staticmethod

83

def toml_config():

84

"""

85

Read configuration from pyproject.toml file.

86

87

Returns:

88

dict: Configuration dictionary from TOML file

89

"""

90

```

91

92

### Analysis Commands

93

94

Core commands for different types of code analysis.

95

96

```python { .api }

97

@program.command

98

def cc(paths, min='A', max='F', show_complexity=False, average=False,

99

exclude=None, ignore=None, order='SCORE', json=False,

100

no_assert=False, show_closures=False, total_average=False,

101

xml=False, md=False, codeclimate=False, output_file=None,

102

include_ipynb=False, ipynb_cells=False):

103

"""

104

Analyze cyclomatic complexity (CC) of Python modules.

105

106

Computes McCabe's cyclomatic complexity and provides A-F rankings

107

for functions, methods, and classes.

108

109

Parameters:

110

- paths (list): Paths to Python files or directories to analyze

111

- min (str): Minimum complexity grade to display ('A'-'F')

112

- max (str): Maximum complexity grade to display ('A'-'F')

113

- show_complexity (bool): Show numeric complexity scores

114

- average (bool): Display average complexity at end

115

- exclude (str): Glob patterns for files to exclude

116

- ignore (str): Glob patterns for directories to ignore

117

- order (str): Sort order ('SCORE', 'LINES', 'ALPHA')

118

- json (bool): Output results as JSON

119

- no_assert (bool): Don't count assert statements

120

- show_closures (bool): Include nested functions/classes

121

- total_average (bool): Average unfiltered by min/max

122

- xml (bool): Output results as XML (CCM compatible)

123

- md (bool): Output results as Markdown

124

- codeclimate (bool): Output Code Climate format

125

- output_file (str): Write output to file instead of stdout

126

- include_ipynb (bool): Include Jupyter notebook files

127

- ipynb_cells (bool): Report individual notebook cells

128

"""

129

130

@program.command

131

def raw(paths, exclude=None, ignore=None, summary=False, json=False,

132

output_file=None, include_ipynb=False, ipynb_cells=False):

133

"""

134

Analyze raw code metrics (LOC, LLOC, comments, etc.).

135

136

Computes lines of code, logical lines, comments, blank lines,

137

and other basic code statistics.

138

139

Parameters:

140

- paths (list): Paths to Python files or directories to analyze

141

- exclude (str): Glob patterns for files to exclude

142

- ignore (str): Glob patterns for directories to ignore

143

- summary (bool): Display summary statistics

144

- json (bool): Output results as JSON

145

- output_file (str): Write output to file instead of stdout

146

- include_ipynb (bool): Include Jupyter notebook files

147

- ipynb_cells (bool): Report individual notebook cells

148

"""

149

150

@program.command

151

def mi(paths, min='A', max='C', multi=True, exclude=None, ignore=None,

152

show=False, json=False, sort=False, output_file=None,

153

include_ipynb=False, ipynb_cells=False):

154

"""

155

Analyze Maintainability Index of Python modules.

156

157

Computes compound maintainability metric combining Halstead volume,

158

cyclomatic complexity, and lines of code.

159

160

Parameters:

161

- paths (list): Paths to Python files or directories to analyze

162

- min (str): Minimum MI grade to display ('A', 'B', 'C')

163

- max (str): Maximum MI grade to display ('A', 'B', 'C')

164

- multi (bool): Count multi-line strings as comments

165

- exclude (str): Glob patterns for files to exclude

166

- ignore (str): Glob patterns for directories to ignore

167

- show (bool): Show actual MI numeric values

168

- json (bool): Output results as JSON

169

- sort (bool): Sort results in ascending order

170

- output_file (str): Write output to file instead of stdout

171

- include_ipynb (bool): Include Jupyter notebook files

172

- ipynb_cells (bool): Report individual notebook cells

173

"""

174

175

@program.command

176

def hal(paths, exclude=None, ignore=None, json=False, functions=False,

177

output_file=None, include_ipynb=False, ipynb_cells=False):

178

"""

179

Analyze Halstead complexity metrics of Python modules.

180

181

Computes software science metrics including volume, difficulty,

182

effort, time estimates, and bug predictions.

183

184

Parameters:

185

- paths (list): Paths to Python files or directories to analyze

186

- exclude (str): Glob patterns for files to exclude

187

- ignore (str): Glob patterns for directories to ignore

188

- json (bool): Output results as JSON

189

- functions (bool): Analyze by top-level functions instead of files

190

- output_file (str): Write output to file instead of stdout

191

- include_ipynb (bool): Include Jupyter notebook files

192

- ipynb_cells (bool): Report individual notebook cells

193

"""

194

```

195

196

### Output and Logging Functions

197

198

Functions for formatting and displaying analysis results.

199

200

```python { .api }

201

def log_result(harvester, **kwargs):

202

"""

203

Log results from a Harvester object with format selection.

204

205

Automatically selects output format based on keyword arguments

206

and delegates to appropriate formatter.

207

208

Parameters:

209

- harvester: Harvester instance with analysis results

210

- json (bool): Format as JSON

211

- xml (bool): Format as XML

212

- md (bool): Format as Markdown

213

- codeclimate (bool): Format for Code Climate

214

- stream: Output stream (default stdout)

215

- **kwargs: Additional formatting options

216

"""

217

218

def log(msg, *args, **kwargs):

219

"""

220

Log a message with formatting and indentation support.

221

222

Parameters:

223

- msg (str): Message template

224

- *args: Arguments for message formatting

225

- indent (int): Indentation level (4 spaces per level)

226

- delimiter (str): Line delimiter (default newline)

227

- noformat (bool): Skip string formatting

228

- stream: Output stream (default stdout)

229

"""

230

231

def log_list(lst, *args, **kwargs):

232

"""

233

Log a list of messages line by line.

234

235

Parameters:

236

- lst (list): List of messages to log

237

- *args, **kwargs: Passed to log() function

238

"""

239

240

def log_error(msg, *args, **kwargs):

241

"""

242

Log an error message with colored formatting.

243

244

Parameters:

245

- msg (str): Error message

246

- *args, **kwargs: Passed to log() function

247

"""

248

249

@contextmanager

250

def outstream(outfile=None):

251

"""

252

Context manager for output stream management.

253

254

Parameters:

255

- outfile (str): Output filename, or None for stdout

256

257

Yields:

258

file: Open file handle or stdout

259

"""

260

```

261

262

## Command-Line Usage Examples

263

264

### Cyclomatic Complexity Analysis

265

266

```bash

267

# Basic complexity analysis

268

radon cc src/

269

270

# Show numeric complexity scores

271

radon cc --show-complexity src/

272

273

# Filter by complexity range

274

radon cc --min B --max F src/

275

276

# Include average complexity

277

radon cc --average src/

278

279

# Sort by different criteria

280

radon cc --order LINES src/ # Sort by line number

281

radon cc --order ALPHA src/ # Sort alphabetically

282

283

# Different output formats

284

radon cc --json src/ # JSON output

285

radon cc --xml src/ # XML output (CCM compatible)

286

radon cc --md src/ # Markdown output

287

radon cc --codeclimate src/ # Code Climate format

288

289

# Save to file

290

radon cc --output-file complexity.json --json src/

291

292

# Include Jupyter notebooks

293

radon cc --include-ipynb --ipynb-cells notebooks/

294

```

295

296

### Raw Metrics Analysis

297

298

```bash

299

# Basic raw metrics

300

radon raw src/

301

302

# Show summary statistics

303

radon raw --summary src/

304

305

# JSON output for processing

306

radon raw --json src/

307

308

# Exclude test files

309

radon raw --exclude "*/tests/*" src/

310

311

# Ignore specific directories

312

radon raw --ignore "__pycache__,*.egg-info" src/

313

314

# Include Jupyter notebooks

315

radon raw --include-ipynb notebooks/

316

```

317

318

### Maintainability Index

319

320

```bash

321

# Basic MI analysis

322

radon mi src/

323

324

# Show numeric MI values

325

radon mi --show src/

326

327

# Filter by maintainability grade

328

radon mi --min B --max A src/ # Only high maintainability

329

330

# Sort results

331

radon mi --sort src/

332

333

# Don't count docstrings as comments

334

radon mi --no-multi src/

335

336

# JSON output

337

radon mi --json src/

338

```

339

340

### Halstead Metrics

341

342

```bash

343

# Basic Halstead analysis

344

radon hal src/

345

346

# Analyze by functions instead of files

347

radon hal --functions src/

348

349

# JSON output for detailed metrics

350

radon hal --json src/

351

352

# Save detailed analysis

353

radon hal --output-file halstead.json --json src/

354

```

355

356

## Configuration Files

357

358

Radon supports configuration through multiple file formats:

359

360

### setup.cfg

361

362

```ini

363

[radon]

364

exclude = */tests/*,*/migrations/*

365

ignore = __pycache__,.git

366

cc_min = B

367

cc_max = F

368

show_complexity = true

369

average = true

370

```

371

372

### pyproject.toml

373

374

```toml

375

[tool.radon]

376

exclude = "*/tests/*"

377

ignore = "__pycache__"

378

cc_min = "B"

379

show_complexity = true

380

average = true

381

```

382

383

### radon.cfg

384

385

```ini

386

[radon]

387

exclude = build/*,dist/*

388

cc_min = A

389

cc_max = F

390

show_complexity = true

391

```

392

393

## Programmatic CLI Usage

394

395

Using the CLI components from Python code:

396

397

```python

398

from radon.cli import Config, program

399

from radon.cli.harvest import CCHarvester

400

from radon.cli.tools import iter_filenames

401

import sys

402

403

# Create configuration

404

config = Config(

405

min='B',

406

max='F',

407

show_complexity=True,

408

exclude='*/tests/*',

409

order='SCORE'

410

)

411

412

# Use file discovery

413

paths = ['src/']

414

filenames = list(iter_filenames(paths, exclude=config.exclude))

415

print(f"Found {len(filenames)} Python files")

416

417

# Run complexity analysis

418

harvester = CCHarvester(paths, config)

419

harvester.run()

420

421

# Get results programmatically

422

results = harvester.results

423

for filename, analysis in results.items():

424

print(f"{filename}: {len(analysis)} blocks analyzed")

425

426

# Format as JSON

427

json_output = harvester.as_json()

428

print("JSON output generated")

429

430

# Format for terminal

431

for msg, args, kwargs in harvester.to_terminal():

432

if not kwargs.get('error', False):

433

print(msg.format(*args) if args else msg)

434

```

435

436

### Custom Harvester Usage

437

438

```python

439

from radon.cli.harvest import RawHarvester, MIHarvester, HCHarvester

440

from radon.cli import Config

441

442

config = Config(summary=True, exclude='*/tests/*')

443

444

# Raw metrics harvester

445

raw_harvester = RawHarvester(['src/'], config)

446

raw_harvester.run()

447

448

print("Raw metrics summary:")

449

raw_results = raw_harvester.results

450

total_loc = sum(metrics.loc for metrics in raw_results.values())

451

total_sloc = sum(metrics.sloc for metrics in raw_results.values())

452

print(f"Total LOC: {total_loc}")

453

print(f"Total SLOC: {total_sloc}")

454

455

# Maintainability index harvester

456

mi_config = Config(show=True, sort=True)

457

mi_harvester = MIHarvester(['src/'], mi_config)

458

mi_harvester.run()

459

460

# Halstead harvester

461

hal_config = Config(by_function=True)

462

hal_harvester = HCHarvester(['src/'], hal_config)

463

hal_harvester.run()

464

```

465

466

## Integration Examples

467

468

### CI/CD Pipeline Integration

469

470

```bash

471

#!/bin/bash

472

# ci-quality-check.sh

473

474

# Check complexity - fail if any function/class has F grade

475

if radon cc --min F --json src/ | grep -q '"rank": "F"'; then

476

echo "Error: Code contains F-grade complexity"

477

exit 1

478

fi

479

480

# Check maintainability - fail if average MI is too low

481

MI_SCORE=$(radon mi --json src/ | jq '.[] | .mi' | awk '{sum+=$1; count++} END {print sum/count}')

482

if (( $(echo "$MI_SCORE < 20" | bc -l) )); then

483

echo "Error: Maintainability index too low: $MI_SCORE"

484

exit 1

485

fi

486

487

echo "Code quality checks passed"

488

```

489

490

### Code Quality Reports

491

492

```python

493

import json

494

import subprocess

495

from pathlib import Path

496

497

def generate_quality_report(src_path):

498

"""Generate comprehensive code quality report."""

499

500

# Run all radon analyses

501

analyses = {}

502

503

# Complexity analysis

504

cc_result = subprocess.run(

505

['radon', 'cc', '--json', src_path],

506

capture_output=True, text=True

507

)

508

analyses['complexity'] = json.loads(cc_result.stdout)

509

510

# Raw metrics

511

raw_result = subprocess.run(

512

['radon', 'raw', '--json', src_path],

513

capture_output=True, text=True

514

)

515

analyses['raw'] = json.loads(raw_result.stdout)

516

517

# Maintainability index

518

mi_result = subprocess.run(

519

['radon', 'mi', '--json', src_path],

520

capture_output=True, text=True

521

)

522

analyses['maintainability'] = json.loads(mi_result.stdout)

523

524

# Generate summary report

525

report = {

526

'total_files': len(analyses['raw']),

527

'total_loc': sum(m['loc'] for m in analyses['raw'].values()),

528

'total_sloc': sum(m['sloc'] for m in analyses['raw'].values()),

529

'avg_complexity': calculate_avg_complexity(analyses['complexity']),

530

'avg_maintainability': calculate_avg_mi(analyses['maintainability']),

531

'quality_grade': determine_quality_grade(analyses)

532

}

533

534

return report

535

536

def calculate_avg_complexity(cc_data):

537

"""Calculate average complexity across all functions."""

538

total_complexity = 0

539

total_functions = 0

540

541

for file_data in cc_data.values():

542

for block in file_data:

543

total_complexity += block['complexity']

544

total_functions += 1

545

546

return total_complexity / total_functions if total_functions > 0 else 0

547

548

def calculate_avg_mi(mi_data):

549

"""Calculate average maintainability index."""

550

scores = [data['mi'] for data in mi_data.values()]

551

return sum(scores) / len(scores) if scores else 0

552

553

def determine_quality_grade(analyses):

554

"""Determine overall quality grade."""

555

avg_complexity = calculate_avg_complexity(analyses['complexity'])

556

avg_mi = calculate_avg_mi(analyses['maintainability'])

557

558

if avg_complexity <= 5 and avg_mi >= 20:

559

return 'A'

560

elif avg_complexity <= 10 and avg_mi >= 15:

561

return 'B'

562

elif avg_complexity <= 20 and avg_mi >= 10:

563

return 'C'

564

else:

565

return 'D'

566

567

# Usage

568

# report = generate_quality_report('src/')

569

# print(f"Quality Grade: {report['quality_grade']}")

570

```

571

572

## Error Handling and Debugging

573

574

The CLI handles various error conditions gracefully:

575

576

- **File not found**: Clear error messages for missing files/directories

577

- **Syntax errors**: Reports files with parsing errors and continues

578

- **Permission errors**: Handles files that cannot be read

579

- **Configuration errors**: Validates configuration values and provides defaults

580

- **Output errors**: Handles file write permissions and disk space issues

581

582

### Debug Mode

583

584

```bash

585

# Enable verbose output for troubleshooting

586

RADON_DEBUG=1 radon cc src/

587

588

# Check configuration loading

589

radon cc --help # Shows all available options and defaults

590

```

591

592

## Performance Considerations

593

594

- **Large codebases**: Use `--exclude` and `--ignore` to skip unnecessary files

595

- **Parallel processing**: Radon processes files sequentially; use shell scripting for parallelization

596

- **Memory usage**: JSON output can be memory-intensive for very large projects

597

- **Network filesystems**: Local analysis is faster than network-mounted directories

598

599

The CLI provides a comprehensive interface for all radon analysis capabilities while maintaining compatibility with automated workflows and integration tools.