惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
GbyAI
GbyAI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
U
Unit 42
美团技术团队
NISL@THU
NISL@THU
C
Cisco Blogs
SecWiki News
SecWiki News
N
Netflix TechBlog - Medium
Forbes - Security
Forbes - Security
Cloudbric
Cloudbric
雷峰网
雷峰网
T
Tailwind CSS Blog
博客园 - 司徒正美
The Register - Security
The Register - Security
L
LangChain Blog
S
Security Affairs
Hacker News - Newest:
Hacker News - Newest: "LLM"
B
Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
Threat Research - Cisco Blogs
I
InfoQ
S
Schneier on Security
L
Lohrmann on Cybersecurity
量子位
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Martin Fowler
Martin Fowler
Schneier on Security
Schneier on Security
F
Fortinet All Blogs
TaoSecurity Blog
TaoSecurity Blog
K
Kaspersky official blog
Google DeepMind News
Google DeepMind News
Cisco Talos Blog
Cisco Talos Blog
PCI Perspectives
PCI Perspectives
Attack and Defense Labs
Attack and Defense Labs
WordPress大学
WordPress大学
Microsoft Azure Blog
Microsoft Azure Blog
H
Help Net Security
Project Zero
Project Zero
The GitHub Blog
The GitHub Blog
D
Docker
N
News | PayPal Newsroom
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
H
Hacker News: Front Page
云风的 BLOG
云风的 BLOG
Microsoft Security Blog
Microsoft Security Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 聂微东
Webroot Blog
Webroot Blog
MongoDB | Blog
MongoDB | Blog

智伤帝的个人博客

Maya 拍屏方案汇总 C++ 道法器术 C++ 基础入门 FBX 二进制数据解析 Maya RBF 算法应用 Maya 顶点色单通道笔刷 Maya CurveBrush 笔刷开发 Unreal C++ 工具开发最小实践 Maya C++ pyd 模块开发 Unreal C++ VScode 配置 Maya C++ mll hot reload 研究 Maya CMake 构建 C++ 插件编译环境 Unreal Python 导出 MetaHuman 控制器关键帧 TA 工具人知乎分享 Python 代码规范 Python - Import 机制 Python dependencies 库 Python blinker 库 Python marshmallow 库
Python doit 库
智伤帝 · 2022-03-28 · via 智伤帝的个人博客

前言

  代码开发的过程中可能遇到一些情况想要通过 代码 来自动执行命令行生成一些东西的情况。
  如果不使用框架进行管理,这些代码脚本就很零碎地散落在各个地方。
  因此就找到这个框架可以很方便管理多个任务,实现

Github 地址
官方说明文档

  在 doit 执行命令的地方添加一个 dodo.py 的脚本
  doit 会去读取 dodo.py 里面命名开头为 task_ 的方法作为执行的命令。

1
2
3
4
5
6
7
8
9
10
11
def task_hello():
"""hello"""

def python_hello(targets):
with open(targets[0], "a") as output:
output.write("Python says Hello World!!!\n")

return {
'actions': [python_hello],
'targets': ["hello.txt"],
}

  比如添加上面的方法到 dodo.py 里面
  执行 doit list 可以罗列出当前的可执行的命令

1
2
3
4
F:\thm_git\adam_pose_editor>doit list
hello hello
F:\thm_git\adam_pose_editor>doit hello
. hello

  执行 doit hello 就会在 dodo.py 缩在目录下输出一个 hello.txt 的文件。
  这个就是 doit 的基本用法。

dodo.py 配置

https://pydoit.org/configuration.html

  可以使用 doit -f xxx/dodo.py 配置 dodo.py 的路径
  也可以使用 pyproject.toml 进行配置

1
2
[tool.doit]
dodoFile = "scripts/dodo.py"

task 配置

  dodo.py 的 task 支持导入
  只要是 task_ 前缀的方法就会自动识别。
  也可以给函数添加 create_doit_tasks 属性,这样就可以自动生成了。 文档链接

  利用这些机制,我搞了一个装饰器可以给 task 添加一个短名的方案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def add_short_name(short_name):
"""Doit for short decorator.

Args:
short_name (str): short alias name.

Returns:
callable: decoartor function.
"""

def decorator(func):
globals()["task_{0}".format(short_name)] = func
return func

return decorator

