or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-parsing.mdcollections.mdconfiguration.mdindex.mdsubprocess-runners.mdtask-execution.mdwatchers.md

cli-parsing.mddocs/

0

# CLI Argument Parsing

1

2

Invoke provides a comprehensive argument parsing system that supports flags, options, positional arguments, help generation, and complex argument types with automatic CLI generation from task signatures.

3

4

## Capabilities

5

6

### Parser Class

7

8

Main CLI argument parser supporting contexts, flags, options, and positional arguments.

9

10

```python { .api }

11

class Parser:

12

"""

13

Main CLI argument parser.

14

15

Handles parsing command-line arguments into structured contexts with

16

support for flags, options, positional arguments, and help generation.

17

18

Attributes:

19

- contexts (list): List of parsing contexts

20

- initial (ParserContext): Initial parsing context

21

- ignore_unknown (bool): Whether to ignore unknown arguments

22

"""

23

24

def __init__(self, contexts=None, initial=None, ignore_unknown=False):

25

"""

26

Initialize Parser.

27

28

Parameters:

29

- contexts (list, optional): Parsing contexts to use

30

- initial (ParserContext, optional): Initial context

31

- ignore_unknown (bool): Ignore unknown arguments instead of erroring

32

"""

33

34

def parse_argv(self, argv):

35

"""

36

Parse command-line arguments.

37

38

Parameters:

39

- argv (list): Command-line arguments to parse

40

41

Returns:

42

ParseResult: Parsed arguments organized by context

43

44

Raises:

45

ParseError: If argument parsing fails

46

"""

47

48

def print_help(self, name=None, text=None):

49

"""

50

Print help text for parser.

51

52

Parameters:

53

- name (str, optional): Program name

54

- text (str, optional): Additional help text

55

"""

56

```

57

58

### Argument Class

59

60

Command-line argument definition with validation and type conversion.

61

62

```python { .api }

63

class Argument:

64

"""

65

Command-line argument definition.

66

67

Defines a single command-line argument including its names, type,

68

default value, help text, and parsing behavior.

69

70

Attributes:

71

- names (list): Argument names (including aliases)

72

- kind (type): Argument type (str, int, bool, etc.)

73

- default: Default value

74

- help (str): Help text

75

- positional (bool): Whether argument is positional

76

- optional (bool): Whether argument is optional

77

- incrementable (bool): Whether argument can be repeated to increment value

78

- iterable (bool): Whether argument accepts multiple values

79

- attr_name (str): Attribute name for storing parsed value

80

"""

81

82

def __init__(self, names=None, kind=str, default=None, help=None, positional=False, optional=None, incrementable=False, iterable=False, attr_name=None):

83

"""

84

Initialize Argument.

85

86

Parameters:

87

- names (list/str): Argument name(s)

88

- kind (type): Argument type for conversion

89

- default: Default value if not provided

90

- help (str): Help text description

91

- positional (bool): Whether this is a positional argument

92

- optional (bool): Whether argument is optional

93

- incrementable (bool): Can be repeated to increment (e.g., -vvv)

94

- iterable (bool): Accepts multiple values

95

- attr_name (str): Attribute name for parsed value storage

96

"""

97

98

@property

99

def name(self):

100

"""Primary argument name."""

101

102

@property

103

def nicknames(self):

104

"""Alternative argument names."""

105

106

@property

107

def takes_value(self):

108

"""Whether argument takes a value."""

109

110

def value_set(self, given):

111

"""

112

Set argument value with type conversion.

113

114

Parameters:

115

- given: Raw value to set

116

"""

117

118

@property

119

def value(self):

120

"""Current argument value."""

121

122

@property

123

def got_value(self):

124

"""Whether argument received a value."""

125

```

126

127

### ParserContext Class

128

129

Parser execution context containing parsed arguments for a specific command or task.

130

131

```python { .api }

132

class ParserContext:

133

"""

134

Parser context containing arguments for a specific parsing scope.

135

136

Represents the parsed arguments for a single command, task, or parsing

137

context within a larger argument parsing operation.

138

139

Attributes:

140

- name (str): Context name

141

- aliases (list): Context aliases

142

- args (list): Parsed arguments

143

- positional_args (list): Positional arguments

144

- seen_flags (set): Flags that were encountered

145

"""

146

147

def __init__(self, name=None, aliases=None, args=None):

148

"""

149

Initialize ParserContext.

150

151

Parameters:

152

- name (str, optional): Context name

153

- aliases (list, optional): Context aliases

154

- args (list, optional): Arguments for this context

155

"""

156

157

def add_arg(self, *args, **kwargs):

158

"""

159

Add argument to this context.

160

161

Parameters:

162

- *args, **kwargs: Arguments passed to Argument constructor

163

164

Returns:

165

Argument: Added argument object

166

"""

167

168

def help_tuples(self):

169

"""

170

Generate help text tuples for arguments.

171

172

Returns:

173

list: List of (names, help_text) tuples

174

"""

175

176

def as_kwargs(self):

177

"""

178

Convert parsed arguments to keyword arguments dictionary.

179

180

Returns:

181

dict: Parsed arguments as keyword arguments

182

"""

183

184

def __getitem__(self, key):

185

"""Get argument value by name."""

186

187

def __contains__(self, key):

188

"""Test if argument exists."""

189

190

def __iter__(self):

191

"""Iterate over argument names."""

192

```

