Package: dryads
Dryads非侵入式命令行构建工具以及脚本管理工具类似工具:Just如果构建工业级命令行项目，推荐其他框架，比如argparse，click，typer，不过理论上本框架也行推荐阅读：Line Interface Guidelines使用该框架的实例：BusTub lab test script:介绍Note Analysis Tool发心：命令行软件也是软件，那么人类是怎么将需求传达给机器的呢？即参数和选项，形象的说，如果把命令行软件当作人类与机器交通的工具的话，参数和选项就是修饰词。而围绕某一个事物的各种修饰词，将其相同的部分汇总并依次连接，很容易形成树形结构。即很多命令行软件的选项设计可以总结为树形结构。拿我在CMU15445 Lab的过程遇到的需求来说，这个过程，测试、格式化、打包等等每个动作都对应一系列命令，而每个动作还能细分，比如Lab分成多个Project，每个Project分成多个Task，于是就可能出现“测试Project1 Task1相关代码”，同理，格式化和打包操作也类似，所以形成了如下树形结构（以Json表示）：{"Test":{"Project1":{"Task1":...,"Task2":...,...,},"Project2":...,...},"Format":...,"Submit":...,}而这里的每个指令，都是由一系列Shell命令实现的；几乎不可能记忆所有的命令，而将对应的命令放在对应的指令下，则可以自由使用如果把Shell脚本换成一个个Python函数，则这就形成了一个命令行程序即使不考虑命令行程序，即使同是脚本语言，Python的表意能力要比Bash强得多，如果运维相关的操作有点复杂，使用Python实现可能要比Bash实现容易的多。这个工具极大的提高了我的工作效率。Install通过PyPI：pipinstalldryads同时会下载可执行文件ds/ds.exe，它会执行路径为~/dryadsfile的使用该框架的正常脚本通过源代码下载：pipinstallgit+https://github.com/zweix123/dryads.git@masterUse如果是在Linux系统，通过在脚本前添加shebang#!/usr/bin/env python3# -*- coding: utf-8 -*-则可以通过./script.py这种很接近命令的形式使用我们只需要描述好树形结构即可，即通过dict类型的变量，参数解析和执行交给框架，下面是一个简单的例子# test/example.pyfromdryadsimportDryads,DryadsContainer,DryadsFlag,run_shell_cmddefcreate_python():run_shell_cmd(f"poetry new{DryadsContainer.DryadsArg}")defcreate_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)基本元素：以嵌套的dict来描述树形结构dict的键只能是str或者tuple[str]来描述选项tuple即多选项叶子节点为str/Callable/list[str | Callable]类型表示具体的命令执行内容每个str作为一个shell脚本一起交给shellypx如果命令中包含cd，需要放在一个str字面量中--help: help option必不可少根help option：python3 script.py/python3 script.py -h/python3 script.py --help该脚本命令可分为两大类ShellCommands,help会输出命令本身PythonFunction,help会输出函数的__doc__echoEnglish:echoHelloWorldechoChinese:echo我可以吞下玻璃而不受到伤害echoMath:echo42echo3.14
workDryadsFlag.PrefixCmd:cdProject
workbuild:cdbuild&&make-j`nproc`workrun:./build/bin/work
createpython:DryadsFlag.AnchoringDryadsFlag.AcceptArgCreatePython
createrust:DryadsFlag.AnchoringDryadsFlag.AcceptArgCreateRust
-d/--dryads:echoHelloDryads
env:PrintDryadsenvironmentvariable.各选项help option：在任意选项后，都可以添加help option查看之后的命令>pythonexample.pyecho--help
该脚本命令可分为两大类ShellCommands,help会输出命令本身PythonFunction,help会输出函数的__doc__echoEnglish:echoHelloWorldechoChinese:echo我可以吞下玻璃而不收到伤害echoMath:echo42echo3.14执行：一个命令相当于从根到叶子的路径叶子节点：>pythonexample.pyechoChineseecho我可以吞下玻璃而不收到伤害
我可以吞下玻璃而不收到伤害中间节点：执行该节点子树中的所有叶子节点>pythonexample.pyechoechoHelloWorld
Hello
Worldecho我可以吞下玻璃而不收到伤害
我可以吞下玻璃而不收到伤害echo4242echo3.143.14标记DryadsFlag.Anchoring: 作为叶子的值, 表示该叶子中的命令都是以执行脚本的路径开始, 默认从脚本所在的路径开始, 例子在AnchoringDryadsFlag.AcceptArg: 作为叶子的值, 表示该选项还接收一个可选参数, 并将参数放在变量DryadsArg中, 例子在AcceptArg, 还有两个非法的例子,AcceptArg Invalid|AcceptArg InvalidDryadsFlag.InVisible: 作为叶子的值, 表示执行的脚本是否打印, 默认打印, 使用该标志表示不打印, 例子在InVisibleDryadsFlag.IgnoreErr: 作为叶子的值, 表示命令执行出错后是否停止, 默认停止, 使用该标志表示不停止, 例子在IgnoreErrDryadsFlag.PrefixCmd: 作为某个节点的键, 其值对应的脚本为子树中所有脚本的前置脚本, 例子在PrefixCmd该标记只能用于dict不能用于list，但是我们往往是对叶子节点list中的一系列命令设置前置脚本，通过再套一层dict解决。TODO缩进支持中文美化help效果debug: help option显示-h/--help本身