harness_cli/configs/
run_info.rs1use std::{collections::HashMap, ops::Deref, path::PathBuf};
21
22use cargo_metadata::MetadataCommand;
23use chrono::{DateTime, Local};
24use serde::{Deserialize, Serialize};
25
26use crate::utils::{self, lockfile::load_lockfiles};
27
28use super::harness::{CargoConfig, Profile};
29
30#[derive(Debug, Serialize, Deserialize)]
31pub struct ProfileWithName {
32 pub name: String,
33 #[serde(flatten)]
34 pub profile: Profile,
35}
36
37impl Deref for ProfileWithName {
38 type Target = Profile;
39
40 fn deref(&self) -> &Self::Target {
41 &self.profile
42 }
43}
44
45#[derive(Debug, Serialize, Deserialize)]
47pub struct RunInfo {
48 pub version: i32,
50 pub runid: String,
52 pub project: String,
54 #[serde(rename = "start-time-utc")]
56 pub start_timestamp_utc: i64,
57 #[serde(rename = "finish-time-utc")]
59 pub finish_timestamp_utc: Option<i64>,
60 pub commit: String,
62 #[serde(rename = "crate")]
64 pub crate_info: CrateInfo,
65 pub profile: ProfileWithName,
67 pub system: SystemInfo,
69 pub lockfiles: Lockfiles,
71}
72
73impl RunInfo {
74 pub(crate) fn new_v0(
75 crate_info: CrateInfo,
76 profile: Profile,
77 runid: String,
78 profile_name: String,
79 project: Option<String>,
80 start_time: DateTime<Local>,
81 ) -> anyhow::Result<Self> {
82 let lockfiles = load_lockfiles(&crate_info, &profile)?;
83 let project = project.unwrap_or_else(|| crate_info.name.clone());
84 Ok(Self {
85 version: 0,
86 crate_info,
87 project,
88 system: utils::sys::get_current_system_info(),
89 profile: ProfileWithName {
90 name: profile_name,
91 profile,
92 },
93 runid,
94 commit: utils::git::get_git_hash()?,
95 start_timestamp_utc: start_time.to_utc().timestamp(),
96 finish_timestamp_utc: None,
97 lockfiles,
98 })
99 }
100
101 pub(crate) fn load(path: &PathBuf) -> anyhow::Result<Self> {
102 let content = std::fs::read_to_string(path)?;
103 Ok(toml::from_str(&content)?)
104 }
105}
106
107#[derive(Debug, Serialize, Deserialize, Clone)]
109pub struct CrateInfo {
110 pub name: String,
112 pub target_dir: PathBuf,
114 pub benches: Vec<String>,
116 pub workspace_root: PathBuf,
118}
119
120impl CrateInfo {
121 pub(crate) fn get_target_path() -> anyhow::Result<PathBuf> {
122 let Ok(meta) = MetadataCommand::new().manifest_path("./Cargo.toml").exec() else {
123 anyhow::bail!("Failed to get metadata from ./Cargo.toml");
124 };
125 let target_dir = meta.target_directory.as_std_path();
126 Ok(target_dir.to_owned())
127 }
128
129 pub(crate) fn load() -> anyhow::Result<Self> {
130 let Ok(meta) = MetadataCommand::new().manifest_path("./Cargo.toml").exec() else {
131 anyhow::bail!("Failed to get metadata from ./Cargo.toml");
132 };
133 let target_dir = meta.target_directory.as_std_path();
134 let Some(pkg) = meta.root_package() else {
135 anyhow::bail!("No root package found");
136 };
137 let benches = CargoConfig::load_benches()?;
138 Ok(CrateInfo {
139 name: pkg.name.clone(),
140 target_dir: target_dir.to_owned(),
141 benches,
142 workspace_root: meta.workspace_root.as_std_path().to_owned(),
143 })
144 }
145}
146
147#[derive(Debug, Serialize, Deserialize, Clone)]
149pub struct SystemInfo {
150 pub host: String,
152 pub os: String,
154 pub arch: String,
156 #[serde(rename = "kernel-version")]
158 pub kernel: String,
159 #[serde(rename = "cpu-model")]
161 pub cpu_model: String,
162 #[serde(rename = "cpu-frequency")]
164 pub cpu_frequency: Vec<usize>,
165 pub memory_size: usize,
167 pub swap_size: usize,
169 #[cfg(target_os = "linux")]
171 pub users: Vec<String>,
172 pub processes: usize,
174 pub env: HashMap<String, String>,
176 pub pid: usize,
178 pub rustc: String,
180 #[cfg(target_os = "linux")]
182 #[serde(rename = "scaling-governor")]
183 pub scaling_governor: Vec<String>,
184}
185
186#[derive(Debug, Serialize, Deserialize)]
188pub struct Lockfiles {
189 #[serde(flatten)]
190 pub lockfiles: HashMap<String, toml::Value>,
191}