1

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.

cryptoplex
  • 1,235
  • 10
  • 14

1 Answers1

1

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...
sreenivas
  • 2,067
  • 1
  • 19
  • 29