34 个版本 (17 个重大变更)
新 0.18.2 | 2024年8月22日 |
---|---|
0.17.1 | 2024年8月6日 |
0.16.5 | 2024年7月3日 |
0.13.1 | 2024年1月27日 |
0.11.0 | 2023年11月20日 |
#30 in 构建实用工具
每月624次下载
37KB
584 行
关于
构建自动化工具
- 受 make 启发
- 无自动目标[^one]
- 简约功能;最大可读性
- 配置为一个或多个简单的 Markdown 文件(默认为
Makefile.md
) - 输出为彩色 Markdown(除非重定向或管道传输)
- 处理指定的目标或如果没有指定,则处理第一个目标
- 命令独立运行,在脚本模式下运行或通过自定义命令运行
- 如果任何命令失败(退出码非零),则立即停止处理(如果不使用不提供此功能的自定义 shell)
- 详细级别:
-v
:在脚本模式中的bash
命令中添加-x
,-vv
:打印最新的目标,-vvv
:显示配置 - 为 Rust 项目生成默认的 [代码
Makefile.md
](-g
) - 通过
-l
列出目标;如果指定了目标,则列出分层依赖关系 - 按照指定的顺序处理目标和依赖关系
语法
输入
- 一级标题开始定义 目标。
- 纯文本目标名称是一个 "虚拟" 目标,且 总是运行。[^two]
- 代码段目标名称是一个文件目标,只有在以下情况下才会运行:(a) 任何依赖文件目标的修改时间晚于文件目标,(b) 文件目标不存在且有配方,或者 (c) 启用强制处理(
-B
)[^two] - 无序列表项定义目标 依赖。
- 纯文本依赖名称是一个虚拟依赖,如果目标运行,则也会运行。
- 代码段依赖名称是一个文件依赖,它可能有一个相关的目标或没有。如果没有,它被解释为匹配现有文件的文件glob,这使目标可以轻松地依赖于任何匹配glob的文件,例如,
build
目标可能依赖于src/**/*.rs
,这意味着src/
目录下的任何*.rs
文件。 - 代码块是一个 配方,包含在处理目标时运行的命令。
- 默认情况下,通过
sh -c
独立运行配方命令,如果启用了脚本模式(-s
),则通过bash -eo pipefail
运行,如果脚本模式和详细级别1或更高(-sv
)启用,则通过代码块信息字符串中给出的命令运行。 - 命令可以使用以下变量:
{0}
:第一个依赖{target}
:目标名称{dirname}
:目录名称
请参阅 Makefile.md
、styles/Makefile.rust.md
以及 -g
选项中的示例。
输出
-
级别2标题是输出部分:“配置”、“目标(们)”。
-
在“目标(们)”部分中的级别3标题是每个目标,无论是纯文本“phony”目标还是代码段文件目标。
-
代码块
脚本模式 试运行 描述 每个命令和输出 ✔ 每个命令 ✔ 每个脚本 ✔ ✔ 每个脚本和输出(在单独的代码块中)
用法
$ mkrs -V
mkrs 0.18.2
$ mkrs -h
Build automation tool
Usage: mkrs [OPTIONS] [NAME]...
Arguments:
[NAME]... Target(s)
Options:
-l List targets/dependencies
-B Force processing
-n Dry run
-s Script mode
-v... Verbose
-q Quiet
-C <PATH> Change directory
-f <PATH> Configuration file(s) [default: Makefile.md]
-g <STYLE> Generate Makefile.md content [styles: rust]
--color <COLOR> Force enable/disable terminal colors [default: auto]
[possible values: auto, always, never]
-r Print readme
-h, --help Print help
-V, --version Print version
示例
列出可用的目标
$ mkrs -l
* all
* check
* update
* run
* clippy
* test
* build
* `target/release/mkrs`
* `README.md`
* doc
* outdated
* audit
* update-toml
* update-lock
* install
* uninstall
* install-deps
* clean
* cocomo
* commit
* publish
* full
* fail
* `nonexistent`
* custom
列出 full
目标的依赖关系
$ mkrs -l full
* full
* update
* update-toml
* update-lock
* check
* outdated
* audit
* all
* clippy
* `Cargo.lock`
* `Cargo.toml`
* `src/main.rs`
* test
* `Cargo.lock`
* `Cargo.toml`
* `src/main.rs`
* build
* `target/release/mkrs`
* `Cargo.lock`
* `Cargo.toml`
* `src/main.rs`
* `README.md`
* `t/README.md`
* `Cargo.toml`
* `CHANGELOG.md`
* `src/main.rs`
* doc
* install
* `README.md`
* `t/README.md`
* `Cargo.toml`
* `CHANGELOG.md`
* `src/main.rs`
试运行
$ mkrs -n
# clippy
```text
cargo clippy -- -D clippy::all
```
# test
```text
cargo test
```
# `target/release/mkrs`
```text
cargo build --release
```
# doc
```text
cargo doc
```
处理默认目标
$ mkrs
# clippy
```text
$ cargo clippy -- -D clippy::all
Checking mkrs v0.18.2 (/home/nick/github.com/qtfkwk/mkrs)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.40s
```
# test
```text
$ cargo test
Compiling mkrs v0.18.2 (/home/nick/github.com/qtfkwk/mkrs)
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.44s
Running unittests src/main.rs (target/debug/deps/mkrs-1319d8fc4c6c108b)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
```
# `target/release/mkrs`
```text
$ cargo build --release
Compiling mkrs v0.18.2 (/home/nick/github.com/qtfkwk/mkrs)
Finished `release` profile [optimized] target(s) in 1.49s
```
# doc
```text
$ cargo doc
Documenting mkrs v0.18.2 (/home/nick/github.com/qtfkwk/mkrs)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.41s
Generated /home/nick/github.com/qtfkwk/mkrs/target/doc/mkrs/index.html
```
处理 check
目标
$ mkrs check
# outdated
```text
$ cargo outdated --exit-code=1
All dependencies are up to date, yay!
```
# audit
```text
$ cargo audit
Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
Loaded 648 security advisories (from /home/nick/.cargo/advisory-db)
Updating crates.io index
Scanning Cargo.lock for vulnerabilities (80 crate dependencies)
```
处理 update
、check
和 build
目标
$ mkrs update check build
# update-toml
```text
$ cargo upgrade -i
Updating 'https://github.com/rust-lang/crates.io-index' index
Checking mkrs's dependencies
note: Re-run with `--verbose` to show more dependencies
latest: 11 packages
```
# update-lock
```text
$ cargo update
Updating crates.io index
Locking 0 packages to latest compatible versions
note: pass `--verbose` to see 14 unchanged dependencies behind latest
```
# outdated
```text
$ cargo outdated --exit-code=1
All dependencies are up to date, yay!
```
# audit
```text
$ cargo audit
Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
Loaded 648 security advisories (from /home/nick/.cargo/advisory-db)
Updating crates.io index
Scanning Cargo.lock for vulnerabilities (80 crate dependencies)
```
# `target/release/mkrs`
```text
$ cargo build --release
Compiling mkrs v0.18.2 (/home/nick/github.com/qtfkwk/mkrs)
Finished `release` profile [optimized] target(s) in 1.55s
```
为Rust项目生成默认的 Makefile.md
$ mkrs -g rust
# all
* clippy
* test
* build
* doc
# check
* outdated
* audit
# update
* update-toml
* update-lock
# run
* `target/release/{dirname}`
```
target/release/{dirname}
```
# clippy
* `Cargo.lock`
* `Cargo.toml`
* `**/*.rs`
```
cargo clippy -- -D clippy::all
```
# test
* `Cargo.lock`
* `Cargo.toml`
* `**/*.rs`
```
cargo test
```
# bench
```
cargo bench -q 2>&1 |tee benches/report.txt
```
# build
* `target/release/{dirname}`
# `target/release/{dirname}`
* `Cargo.lock`
* `Cargo.toml`
* `**/*.rs`
* `README.md`
```
cargo build --release
```
# `README.md`
* `t/README.md`
* `Cargo.toml`
* `CHANGELOG.md`
* `**/*.rs`
```
cargo build --release
kapow {0} >{target}
```
# doc
```
cargo doc
```
# outdated
```
cargo outdated --exit-code=1
```
# audit
```
cargo audit
```
# update-toml
```
cargo upgrade -i
```
# update-lock
```
cargo update
```
# install
* `README.md`
```
cargo install --path .
```
# uninstall
```
cargo uninstall {dirname}
```
# install-deps
```
cargo install cargo-audit cargo-edit cargo-outdated cocomo dtg kapow tokei toml-cli
```
# scaffold
```bash -eo pipefail
if ! toml get -r Cargo.toml package.description >/dev/null; then
toml set Cargo.toml package.description "Insert a description here" >Cargo.toml.new
mv Cargo.toml.new Cargo.toml
echo Edit package description in Cargo.toml, then rerun \`mkrs scaffold\`.
exit 0
fi
mkdir -p t
if [ ! -e t/README.md ]; then
NAME=$(toml get -r Cargo.toml package.name)
ABOUT=$(toml get -r Cargo.toml package.description)
cat <<EOF >t/README.md
# About
$ABOUT
# Usage
~~~~text
\$ $NAME -V
!run:../target/release/$NAME -V 2>&1
\$ $NAME -h
!run:../target/release/$NAME -h 2>&1
!inc:../CHANGELOG.md
EOF fi if [ ! -e CHANGELOG.md ]; then VERSION=$(toml get -r Cargo.toml package.version) TODAY=$(dtg -n %Y-%m-%d) cat <CHANGELOG.md
变更日志
- $VERSION ($TODAY): 初次发布
EOF fi
# clean
cargo clean
# cocomo
```bash -eo pipefail
tokei; echo
cocomo -o sloccount
cocomo
commit
set -xeo pipefail
V=$(toml get -r Cargo.toml package.version)
git commit -m "$V"
git tag -a "$V" -m "$V"
publish
cargo publish
git push
git push --tags
full
- update
- check
- all
- install
**Note:** Save to `Makefile.md` via redirection: `mkrs -g rust >Makefile.md`
## Generate a COCOMO report
~~~text
$ mkrs cocomo
# cocomo
```bash -eo pipefail
tokei; echo
cocomo -o sloccount
cocomo
```
```
text
===============================================================================
Language Files Lines Code Comments Blanks
===============================================================================
TOML 1 22 20 0 2
-------------------------------------------------------------------------------
Markdown 5 1072 0 787 285
|- BASH 3 112 90 6 16
|- Python 1 1 1 0 0
(Total) 1185 91 793 301
-------------------------------------------------------------------------------
Rust 1 688 584 29 75
|- Markdown 1 12 0 12 0
(Total) 700 584 41 75
===============================================================================
Total 7 1782 604 816 362
===============================================================================
Total Physical Source Lines of Code (SLOC) = 604
Development Effort Estimate, Person-Years (Person-Months) = 0.12 (1.41)
(Basic COCOMO model, Person-Months = 2.40*(KSLOC**1.05)*1.00)
Schedule Estimate, Years (Months) = 0.24 (2.85)
(Basic COCOMO model, Months = 2.50*(person-months**0.38))
Estimated Average Number of Developers (Effort/Schedule) = 0.50
Total Estimated Cost to Develop = $15,912
(average salary = $56,286/year, overhead = 2.40)
Description | Value
---------------------------|---------------------------------
Total Source Lines of Code | 604
Estimated Cost to Develop | $15,912.21
Estimated Schedule Effort | 2.85 months
Estimated People Required | 0.50
```
使用自定义的shell程序
$ mkrs custom
# custom
```python
print("This is a custom recipe in Python.")
```
```
text
This is a custom recipe in Python.
```
通过dotenv使用.env
文件
- 安装
dotenv
:cargo install dotenv
。 - 创建一个包含环境变量的
.env
文件。 - 在
Makefile.md
配方中用dotenv
预先添加命令。 - 运行
mkrs
命令。
变更日志
请参阅 CHANGELOG.md
中的 存储库。
[^one]: 与 make 不同,mkrs 没有任何关于如何 编译 任何类型文件的内置知识;所有此类命令都必须在配置文件中定义。
[^two]: 只有当目标是该正在处理的目标的依赖项时,才会处理此类目标。
依赖项
~6–15MB
~210K SLoC