Skip to main content

Simple CLI building tool and script management tool.

Project description

Dryads

Simple CLI building tool and script management tool.

  • 对标:
    • Simple CLI building tools: argparse, click and typer
    • Script management tool: Just

发心

在图形化(GUI)软件出现之前,计算机操作员使用的是命令行(CLI)软件。两种软件本质是将人的指令交给计算机。

学术的说,在CLI中,有argument参数,不带前缀,是字符串;flag标志,通常以-开头,通常是可选的,相当于bool值;options选项,通常以-或者--开头,通常后接参数。注意git add中的add并不属于此三者的任何一个,而是命令本身。

形象的说,命令、参数、标志和选项是人和计算机交流的语言。而围绕某一个事物的一系列修饰词中,将归纳汇总并依次连接,可形成树形结构,很多命令行工具的选项都是。

举个🌰,网易的分布式存储系统下有对集群的运维工具curve-tool


有子命令,分别是bs(管理块存储集群)、completion()、fs(管理文件存储集群)、upgrade(升级)。

使用一个子命令继续看

还有子命令,可以理解为针对块存储集群的各种操作,比如check(检测)、create(创建资源)、delete(删除资源)、list(罗列资源)等等。

继续使用一个子命令继续看
还有子命令,对于“检测”这个动作,还能继续“修饰”,到底检测什么“事物”

继续使用一个子命令继续看
至此确实没有了,开始添加flag了

可以想象,将这里所有的子命令取出来,并通过前后关系作为Parent结点和Child结点,可以形成树形结构。

再举个🌰,在完成CMU 15445 Lab过程中,需要较多命令,比如测试、格式化、打包等等。而每个动作还能细分,比如Lab分成多个Project,每个Project又分成多个Task。于是就出现了“测试Project1 Task1相关代码”这样的命令。同理,格式化和打包操作也类似。所以可形成如下树形结构(以Json表示)

{
    "test": {
        "p1": {
            "t1": ...,
            "t2": ...,
            ...
        },
        "p2": ...,
        ...
    },
    "format": ...,
    "submit": ...,
}

故本项目的使用场景呼之欲出

  • Simple CLI building tools: 如果命令行工具可以描述为嵌套的子命令,则该框架可以很简单的构建。
  • Script management tool: 如果围绕某个项目或者在工作流中有一系列的命令,可以用该框架管理使之维护在一个文件中。同时大量的命令几乎无法记忆(比如在15445中使用的命令),通过子命令的方式使记忆它们称为可能(子命令对应一个脚本)。同时,文件主体是一个Python文件,命令作为字符串嵌入其中,同样是脚本语言,Python有较于Bash或者Powershell强的多的表意能力和跨平台性。

该工具以嵌入我的工作流中并极大的提高我的效率。

Install

  • 通过PyPI:PyPI

    pip install dryads
    

    同时会下载命令ds,它会在当前路径递归向上寻找dryadsfile文件并使用Python解释器运行它。我们也建议每个项目下都有一个dryadsfile用来管理维护该项目需要命令,原因在Just Further Ramblings

Use

  • 命令ds,如上,它会在当前路径递归向上寻找dryadsfile文件并使用Python解释器运行它。

  • 如果是在Linux系统,通过在脚本前添加shebang

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    

    则可以通过./script.py这种很接近命令的形式使用

使用字符串表达脚本内容,而Python中“万物皆对象”,可以将函数本身作为值传递。使用dict数据类型即可描述出树形结构,将该dict交给框架,子命令的解析和执行交给框架即可。

下面是一个经典的例子。

# test/classic_example.py
from dryads import Dryads, DryadsContainer, DryadsFlag, run_shell_cmd

def create_python():
    run_shell_cmd(f"poetry new {DryadsContainer.DryadsArg}")

def create_rust():
    run_shell_cmd(f"cargo new {DryadsContainer.DryadsArg}")

CMDS = {
    "echo": {
        "English": "echo Hello World",
        "Chinese": "echo 我可以吞下玻璃而不受到伤害",
        "Math": ["echo 42", "echo 3.14"],
    },
    "work": {
        DryadsFlag.PrefixCmd: ["cd Project"],
        "build": "cd build && make -j`nproc`",
        "run": "./build/bin/work",
    },
    "create": {
        "python": [
            DryadsFlag.Anchoring,
            DryadsFlag.AcceptArg,
            create_python,
        ],
        "rust": [
            DryadsFlag.Anchoring,
            DryadsFlag.AcceptArg,
            create_rust,
        ],
    },
    ("-d", "--dryads"): "echo Hello Dryads",
}

Dryads(CMDS)

直接执行上文件输出如下

相当于

其中子命令env-h/--help是默认生成的

对于各级子命令,也能使用-h(或者--help)选项

下面聊聊语法

  • 以嵌套的dict数据结构描述树形结构

  • dict的键只能是str或者tuple[str]或者DryadsFlag(这是什么后面再聊)来描述子命令

  • 叶子节点以str/Callable/list[str | Callable]类型表示具体的要执行的脚本内容。

    • 每个str类型字面量作为一个Shell脚本一起交给Shell执行,即一个字符串可以是多行的,它们是连续的。

      • 如果在list[str]中有cd命令,列表中的其他字符串中的命令不会被影响。
  • 执行:一个命令的所有子命令相当于从根到叶子的路径

    • 叶子节点:

    • 中间节点:执行该节点子树中的所有叶子节点

  • 标记DryadsFlag,当希望概念某些默认的行为时,以标记的方式实现。其本身是枚举量,作为键或者叶子执行修改某种行为。

    • DryadsFlag.Anchoring: 作为叶子的值, 表示该叶子中的命令都是以执行脚本的路径开始, 默认从脚本所在的路径开始, 例子在Anchoring
    • DryadsFlag.AcceptArg: 作为叶子的值, 表示该选项还接收一个可选参数, 并将参数放在变量DryadsArg中, 例子在AcceptArg, 还有两个非法的例子, AcceptArg Invalid | AcceptArg Invalid
    • DryadsFlag.InVisible: 作为叶子的值, 表示执行的脚本是否打印, 默认打印, 使用该标志表示不打印, 例子在InVisible
    • DryadsFlag.IgnoreErr: 作为叶子的值, 表示命令执行出错后是否停止, 默认停止, 使用该标志表示不停止, 例子在IgnoreErr
    • DryadsFlag.PrefixCmd: 作为某个节点的键, 其值对应的脚本为子树中所有脚本的前置脚本, 例子在PrefixCmd
      • 该标记只能用于dict不能用于list,但往往是对叶子节点list中的一系列命令设置前置脚本,可通过再套一层dict解决。

用户

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dryads-1.3.1.tar.gz (13.4 kB view hashes)

Uploaded Source

Built Distribution

dryads-1.3.1-py3-none-any.whl (12.1 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page