@add_short_name("pf")
def task_preflight():
"""Run pre commit for all files.

Returns:
dict: doit config.
"""
command = ["poetry", "run", "pre-commit", "run", "-a"]
return {"actions": [command], "verbosity": 2}

  这样运行 doit 会识别到两个 task ,可以分别通过 doit pf 或者 doit preflight 触发指令

1
2
3
>doit list 
pf Run pre commit for all files.
preflight Run pre commit for all files.

  但是默认排序是按命名来的,如果命令很多就会混在一起

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>doit list 
b Run black format all python files.
black Run black format all python files.
d Run mkdocs serve.
dd Run mike to deploy docs.
docs Run mkdocs serve.
docs_deploy Run mike to deploy docs.
f Run `black` `isort`.
format Run `black` `isort`.
i Run isort format all python files.
isort Run isort format all python files.
l Run flakehell lint for all python files.
lint Run flakehell lint for all python files.
m Run mike serve.
mike Run mike serve.
pf Run pre commit for all files.
preflight Run pre commit for all files.
pt Run pytest.
pytest Run pytest.

  可以使用 doit list –sort=definition 的方式让排序变成创建顺序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>doit list --sort=definition
f Run `black` `isort`.
format Run `black` `isort`.
pf Run pre commit for all files.
preflight Run pre commit for all files.
b Run black format all python files.
black Run black format all python files.
i Run isort format all python files.
isort Run isort format all python files.
l Run flakehell lint for all python files.
lint Run flakehell lint for all python files.
pt Run pytest.
pytest Run pytest.
d Run mkdocs serve.
docs Run mkdocs serve.
m Run mike serve.
mike Run mike serve.
dd Run mike to deploy docs.
docs_deploy Run mike to deploy docs.

  但是每次使用都要加一个参数配置,那是相当的麻烦。
  我们可以利用 DOIT_CONFIG 进行配置 文档链接

1
2
3
DOIT_CONFIG = {
"sort": "definition",
}

task group

  可以使用 task_dep 的方式执行多个定义好的 task 文档链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import glob
DIR = os.path.dirname(__file__)
PY_FILES = glob.glob(os.path.join(DIR, "**/*.py"), recursive=True)
@add_short_name("f")
def task_format():
"""Run `black` `isort`.

Returns:
dict: doit config.
"""
return {"actions": None, "task_dep": ["black", "isort"]}

@add_short_name("b")
def task_black():
"""Run black format all python files.

Returns:
dict: doit config.
"""
command = ["poetry", "run", "black"] + PY_FILES
return {"actions": [command], "verbosity": 2}


@add_short_name("i")
def task_isort():
"""Run isort format all python files.

Returns:
dict: doit config.
"""
command = ["poetry", "run", "isort"] + PY_FILES
return {"actions": [command], "verbosity": 2}

  通过上面的配置就可以快速给所有的 python 脚本运行 black 和 isort

task 传参

文档链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def gen_api(api):
"""Generate API docs.

Args:
api (bool): flag to generate docs

Returns:
str: running command
"""

rmtree(os.path.join(DIR, "docs", "reference"), ignore_errors=True)
script_path = os.path.join(DIR, "docs", "gen_api_nav.py")
api_command = " ".join(["poetry", "run", "python", script_path])
serve_command = " ".join(["poetry", "run", "mkdocs", "serve"])
return f"{api_command} & {serve_command}" if api else serve_command


@add_short_name("d")
def task_docs():
"""Run mkdocs serve.

Returns:
dict: doit config.
"""
return {
"actions": [CmdAction(gen_api)],
"params": [
{
"name": "api",
"short": "a",
"type": bool,
"default": False,
"inverse": "flagoff",
"help": "generate api docs",
},
],
"verbosity": 2,
}

  通过 params 定义传入的参数,就可以控制 mkdocs 是否自动生成 api 的 markdown 脚本。

总结

  目前我使用上面的写法已经很够用了,其实它还有很多其他的配置可以用来做 C 编译。
  还可以定义 task 依赖 和 文件依赖,确保 task 的执行顺序。
  整体而言,doit 是个非常简单而是用的框架,配置 tox 等工具可谓是锦上添花。

版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 智伤帝的个人博客

打赏

  • 微信

    微信

  • 支付宝

    支付宝