193

194

### ParseResult Class

195

196

Container for complete parsing results from multiple contexts.

197

198

```python { .api }

199

class ParseResult(list):

200

"""

201

Parse result containing multiple parser contexts.

202

203

Behaves as a list of ParserContext objects representing the complete

204

parsing result from command-line arguments.

205

"""

206

207

def __getitem__(self, index):

208

"""Get context by index or name."""

209

210

def __iter__(self):

211

"""Iterate over contexts."""

212

213

def remainder(self):

214

"""Get unparsed remainder arguments."""

215

```

216

217

### Program Class

218

219

High-level CLI program management integrating parsing with task execution.

220

221

```python { .api }

222

class Program:

223

"""

224

Top-level CLI program management.

225

226

Coordinates argument parsing, task loading, help generation, and

227

task execution for complete CLI application functionality.

228

229

Attributes:

230

- name (str): Program name

231

- namespace (Collection): Task namespace

232

- config_class (type): Configuration class to use

233

- executor_class (type): Executor class to use

234

- loader_class (type): Collection loader class

235

- parser_class (type): Parser class to use

236

- config (Config): Program configuration

237

- initial_context (Context): Initial execution context

238

"""

239

240

def __init__(self, name=None, namespace=None, version=None, config_class=None, executor_class=None, loader_class=None, parser_class=None):

241

"""

242

Initialize Program.

243

244

Parameters:

245

- name (str, optional): Program name

246

- namespace (Collection, optional): Task collection

247

- version (str, optional): Program version

248

- config_class (type, optional): Config class

249

- executor_class (type, optional): Executor class

250

- loader_class (type, optional): Loader class

251

- parser_class (type, optional): Parser class

252

"""

253

254

def run(self, argv=None, exit=None):

255

"""

256

Run the program with given arguments.

257

258

Parameters:

259

- argv (list, optional): Command-line arguments

260

- exit (bool, optional): Whether to exit on completion

261

262

Returns:

263

any: Program result

264

"""

265

266

def parse_core(self, argv):

267

"""

268

Parse core program arguments.

269

270

Parameters:

271

- argv (list): Command-line arguments

272

273

Returns:

274

tuple: (core_args, task_args)

275

"""

276

277

def parse_tasks(self, args):

278

"""

279

Parse task-specific arguments.

280

281

Parameters:

282

- args (list): Task arguments to parse

283

284

Returns:

285

ParseResult: Parsed task arguments

286

"""

287

288

def execute(self, *args, **kwargs):

289

"""

290

Execute parsed tasks.

291

292

Parameters:

293

- *args, **kwargs: Execution arguments

294

"""

295

296

def print_help(self):

297

"""Print program help text."""

298

299

def print_version(self):

300

"""Print program version."""

301

302

def list_tasks(self, format='nested'):

303

"""

304

List available tasks.

305

306

Parameters:

307

- format (str): Output format ('nested', 'flat', 'json')

308

"""

309

```

310

311

## Usage Examples

312

313

### Basic Argument Parsing

314

315

```python

316

from invoke.parser import Parser, Argument, ParserContext

317

318

# Create argument definitions

319

ctx = ParserContext(name='mytask')

320

ctx.add_arg('--verbose', '-v', kind=bool, help='Verbose output')

321

ctx.add_arg('--count', '-c', kind=int, default=1, help='Repeat count')

322

ctx.add_arg('filename', positional=True, help='File to process')

323

324

# Create parser

325

parser = Parser([ctx])

326

327

# Parse arguments

328

result = parser.parse_argv(['mytask', '--verbose', '--count', '3', 'data.txt'])

329

330

# Access parsed values

331

task_ctx = result[0]

332

print(task_ctx.as_kwargs()) # {'verbose': True, 'count': 3, 'filename': 'data.txt'}

333

```

334

335

### Task Argument Integration

336

337

