I'd like to create a standalone python script that uses invoke
and also includes the tasks to be executed. A minimal working example looks like:
#!/usr/bin/env python3
from invoke import task, Program
@task()
def foo(c):
print("Task...")
program = Program()
program.run()
If I name the script example.py
, I'd like to be able to take the script and do:
(py37) bash-3.00$ ./example.py foo
Task...
If I put the task in a separate file named tasks.py
, things work. The documentation shows how to put the tasks in a separate package, but not the top-level script itself. I suspect it may be possible by providing the right namespace
argument to Program()
, but I haven't found a value that works.
You are absolutely right and so close to the solution. Program
doc says...
namespace:
A Collection to use as this program's subcommands.
If None (the default), the program will behave like invoke, seeking a nearby task namespace with a Loader and exposing arguments such as --list and --collection for inspecting or selecting specific namespaces.
You need to initialise a collection, add the tasks and pass it on to the Program
.
#!/usr/bin/env python3
import sys
from invoke import task, Program, Collection
@task()
def foo(c):
print("Task...")
namespace = Collection()
namespace.add_task(foo)
program = Program(namespace=namespace)
program.run()
Save this as example.py and run as you expected.
$ python3 example.py foo
Task...