0
# Task Definition and Execution
1
2
Task definition and execution forms the core of Invoke's functionality, allowing Python functions to be decorated and invoked from the command line with automatic argument parsing, help generation, and execution management.
3
4
## Capabilities
5
6
### Task Decorator
7
8
The primary decorator for converting Python functions into CLI-invokable tasks with rich metadata and argument handling.
9
10
```python { .api }
11
def task(*args, **kwargs):
12
"""
13
Decorator for converting functions into Task objects.
14
15
Parameters:
16
- name (str, optional): Task name (defaults to function name)
17
- aliases (tuple, optional): Alternative names for the task
18
- positional (list, optional): Arguments that should be positional
19
- optional (list, optional): Arguments that should be optional
20
- default (bool): Whether this task is the collection's default
21
- auto_shortflags (bool): Auto-generate short flags for arguments
22
- help (dict, optional): Help text for task and arguments
23
- pre (list, optional): Tasks to run before this task
24
- post (list, optional): Tasks to run after this task
25
- iterable (list, optional): Arguments that accept multiple values
26
- incrementable (list, optional): Arguments that can be repeated to increment
27
28
Returns:
29
Task: Decorated task object
30
"""
31
```
32
33
Usage example:
34
35
```python
36
from invoke import task
37
38
@task
39
def hello(ctx, name="World"):
40
"""Say hello to someone."""
41
print(f"Hello {name}!")
42
43
@task(help={'env': 'Target environment'})
44
def deploy(ctx, env='staging'):
45
"""Deploy to specified environment."""
46
ctx.run(f"deploy.sh {env}")
47
48
@task(aliases=['ls'])
49
def list_files(ctx):
50
"""List files in current directory."""
51
ctx.run("ls -la")
52
```
53
54
### Task Class
55
56
Core task representation containing metadata, argument specifications, and execution state.
57
58
```python { .api }
59
class Task:
60
"""
61
Core task class wrapping a callable with metadata and argument handling.
62
63
Attributes:
64
- name (str): Task name
65
- called (bool): Whether task has been called
66
- times_called (int): Number of times task has been invoked
67
- body (callable): Underlying Python function
68
- aliases (tuple): Alternative task names
69
- positional (list): Positional argument names
70
- optional (list): Optional argument names
71
- default (bool): Whether this is the default task
72
- auto_shortflags (bool): Auto-generate short flags
73
- help (dict): Help text mapping
74
- pre (list): Pre-execution tasks
75
- post (list): Post-execution tasks
76
- iterable (list): Multi-value arguments
77
- incrementable (list): Incrementable arguments
78
"""
79
80
def __init__(self, body, name=None, aliases=None, positional=None, optional=None, default=False, auto_shortflags=True, help=None, pre=None, post=None, iterable=None, incrementable=None):
81
"""
82
Initialize a Task object.
83
84
Parameters match the task decorator parameters.
85
"""
86
87
def argspec(self, body):
88
"""
89
Get argument specification from function signature.
90
91
Parameters:
92
- body (callable): Function to inspect
93
94
Returns:
95
argspec: Function argument specification
96
"""
97
98
def fill_implicit_positionals(self, args):
99
"""
100
Fill in positional arguments not explicitly marked.
101
102
Parameters:
103
- args (list): Existing positional arguments
104
105
Returns:
106
list: Updated positional arguments
107
"""
108
109
def arg_opts(self, name, default, taken_names):
110
"""
111
Generate argument parsing options for a parameter.
112
113
Parameters:
114
- name (str): Parameter name
115
- default: Parameter default value
116
- taken_names (set): Already used argument names
117
118
Returns:
119
dict: Argument parsing options
120
"""
121
122
def get_arguments(self):
123
"""
124
Generate Argument objects for all task parameters.
125
126
Returns:
127
list: List of Argument objects for CLI parsing
128
"""
129
```
130
131
### Call Class
132
133
Represents a specific invocation of a task with arguments and execution context.
134
135
```python { .api }
136
class Call:
137
"""
138
Task execution call with specific arguments and context.
139
140
Attributes:
141
- task (Task): Task being called
142
- args (tuple): Positional arguments
143
- kwargs (dict): Keyword arguments
144
"""
145
146
def __init__(self, task, args=None, kwargs=None):
147
"""
148
Initialize a Call object.
149
150
Parameters:
151
- task (Task): Task to call
152
- args (tuple, optional): Positional arguments
153
- kwargs (dict, optional): Keyword arguments
154
"""
155
156
def make_context(self, config):
157
"""
158
Create execution context for this call.
159
160
Parameters:
161
- config (Config): Configuration object
162
163
Returns:
164
Context: Execution context with config and call data
165
"""
166
167
def clone_data(self, **kwargs):
168
"""
169
Clone call data with optional overrides.
170
171
Parameters:
172
- **kwargs: Data to override
173
174
Returns:
175
dict: Cloned call data
176
"""
177
178
def clone(self, into=None, **kwargs):
179
"""
180
Clone this call with optional modifications.
181
182
Parameters:
183
- into (type, optional): Class to clone into
184
- **kwargs: Attributes to override
185
186
Returns:
187
Call: Cloned call object
188
"""
189
190
def __getattr__(self, name):
191
"""Delegate attribute access to wrapped task."""
192
193
def __eq__(self, other):
194
"""Test equality with another call."""
195
196
def __hash__(self):
197
"""Generate hash for call object."""
198
```
199
200
### Call Factory Function
201
202
Convenience function for creating Call objects.
203
204
```python { .api }
205
def call(task, *args, **kwargs):
206
"""
207
Create a Call object for executing a task with arguments.
208
209
Parameters:
210
- task (Task): Task to call
211
- *args: Positional arguments for task
212
- **kwargs: Keyword arguments for task
213
214
Returns:
215
Call: Call object ready for execution
216
"""
217
```
218
219
Usage example:
220
221
```python
222
from invoke import task, call
223
224
@task
225
def deploy(ctx, env='staging'):
226
ctx.run(f"deploy.sh {env}")
227
228
# Create call objects
229
staging_deploy = call(deploy, env='staging')
230
prod_deploy = call(deploy, env='production')
231
```
232
233
## Usage Examples
234
235
### Basic Task Definition
236
237
```python
238
from invoke import task
239
240
@task
241
def clean(ctx):
242
"""Clean build artifacts."""
243
ctx.run("rm -rf build/ dist/ *.egg-info/")
244
245
@task
246
def build(ctx, docs=False):
247
"""Build the project."""
248
ctx.run("python setup.py build")
249
if docs:
250
ctx.run("sphinx-build docs docs/_build")
251
252
@task(clean) # Pre-task dependency
253
def test(ctx):
254
"""Run test suite."""
255
ctx.run("python -m pytest")
256
```
257
258
### Advanced Task Configuration
259
260
```python
261
from invoke import task
262
263
@task(
264
aliases=['serve'],
265
help={
266
'port': 'Port to serve on (default: 8000)',
267
'host': 'Host to bind to (default: localhost)'
268
},
269
iterable=['exclude'],
270
incrementable=['verbose']
271
)
272
def runserver(ctx, port=8000, host='localhost', exclude=None, verbose=0):
273
"""Run development server."""
274
excludes = exclude or []
275
verbosity = '-' + 'v' * verbose if verbose else ''
276
277
exclude_args = ' '.join(f'--exclude {ex}' for ex in excludes)
278
ctx.run(f"python manage.py runserver {host}:{port} {verbosity} {exclude_args}")
279
280
# Usage from CLI:
281
# invoke runserver --port 3000 --exclude logs --exclude temp -vv
282
```
283
284
### Task Dependencies
285
286
```python
287
from invoke import task
288
289
@task
290
def setup_env(ctx):
291
"""Set up virtual environment."""
292
ctx.run("python -m venv venv")
293
ctx.run("venv/bin/pip install -r requirements.txt")
294
295
@task
296
def migrate(ctx):
297
"""Run database migrations."""
298
ctx.run("python manage.py migrate")
299
300
@task(pre=[setup_env, migrate])
301
def deploy(ctx):
302
"""Deploy application (runs setup and migration first)."""
303
ctx.run("python manage.py collectstatic --noinput")
304
ctx.run("systemctl restart myapp")
305
```