Rust构建数据管理库build-data的使用,轻松收集和注入构建时元数据到应用程序中
Rust构建数据管理库build-data的使用,轻松收集和注入构建时元数据到应用程序中
特性
- 保存构建时数据:
- Git提交、分支和脏状态
- 源代码修改日期和时间
- Rustc版本
- Rust渠道(stable、nightly或beta)
- 所有工作都在您的
build.rs
中完成 - 设置环境变量。使用
env!
在程序中使用它们 - 无宏
- 无运行时依赖
- 轻量级构建依赖
forbid(unsafe_code)
- 100%测试覆盖率
替代方案
- Cargo为crates设置的环境变量:
CARGO_PKG_NAME
CARGO_PKG_VERSION
CARGO_BIN_NAME
- 其他
vergen
- 成熟且非常流行
- 良好的API,只需要
env!
来检索值 - 优秀的测试覆盖率
- 重型构建依赖
build-info
- 成熟
- 令人困惑的API
- 使用过程宏
示例
# Cargo.toml
[dependencies]
[build-dependencies]
build-data = "0.3"
在您的Cargo.toml
旁边添加一个build.rs
文件。
调用build_data::set_*
函数来设置变量。
// build.rs
fn main() {
build_data::set_GIT_BRANCH().unwrap();
build_data::set_GIT_COMMIT().unwrap();
build_data::set_GIT_DIRTY().unwrap();
build_data::set_SOURCE_TIMESTAMP().unwrap();
build_data::no_debug_rebuilds().unwrap();
}
使用env!
在程序中访问变量:
// src/bin/main.rs
fn main() {
// Built from branch=release
// commit=a5547bfb1edb9712588f0f85d3e2c8ba618ac51f
// dirty=false
// source_timestamp=2021-04-14T06:25:59+00:00
println!("Built from branch={} commit={} dirty={} source_timestamp={}",
env!("GIT_BRANCH"),
env!("GIT_COMMIT"),
env!("GIT_DIRTY"),
env!("SOURCE_TIMESTAMP"),
);
}
Cargo Geiger安全报告
Metric output format: x/y
x = unsafe code used by the build
y = total unsafe code found in the crate
Symbols:
🔒 = No `unsafe` usage found, declares #![forbid(unsafe_code)]
❓ = No `unsafe` usage found, missing #![forbid(unsafe_code)]
☢️ = `unsafe` usage found
Functions Expressions Impls Traits Methods Dependency
0/0 0/6 0/0 0/0 0/0 🔒 build-data 0.3.3
0/0 1/13 1/1 0/0 0/0 ☢️ ├── chrono 0.4.41
0/0 0/0 0/0 0/0 0/0 ❓ │ ├── num-traits 0.2.19
0/0 0/5 0/0 0/0 0/0 ❓ │ └── serde 1.0.219
0/0 0/0 0/0 0/0 0/0 ❓ │ └── serde_derive 1.0.219
0/0 0/14 0/0 0/0 0/3 ❓ │ ├── proc-macro2 1.0.95
0/0 0/4 0/0 0/0 0/0 ❓ │ │ └── unicode-ident 1.0.18
0/0 0/0 0/0 0/0 0/0 ❓ │ ├── quote 1.0.40
0/0 0/14 0/0 0/0 0/3 ❓ │ │ └── proc-macro2 1.0.95
0/0 0/88 0/3 0/0 0/2 ❓ │ └── syn 2.0.101
0/0 0/14 0/0 0/0 0/3 ❓ │ ├── proc-macro2 1.0.95
0/0 0/0 0/0 0/0 0/0 ❓ │ ├── quote 1.0.40
0/0 0/4 0/0 0/0 0/0 ❓ │ └── unicode-ident 1.0.18
0/0 0/0 0/0 0/0 0/0 🔒 └── safe-regex 0.3.0
0/0 0/0 0/0 0/0 0/0 🔒 └── safe-regex-macro 0.3.0
0/0 0/0 0/0 0/0 0/0 🔒 ├── safe-proc-macro2 1.0.95
0/0 0/0 0/0 0/0 0/0 🔒 │ └── unicode-xid 0.2.6
0/0 0/0 0/0 0/0 0/0 🔒 └── safe-regex-compiler 0.3.0
0/0 0/0 0/0 0/0 0/0 🔒 ├── safe-proc-macro2 1.0.95
0/0 0/0 0/0 0/0 0/0 🔒 └── safe-quote 1.0.40
0/0 0/0 0/0 0/0 0/0 🔒 └── safe-proc-macro2 1.0.95
0/0 1/130 1/4 0/0 0/5
变更日志
- v0.3.3 - 重建文档
- v0.3.2 - 移除测试二进制文件
- v0.3.1 - 重建文档
- v0.3.0 - 返回
Result
且不panic - v0.2.3 - 添加
rerun_if_git_commit_or_branch_changed
- v0.2.2 - 修复当git配置有
log.showsignature=true
时的get_source_time
- v0.2.1
- 添加
set_TARGET_PLATFORM
。感谢tison! - 在辅助函数中使用u64作为时间戳
- 添加
- v0.1.5 - 更新依赖。感谢dignifiedquire!
- v0.1.4 - 更新依赖
- v0.1.3 - 更新文档
- v0.1.2 - 根据r/rust的反馈重写
- v0.1.1 - 更新文档
- v0.1.0 - 初始版本
待办事项
许可证:Apache-2.0
完整示例代码
# Cargo.toml
[package]
name = "build-data-example"
version = "0.1.0"
edition = "2021"
[dependencies]
[build-dependencies]
build-data = "0.3"
// build.rs
fn main() {
// 设置Git分支信息
build_data::set_GIT_BRANCH().unwrap();
// 设置Git提交信息
build_data::set_GIT_COMMIT().unwrap();
// 设置Git脏状态
build_data::set_GIT_DIRTY().unwrap();
// 设置源代码时间戳
build_data::set_SOURCE_TIMESTAMP().unwrap();
// 防止调试重建
build_data::no_debug_rebuilds().unwrap();
}
// src/main.rs
fn main() {
// 输出构建时收集的元数据信息
println!("应用程序构建信息:");
println!("Git分支: {}", env!("GIT_BRANCH"));
println!("Git提交: {}", env!("GIT_COMMIT"));
println!("Git脏状态: {}", env!("GIT_DIRTY"));
println!("源代码时间戳: {}", env!("SOURCE_TIMESTAMP"));
// 示例:根据构建信息显示不同的消息
let branch = env!("GIT_BRANCH");
if branch == "main" || branch == "master" {
println!("这是从主分支构建的生产版本");
} else {
println!("这是从{}分支构建的开发版本", branch);
}
// 检查是否为脏构建
let dirty = env!("GIT_DIRTY");
if dirty == "true" {
println!("警告:此构建包含未提交的更改");
}
}
1 回复
Rust构建数据管理库build-data的使用指南
介绍
build-data是一个轻量级的Rust库,用于在构建时收集系统元数据并将其注入到应用程序中。它可以帮助开发者轻松获取构建时间、Git提交信息、版本号等元数据,并在运行时访问这些信息。
主要特性
- 自动收集构建时间戳
- 获取Git仓库信息(提交哈希、分支名称)
- 自定义构建元数据
- 零运行时开销
- 简单的API设计
安装方法
在Cargo.toml中添加依赖:
[dependencies]
build-data = "0.4"
基本使用方法
1. 基本元数据收集
use build_data::{get_git_commit, get_git_branch, get_build_time};
fn main() {
println!("构建时间: {}", get_build_time());
println!("Git提交: {}", get_git_commit().unwrap_or("未知".to_string()));
println!("Git分支: {}", get_git_branch().unwrap_or("未知".to_string()));
}
2. 自定义构建信息
在build.rs中:
use build_data::{set_Git_commit, set_Git_branch, set_build_time};
fn main() {
// 设置自定义构建信息
build_data::set_Git_commit("custom-commit-hash");
build_data::set_Git_branch("development");
build_data::set_build_time("2023-10-01T12:00:00Z");
build_data::no_debug_rebuilds();
}
3. 高级用法 - 自定义元数据
use build_data::{set, get};
// 在build.rs中设置自定义数据
fn main() {
build_data::set("BUILD_MODE", "release");
build_data::set("API_VERSION", "v1.2.3");
}
// 在main.rs中获取数据
fn main() {
let build_mode = build_data::get("BUILD_MODE").unwrap();
let api_version = build_data::get("API_VERSION").unwrap();
println!("构建模式: {}", build_mode);
println!("API版本: {}", api_version);
}
配置选项
在Cargo.toml中配置:
[package.metadata.build-data]
# 禁用Git信息收集(默认为true)
git = false
# 自定义构建时间格式(默认为RFC3339)
time-format = "%Y-%m-%d %H:%M:%S"
实际应用示例
版本信息显示
use build_data::{get_git_commit, get_build_time, version};
fn main() {
println!("应用程序版本: {}", version!());
println!("构建信息:");
println!(" 时间: {}", get_build_time());
println!(" 提交: {}", get_git_commit().unwrap());
// 在调试模式下显示详细构建信息
#[cfg(debug_assertions)]
{
println!(" 构建模式: 调试");
}
}
自动化部署验证
use build_data::get_git_commit;
fn verify_deployment() -> Result<(), String> {
let current_commit = get_git_commit().map_err(|_| "无法获取Git提交信息")?;
// 验证当前运行的代码版本
if current_commit != EXPECTED_DEPLOY_COMMIT {
return Err(format!(
"版本不匹配: 预期 {}, 实际 {}",
EXPECTED_DEPLOY_COMMIT, current_commit
));
}
Ok(())
}
完整示例demo
基于上述内容,以下是一个完整的build-data使用示例:
Cargo.toml配置:
[package]
name = "build-data-demo"
version = "0.1.0"
edition = "2021"
[dependencies]
build-data = "0.4"
[package.metadata.build-data]
git = true
time-format = "%Y-%m-%d %H:%M:%S"
build.rs构建脚本:
use build_data::{set, set_Git_commit, set_Git_branch, set_build_time, no_debug_rebuilds};
fn main() {
// 设置自定义构建信息
set_Git_commit("custom-commit-hash");
set_Git_branch("development");
set_build_time("2023-10-01T12:00:00Z");
// 设置自定义元数据
set("BUILD_MODE", "release");
set("API_VERSION", "v1.2.3");
set("BUILD_SERVER", "ci-server-01");
// 防止调试重建
no_debug_rebuilds();
}
src/main.rs主程序:
use build_data::{get, get_git_commit, get_git_branch, get_build_time, version};
const EXPECTED_DEPLOY_COMMIT: &str = "custom-commit-hash";
fn main() {
// 显示基本构建信息
println!("=== 应用程序构建信息 ===");
println!("应用程序版本: {}", version!());
println!("构建时间: {}", get_build_time());
println!("Git提交: {}", get_git_commit().unwrap_or("未知".to_string()));
println!("Git分支: {}", get_git_branch().unwrap_or("未知".to_string()));
// 显示自定义构建信息
println!("\n=== 自定义构建配置 ===");
if let Some(build_mode) = get("BUILD_MODE") {
println!("构建模式: {}", build_mode);
}
if let Some(api_version) = get("API_VERSION") {
println!("API版本: {}", api_version);
}
if let Some(build_server) = get("BUILD_SERVER") {
println!("构建服务器: {}", build_server);
}
// 部署验证
println!("\n=== 部署验证 ===");
match verify_deployment() {
Ok(()) => println!("✅ 部署验证成功"),
Err(e) => println!("❌ 部署验证失败: {}", e),
}
// 调试信息
#[cfg(debug_assertions)]
{
println!("\n=== 调试信息 ===");
println!("当前运行在调试模式下");
}
}
/// 验证部署版本是否正确
fn verify_deployment() -> Result<(), String> {
let current_commit = get_git_commit().map_err(|_| "无法获取Git提交信息")?;
// 验证当前运行的代码版本
if current_commit != EXPECTED_DEPLOY_COMMIT {
return Err(format!(
"版本不匹配: 预期 {}, 实际 {}",
EXPECTED_DEPLOY_COMMIT, current_commit
));
}
Ok(())
}
注意事项
- Git相关信息只在Git仓库中可用
- 构建时间是在编译时确定的
- 自定义数据需要在build.rs中设置
- 生产环境建议禁用调试信息
故障排除
如果遇到Git信息无法获取的问题:
- 确认项目在Git仓库中
- 检查.git目录权限
- 考虑在配置中禁用Git功能
这个库为Rust应用程序提供了简单可靠的构建时元数据管理方案,特别适合需要版本追踪和构建信息显示的应用程序。