入门

本文档简要介绍了Invoke的功能集。有关详细的概念和API文档,请参阅全文的链接。有关安装帮助,请参阅项目的 installation page

定义和运行任务函数

invoke的核心用例是建立一个任务函数集合并执行它们。这很简单——您只需要创建一个名为 tasks.py 导入 task 修饰器和修饰一个或多个函数。您还需要添加一个任意命名的上下文参数(约定是使用 cctxcontext )作为第一个位置参数。现在还不用担心使用这个上下文参数。

让我们从一个虚拟的sphinx文档构建任务开始:

from invoke import task

@task
def build(c):
    print("Building!")

然后,可以通过告诉调用方的命令行转换器来执行新任务, invoke ,你想让它运行:

$ invoke build
Building!

函数体可以是任何你想要的Python——任何东西。

任务参数

函数可以有参数,任务也可以。默认情况下,根据 the CLI docs . 例如,如果我们添加 clean 参数并给它一个布尔默认值,它将显示为一组切换标志, --clean-c ::

@task
def build(c, clean=False):
    if clean:
        print("Cleaning!")
    print("Building!")

调用:

$ invoke build -c
$ invoke build --clean

当然,其他默认参数值将允许给出字符串或整数值。假设没有默认值的参数取字符串,也可以作为位置参数给出。以这段令人难以置信的编造片段为例:

@task
def hi(c, name):
    print("Hi {}!".format(name))

它可以通过以下方式调用,所有导致“嗨名字!”::

$ invoke hi Name
$ invoke hi --name Name
$ invoke hi --name=Name
$ invoke hi -n Name
$ invoke hi -nName

通过添加元数据 @task

@task 可以使用没有任何参数,如上,但它也是一个方便的向量附加元数据有关它的任务函数装饰。一个常见的例子是通过 help 参数(除了通过docstring提供任务级帮助之外):

@task(help={'name': "Name of the person to say hi to."})
def hi(c, name):
    """
    Say hi to someone.
    """
    print("Hi {}!".format(name))

调用时将显示此描述 --help ::

$ invoke --help hi
Usage: inv[oke] [--core-opts] hi [--options] [other tasks here ...]

Docstring:
  Say hi to someone.

Options:
  -n STRING, --name=STRING   Name of the person to say hi to.

关于任务参数化和元数据的更多细节可以在 调用任务 (用于命令行和解析方面)和 task API文档(用于声明端)。

列出任务

有时你会想知道在给定的 tasks.py —— invoke 可以告诉他们而不是执行某事:

$ invoke --list
Available tasks:

    build

这还将打印每个任务docstring的第一行(如果有)。看看还有什么 --listinvoke --help .

运行shell命令

许多调用用例都涉及运行本地shell命令,类似于make或rake等程序。这是通过 run 功能:

from invoke import task

@task
def build(c):
    c.run("sphinx-build docs docs/_build")

当命令运行时,您将在终端中看到它的输出:

$ invoke build
Running Sphinx v1.1.3
loading pickled environment... done
...
build succeeded, 2 warnings.

run 有许多参数控制其行为,例如激活需要它们的复杂程序的伪终端、抑制错误时退出行为、隐藏子进程的输出(同时仍捕获它以供以后查看)等等。见 its API docs 有关详细信息。

run 总是返回有用的 Result 对象提供对捕获的输出、退出代码和其他信息的访问。

旁白:这个“context”参数到底是什么?

跑步者面临的一个常见问题是传输从 configuration filesother configuration vectors ,通过cli标志给出,在“setup”任务中生成,等等。

某些库(如 Fabric 1.x)通过模块级别的属性实现,这使得测试困难且容易出错,限制了并发性,并增加了实现的复杂性。

调用以显式方式封装状态 Context 对象,在任务执行时将其交给任务。上下文是主要的api端点,它提供了尊重当前状态的方法(例如 Context.run )以及进入那个国家本身。

宣布预任务

可以通过 task 装饰者。其中之一是选择一个或多个希望在执行任务之前始终运行的其他任务(用名称表示)。

让我们用一个新的清理任务来扩展我们的文档生成器,它在每个构建之前运行(但是当然,它仍然可以自己执行):

from invoke import task

@task
def clean(c):
    c.run("rm -rf docs/_build")

@task(clean)
def build(c):
    c.run("sphinx-build docs docs/_build")

现在当你 invoke build ,它将自动运行 clean 第一。

备注

如果您不是隐含的“位置参数是预运行任务名称”API的粉丝,那么您可以显式地给出 pre kwarg: @task(pre=[clean]) .

详情可在 任务如何运行 .

创建命名空间

现在,我们的 tasks.py 隐式地仅用于文档,但可能我们的项目需要其他非文档的东西,如打包/部署、测试等。在这一点上,单个平面名称空间是不够的,因此invoke允许您轻松地构建 nested namespace . 这里有一个简单的例子。

我们先把我们的 tasks.py 成为 docs.py ;不需要其他更改。然后我们创建一个新的 tasks.py ,为了简洁起见,用一个名为 deploy .

最后,我们可以使用一个新的API成员, Collection 类,以绑定此任务和 docs 模块到单个显式命名空间中。当调用加载任务模块时,如果 Collection 对象绑定为 nsnamespace 它将用于根命名空间:

from invoke import Collection, task
import docs

@task
def deploy(c):
    c.run("python setup.py sdist")
    c.run("twine upload dist/*")

namespace = Collection(docs, deploy)

结果:

$ invoke --list
Available tasks:

    deploy
    docs.build
    docs.clean

有关命名空间工作原理的更详细分解,请参见 the docs .