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 构建实用工具

Download history 4/week @ 2024-05-16 3/week @ 2024-05-23 98/week @ 2024-06-13 721/week @ 2024-06-20 113/week @ 2024-06-27 61/week @ 2024-07-04 5/week @ 2024-07-11 153/week @ 2024-07-25 243/week @ 2024-08-01 32/week @ 2024-08-08 194/week @ 2024-08-15

每月624次下载

MIT 许可证

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.mdstyles/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)
```

处理 updatecheckbuild 目标

$ 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文件

  1. 安装 dotenvcargo install dotenv
  2. 创建一个包含环境变量的 .env 文件。
  3. Makefile.md 配方中用 dotenv 预先添加命令。
  4. 运行 mkrs 命令。

变更日志

请参阅 CHANGELOG.md 中的 存储库

[^one]: 与 make 不同,mkrs 没有任何关于如何 编译 任何类型文件的内置知识;所有此类命令都必须在配置文件中定义。

[^two]: 只有当目标是该正在处理的目标的依赖项时,才会处理此类目标。

依赖项

~6–15MB
~210K SLoC