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(())
}

注意事项

  1. Git相关信息只在Git仓库中可用
  2. 构建时间是在编译时确定的
  3. 自定义数据需要在build.rs中设置
  4. 生产环境建议禁用调试信息

故障排除

如果遇到Git信息无法获取的问题:

  • 确认项目在Git仓库中
  • 检查.git目录权限
  • 考虑在配置中禁用Git功能

这个库为Rust应用程序提供了简单可靠的构建时元数据管理方案,特别适合需要版本追踪和构建信息显示的应用程序。

回到顶部