```python

338

from invoke import task

339

340

@task(help={'name': 'Name to greet', 'loud': 'Use uppercase'})

341

def hello(ctx, name='World', loud=False):

342

"""Say hello to someone."""

343

greeting = f"Hello {name}!"

344

if loud:

345

greeting = greeting.upper()

346

print(greeting)

347

348

# CLI usage:

349

# invoke hello --name John --loud

350

# invoke hello -n John -l

351

```

352

353

### Complex Argument Types

354

355

```python

356

from invoke import task

357

358

@task(

359

iterable=['exclude'], # Can specify multiple --exclude args

360

incrementable=['verbose'] # Can use -v, -vv, -vvv for levels

361

)

362

def process(ctx, file='data.txt', exclude=None, verbose=0, dry_run=False):

363

"""Process file with options."""

364

excludes = exclude or []

365

366

if verbose >= 1:

367

print(f"Processing {file}")

368

if verbose >= 2:

369

print(f"Excluding: {excludes}")

370

if verbose >= 3:

371

print("Debug mode enabled")

372

373

if dry_run:

374

print("Dry run - no changes made")

375

else:

376

# Do actual processing

377

pass

378

379

# CLI usage:

380

# invoke process --file data.csv --exclude logs --exclude temp -vvv --dry-run

381

```

382

383

### Custom Parser Usage

384

385

```python

386

from invoke.parser import Parser, Argument, ParserContext

387

388

# Create contexts for different commands

389

deploy_ctx = ParserContext('deploy')

390

deploy_ctx.add_arg('--env', default='staging', help='Target environment')

391

deploy_ctx.add_arg('--force', kind=bool, help='Force deployment')

392

393

test_ctx = ParserContext('test')

394

test_ctx.add_arg('--coverage', kind=bool, help='Generate coverage report')

395

test_ctx.add_arg('--pattern', help='Test pattern to run')

396

397

# Create parser with multiple contexts

398

parser = Parser([deploy_ctx, test_ctx])

399

400

# Parse different command sets

401

deploy_result = parser.parse_argv(['deploy', '--env', 'production', '--force'])

402

test_result = parser.parse_argv(['test', '--coverage', '--pattern', 'test_*.py'])

403

```

404

405

### Program Integration

406

407

```python

408

from invoke import Program, Collection, task

409

410

@task

411

def hello(ctx, name='World'):

412

"""Say hello."""

413

print(f"Hello {name}!")

414

415

@task

416

def goodbye(ctx, name='World'):

417

"""Say goodbye."""

418

print(f"Goodbye {name}!")

419

420

# Create task collection

421

ns = Collection(hello, goodbye)

422

423

# Create program

424

program = Program(name='greetings', namespace=ns, version='1.0.0')

425

426

# Run program (this handles all argument parsing)

427

if __name__ == '__main__':

428

program.run()

429

430

# CLI usage:

431

# python greetings.py hello --name John

432

# python greetings.py goodbye --name Jane

433

# python greetings.py --help

434

# python greetings.py --version

435

```

436

437

### Help Generation

438

439

```python

440

from invoke import task

441

442

@task(help={

443

'env': 'Target environment (staging, production)',

444

'force': 'Skip confirmation prompts',

445

'rollback': 'Rollback to previous version if deployment fails'

446

})

447

def deploy(ctx, env='staging', force=False, rollback=True):

448

"""

449

Deploy application to specified environment.

450

451

This command handles the complete deployment process including:

452

- Building the application

453

- Running tests

454

- Deploying to target environment

455

- Running health checks

456

"""

457

# Implementation here

458

pass

459

460

# CLI help output:

461

# invoke deploy --help

462

#

463

# Usage: invoke [--core-opts] deploy [--options] [other tasks here ...]

464

#

465

# Docstring:

466

# Deploy application to specified environment.

467

#

468

# This command handles the complete deployment process including:

469

# - Building the application

470

# - Running tests

471

# - Deploying to target environment

472

# - Running health checks

473

#

474

# Options:

475

# -e STRING, --env=STRING Target environment (staging, production)

476

# -f, --force Skip confirmation prompts

477

# -r, --rollback Rollback to previous version if deployment fails

478

```

479

480

### Error Handling

481

482

```python

483

from invoke.parser import Parser, ParserContext

484

from invoke.exceptions import ParseError

485

486

try:

487

ctx = ParserContext('task')

488

ctx.add_arg('--count', kind=int, help='Number of items')

489

490

parser = Parser([ctx])

491

result = parser.parse_argv(['task', '--count', 'not-a-number'])

492

except ParseError as e:

493

print(f"Argument parsing failed: {e}")

494

# Handle parsing error gracefully

495

```