生产环境中会用到的工具及简单配置
上一篇简单说明了 rust 的基本安装 , 这一篇是常用开发工具的简单配置及自动化方案的分享
依赖检查
Cargo Deny 是 Rust 的一个工具,旨在帮助开发者管理和控制项目依赖项,特别是帮助防止引入不安全的、过时的或不符合项目要求的 crate。它通过检查 Cargo.toml
和 Cargo.lock
文件中的依赖关系,并与设定的规则进行对比,从而提高项目的安全性和合规性。
安装
首先,确保你已经安装了 Rust(可以参考专栏中之前的教程)。然后,你可以通过 cargo
来安装 cargo deny
:
shell
$ cargo install cargo-deny
此命令会安装 cargo deny
工具,并将其添加到你的 PATH
中。安装完成后,你可以通过以下命令验证安装是否成功:
shell
$ cargo deny --version
配置文件
在成功安装了 deny 之后可以通过 init
初始化配置文件
shell
$ cargo deny init
上面的指令会在项目目录下创建一个 deny.toml
文件 , 里面包含缺省配置 , 通常来讲我们只需要修改 allow
字段的内容就可以了 , 打开deny.toml
文件并找到 allow 字段 , 按需修改其中的内容 , 例如:
toml
[licenses]
allow = [
"MIT",
"Apache-2.0",
"Unicode-DFS-2016",
"MPL-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"CC0-1.0",
"Unicode-3.0"
]
现在就可以使用 cargo deny
进行检查了
shell
$ cargo deny check
当 allow 中的许可没有没遇到的时候会出现类似下面这样的 wraning
shell
warning[license-not-encountered]: license was not encountered
┌─ /Users/wuzexian/codes/rust_project/rust_demo/deny.toml:95:4
│
95 │ "Unicode-DFS-2016",
│ ━━━━━━━━━━━━━━━━ unmatched license allowance
可以通过 unused-allowed-license
设置未使用的 license 不再 "wran" 而是 "allow"
toml
[licenses]
unused-allowed-license = "allow" # defult wran
allow = [..]
拼写检查
安装
首先,确保你已经安装了 Rust 环境。如果尚未安装 Rust,请访问 Rust 官网 进行安装。
然后,使用以下命令通过 cargo
安装 cargo typos
工具:
bash
$ cargo install typos-cli
安装完成后,您可以通过以下命令验证是否成功安装:
bash
$ typos --version
如果安装成功,命令会输出 cargo-typos
的版本号。
使用
一旦安装完成,你就可以使用 cargo typos
来检查项目中的拼写错误了。在项目根目录下运行以下命令:
bash
$ typos
这会扫描项目中的源代码(包括 .rs
文件),并报告任何拼写错误。输出内容会列出拼写错误的单词和位置,例如:
go
error: possible typo in documentation: "recieve" should be "receive"
--> src/lib.rs:10:5
|
10 | // This function will recieve the value
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `cargo typos` suggests replacing with "receive"
在此输出中,cargo typos
会列出错误的单词(如 "recieve"),并且还会给出一个建议的更正(如 "receive")。
忽略
有的时候我们代码中会有 "故意错误" 的单词 , 或者不想进行拼写检查的文件 , 可以同意typos.toml
进行配置
toml
[default.extend-words]
teh = "teh" # 不纠正 teh
[files]
# 不纠正某些文件
extend-exclude = ["README.md", "LICENSECHANGELOG.md", "notebooks/*"]
NEXTEST
nextest
是 rust 下一代的 "test runner" , 界面干净简介 , 最重要的是比 cargo test
快 3 倍
安装
首先,确保你已经安装了 Rust 环境。如果尚未安装 Rust,请访问 Rust 官网 进行安装。
然后,使用以下命令通过 cargo
安装 nextest
shell
$ cargo install cargo-nextest
在需要测试的时候使用 nextest
代替 test
即可
shell
$ cargo nextest run
日志文件生成
git-cliff
可以通过使用传统的提交以及regex驱动的自定义解析器从Git历史记录中生成更新日志文件。用于自动生成 CHANGELOG 文件
安装
首先,确保你已经安装了 Rust 环境。如果尚未安装 Rust,请访问 Rust 官网 进行安装。
然后,使用以下命令通过 cargo
安装 git-cliff
shell
$ cargo install git-cliff
配置
git-ciff
的配置需要在根目录下有 cliff.toml
文件 , rust 项目中可以通过 metadata table
在 cargo.toml
中直接配置
toml
[package]
name = "..."
[dependencies]
# ...
# 配置 git-cliff 的 Changelog 生成器
[package.metadata.git-cliff.changelog]
# 定义 Changelog 文件的头部内容
header = """
# 更新日志\n
所有显著的变化将记录在此文件中。请参阅 [常规提交](https://www.conventionalcommits.org/) 规范以了解提交指南。\n
"""
# 定义 Changelog 正文的模板,使用 Tera 模板语言
body = """
---
{% if version %}\
{% if previous.version %}\
## [{{ version | trim_start_matches(pat="v") }}]($REPO/compare/{{ previous.version }}..{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% endif %}\
{% else %}\
## [未发布]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | striptags | trim | upper_first }}
{% for commit in commits
| filter(attribute="scope")
| sort(attribute="scope") %}
- **({{commit.scope}})**{% if commit.breaking %} [**破坏性更改**]{% endif %} \
{{ commit.message|trim }} - ([{{ commit.id | truncate(length=7, end="") }}]($REPO/commit/{{ commit.id }})) - {{ commit.author.name }}
{%- endfor -%}
{% raw %}\n{% endraw %}\
{%- for commit in commits %}
{%- if commit.scope -%}
{% else -%}
- {% if commit.breaking %} [**破坏性更改**]{% endif %}\
{{ commit.message|trim }} - ([{{ commit.id | truncate(length=7, end="") }}]($REPO/commit/{{ commit.id }})) - {{ commit.author.name }}
{% endif -%}
{% endfor -%}
{% endfor %}\n
"""
# 定义 Changelog 文件的尾部内容
footer = """
<!-- 由 git-cliff 生成 -->
"""
# 移除模板字符串首尾的空白字符
trim = true
# 定义 postprocessors,用于替换模板中的变量或模式
postprocessors = [
# 替换 $REPO 为实际的仓库地址
{ pattern = '\$REPO', replace = "" }, # 替换仓库 URL
]
[package.metadata.git-cliff.git]
# 是否解析遵循 conventional commits 规范的提交
conventional_commits = true
# 是否过滤掉非 conventional commits 规范的提交
filter_unconventional = false
# 是否将每个提交的每个正文行作为单独的提交处理
split_commits = false
# 提交消息的预处理正则表达式列表
commit_preprocessors = [
# 替换 Issue 编号为链接形式
# { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/orhun/git-cliff/issues/${2}))" },
]
# 解析和分组提交的正则表达式列表
commit_parsers = [
# 跳过
{ message = "\\[skip", skip = true },
# 包含任何中文跳过
# { message = "\\p{Han}", skip = true },
# feat 开头放入特性分类
{ message = "^feat", group = "feat" },
# fix 开头放入 bug 修复分类
{ message = "^fix", group = "fix bug" },
# doc 开头放入文档分类
{ message = "^doc", group = "document" },
# perf 开头放入性能分类
{ message = "^perf", group = "perf" },
# refactor 放入重构分类
{ message = "^refactor", group = "refactor" },
# style 开头放入样式分类
{ message = "^style", group = "style" },
# revert 放入还原复原分类
{ message = "^revert", group = "revert" },
# test 放入测试分类
{ message = "^test", group = "tests" },
# 以 chore: 开头,跳过这条提交
{ message = "^chore:", skip = true },
# 包含 security 安全修复
{ body = ".*security", group = "security" },
# 不匹配的其他内容归入 Other
{ message = ".*", group = "others" },
]
# 是否保护破坏性更改不被跳过
protect_breaking_commits = false
# 是否过滤掉不符合 commit parsers 的提交
filter_commits = false
# 匹配 git 标签的正则表达式
tag_pattern = "v[0-9].*"
# 跳过匹配的标签
skip_tags = "v0.1.0-beta.1"
# 忽略匹配的标签
ignore_tags = ""
# 是否按照拓扑排序排序标签
topo_order = false
# 小节内提交的排序方式,"oldest" 或 "newest"
sort_commits = "oldest"
# 限制在 Changelog 中包含的提交数量
# limit_commits = 42
此时使用 git cliff -o CHANGELOG.md
即可自动根据git 的提交历史生成CHANGELOG.md
文件 ,例如进行了两次提交 , 第一次commit 的是"first commit: init" ,第二次是"fix : fix unused warning" , 并打了个0.1.1
的 tag , 最终生成如下:
markdown
# 更新日志 Change log
所有显著的变化将记录在此文件中。请参阅 [常规提交](https://www.conventionalcommits.org/) 规范以了解提交指南。
All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines.
---
## [0.1.1] - 2025-01-03
### Fix bug
- fix : fix unused warning - ([9560718](https://github.com/WITstudio86//commit/956071822239ee41896a95199bce8187f99a5995)) - WITstudio
### others
- first commit: init - ([7c97ec1](https://github.com/WITstudio86//commit/7c97ec1228e0ce282a9bbc3c5547070272a67c36)) - WITstudio
<!-- 由 git-cliff 生成 -->
自动化
自动化执行流程,在每次 Git 提交之前执行 cargo fmt
、cargo deny
、nextest
、typos
和 git-cliff
,可以使用 Git 钩子来实现。Git 钩子(git hooks)是 Git 提供的一种机制,可以在特定的 Git 操作(如提交、推送、合并等)之前或之后执行自定义脚本。
使用pre-commit
我们可以使用 pre-commit
钩子来在每次提交之前自动执行这些任务。如果它们都通过了,提交才会继续进行。以下是如何配置和实现这一流程:
安装
先通过pip
安装 pre-commit
, 这需要电脑中存在 pip 工具 , 需要安装 python
shell
$ pip install pre-commit
和之前其他工具一样 ,安装之后可以通过--version
检查安装是否成功
配置
在 .pre-commit-config.yaml
文件中,配置你要执行的所有工具。
toml
# 如果检测到任何钩子失败,pre-commit 将不会继续执行剩余的钩子。
fail_fast: false
# repos 是一个钩子仓库的列表,每个仓库可以包含多个钩子。
repos:
# 每个仓库通过 URL 指定,并且可以指定特定的版本(rev)。
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
# 这是从上述仓库中定义的钩子列表。
- id: check-byte-order-marker # 检查文件是否包含字节顺序标记(BOM)。
- id: check-case-conflict # 检查文件名在不同操作系统的大小写冲突。
- id: check-merge-conflict # 检查文件中是否有合并冲突。
- id: check-symlinks # 检查文件是否是符号链接。
- id: check-yaml # 检查 YAML 文件的格式。
- id: end-of-file-fixer # 确保文件以单个换行符结束。
- id: mixed-line-ending # 检查文件的行结束符是否一致。
- id: trailing-whitespace # 检查并修复行尾的空格。
# local 部分定义了本地钩子。
- repo: local
hooks:
# 每个钩子有以下属性:
# id: 钩子的唯一标识符。
# name: 钩子的名称。
# description: 钩子的描述。
# entry: 要执行的命令。
# language: 钩子运行的语言环境。
# files: 钩子应该运行的文件模式。
# args: 传递给钩子的参数列表。
# pass_filenames: 如果设置为 false,pre-commit 将不会传递文件名给钩子脚本。
- id: cargo-fmt
name: cargo fmt
description: Format files with rustfmt.
entry: bash -c 'cargo fmt -- --check'
language: rust
files: \.rs$ # 钩子仅对 Rust 源文件生效。
args: [] # 不传递额外的参数。
- .......
- ......
cargo make
pre-commit 本身是按照顺序执行某些特定的指令 , fail_fast
配置在出错的时候是否继续执行 , cargo make 可以实现定义多个子指令 , 并将他们组合,配置依赖 , 轻松的组合成为很多不同的自动化脚本
安装
首先,确保你已经安装了 Rust 环境。如果尚未安装 Rust,请访问 Rust 官网 进行安装。
然后,使用以下命令通过 cargo
安装 cargo make
shell
$ cargo install --force cargo-make
使用
我们需要使用一个Makefile.toml
文件对cargo make
进行配置 , 配置很简单,
[tasks.<name>]
配置不同任务的别名command
设置要执行的指令args
设置传递的参数dependencies
用于设置依赖 , 说明当前任务需要依赖于哪个任务的成功install_crate
可以帮助下载需要的 crate
下面是一个实例:
toml
[tasks.format]
install_crate="rustfmt"
command = "cargo"
args = ["fmt", "--", "--emit=files"]
[tasks.clean]
command = "cargo"
args = ["clean"]
[tasks.build]
command = "cargo"
args = ["build"]
dependencies = ["clean"]
[tasks.test]
command = "cargo"
args = ["test"]
dependencies = ["clean"]
[tasks.my-flow]# 下面指令执行时的my-flow是在这里定义的别名
dependencies = [
"format",
"build",
"test"
]
在使用的时候只需要执行下面的指令即可:
shell
$ cargo make my-flow
下面是对于本篇所说到的所有工具的自动化执行配置:
toml
[tasks.format]
command = "cargo"
args = ["fmt", "--", "--emit=files"]
[tasks.deny]
install_crate="cargo-deny"
command = "cargo"
args = ["deny" , "check"]
[tasks.typos]
install_crate="typos-cli"
command = "typos"
dependencies = ["deny"]
[tasks.check]
command = "cargo"
args = ["check" , "--all"]
dependencies = ["typos"]
[tasks.clippy]# 一种代码风格检查工具
command = "cargo"
args = ["clippy" , "--all-features" , "--tests" , "--benches" , "--", "-D" , "warnings"]
dependencies = ["check"]
[tasks.test]
install_crate="cargo-nextest"
command = "cargo"
args = ["nextest" , "run"]
dependencies = ["clippy"]
[tasks.commit]
command = "git"
args = ["commit" , "-a"]
dependencies = ["test"]
[tasks.cliff]
install_crate="git-cliff"
command = "git"
args = ["cliff" , "-o" , "CHANGELOG.md"]
dependencies = ["commit"]
[tasks.doit]
dependencies = [
"format",
"deny",
"typos",
"check",
"clippy",
"test",
"commit",
"cliff"
]
从模板新建
经过刚才的配置 , 现在的项目目录看起来应该像是下面这样:
css
.
├── CHANGELOG.md
├── Cargo.toml
├── Makefile.toml
├── deny.toml
├── README.md
├── src
│ └── main.rs
└── typos.toml
generate
让我们可以将这个项目目录作为模本使用 , 首先将这个项目 push到 github , 然后下载 generate
并通过它创建一个新的项目
shell
$ cargo install cargo-generate
$ cargo generate --git 模板的github地址
视频版: 小破站