treewide: remove dead code; track more activity types
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I8ef141010291a30f28d1d3e8bb9567046a6a6964
This commit is contained in:
parent
503fcbf4e2
commit
287dec65c3
4 changed files with 205 additions and 205 deletions
|
|
@ -35,19 +35,6 @@ pub enum Verbosity {
|
||||||
Vomit = 7,
|
Vomit = 7,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Activity progress tracking for downloads/uploads/builds
|
|
||||||
#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
pub struct ActivityProgress {
|
|
||||||
/// Bytes completed
|
|
||||||
pub done: u64,
|
|
||||||
/// Total bytes expected
|
|
||||||
pub expected: u64,
|
|
||||||
/// Currently running transfers
|
|
||||||
pub running: u64,
|
|
||||||
/// Failed transfers
|
|
||||||
pub failed: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Id = u64;
|
pub type Id = u64;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
|
|
||||||
|
|
@ -382,9 +382,9 @@ impl<W: Write> Display<W> {
|
||||||
|| downloading > 0
|
|| downloading > 0
|
||||||
|| uploading > 0
|
|| uploading > 0
|
||||||
{
|
{
|
||||||
lines.push(self.colored(&"═".repeat(60), Color::Blue).to_string());
|
lines.push(self.colored(&"═".repeat(60), Color::Blue).clone());
|
||||||
lines.push(format!("{} Build Summary", self.colored("┃", Color::Blue)));
|
lines.push(format!("{} Build Summary", self.colored("┃", Color::Blue)));
|
||||||
lines.push(self.colored(&"─".repeat(60), Color::Blue).to_string());
|
lines.push(self.colored(&"─".repeat(60), Color::Blue).clone());
|
||||||
|
|
||||||
// Builds section
|
// Builds section
|
||||||
if running + completed + failed > 0 {
|
if running + completed + failed > 0 {
|
||||||
|
|
@ -431,7 +431,7 @@ impl<W: Write> Display<W> {
|
||||||
self.format_duration(duration)
|
self.format_duration(duration)
|
||||||
));
|
));
|
||||||
|
|
||||||
lines.push(self.colored(&"═".repeat(60), Color::Blue).to_string());
|
lines.push(self.colored(&"═".repeat(60), Color::Blue).clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
lines
|
lines
|
||||||
|
|
|
||||||
|
|
@ -223,8 +223,7 @@ impl<W: Write> Monitor<W> {
|
||||||
.full_summary
|
.full_summary
|
||||||
.running_downloads
|
.running_downloads
|
||||||
.get(&path_id)
|
.get(&path_id)
|
||||||
.map(|t| t.start)
|
.map_or(now, |t| t.start);
|
||||||
.unwrap_or(now);
|
|
||||||
|
|
||||||
let completed = crate::state::CompletedTransferInfo {
|
let completed = crate::state::CompletedTransferInfo {
|
||||||
start,
|
start,
|
||||||
|
|
@ -405,30 +404,6 @@ fn extract_path_from_message(line: &str) -> Option<String> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse byte size from human-readable format (e.g., "123 KiB", "4.5 MiB")
|
|
||||||
/// Supports: B, KiB, MiB, GiB, TiB, PiB
|
|
||||||
fn parse_byte_size(text: &str) -> Option<u64> {
|
|
||||||
let parts: Vec<&str> = text.split_whitespace().collect();
|
|
||||||
if parts.len() < 2 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let value: f64 = parts[0].parse().ok()?;
|
|
||||||
let unit = parts[1];
|
|
||||||
|
|
||||||
let multiplier = match unit {
|
|
||||||
"B" => 1_u64,
|
|
||||||
"KiB" => 1024,
|
|
||||||
"MiB" => 1024 * 1024,
|
|
||||||
"GiB" => 1024 * 1024 * 1024,
|
|
||||||
"TiB" => 1024_u64 * 1024 * 1024 * 1024,
|
|
||||||
"PiB" => 1024_u64 * 1024 * 1024 * 1024 * 1024,
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
Some((value * multiplier as f64) as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extract byte size from a message line (e.g., "downloaded 123 KiB")
|
/// Extract byte size from a message line (e.g., "downloaded 123 KiB")
|
||||||
fn extract_byte_size(line: &str) -> Option<u64> {
|
fn extract_byte_size(line: &str) -> Option<u64> {
|
||||||
// Look for patterns like "123 KiB", "6.7 MiB", etc.
|
// Look for patterns like "123 KiB", "6.7 MiB", etc.
|
||||||
|
|
@ -483,19 +458,6 @@ mod tests {
|
||||||
assert!(path.is_some());
|
assert!(path.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_byte_size() {
|
|
||||||
assert_eq!(parse_byte_size("123 B"), Some(123));
|
|
||||||
assert_eq!(parse_byte_size("1 KiB"), Some(1024));
|
|
||||||
assert_eq!(parse_byte_size("1 MiB"), Some(1024 * 1024));
|
|
||||||
assert_eq!(parse_byte_size("1 GiB"), Some(1024 * 1024 * 1024));
|
|
||||||
assert_eq!(
|
|
||||||
parse_byte_size("2.5 MiB"),
|
|
||||||
Some((2.5 * 1024.0 * 1024.0) as u64)
|
|
||||||
);
|
|
||||||
assert_eq!(parse_byte_size("invalid"), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_extract_byte_size() {
|
fn test_extract_byte_size() {
|
||||||
let line = "downloaded 123 KiB in 2 seconds";
|
let line = "downloaded 123 KiB in 2 seconds";
|
||||||
|
|
|
||||||
|
|
@ -91,18 +91,25 @@ fn handle_start(
|
||||||
});
|
});
|
||||||
|
|
||||||
let changed = match activity_u8 {
|
let changed = match activity_u8 {
|
||||||
104 | 105 => handle_build_start(state, id, parent_id, &text, &fields, now), /* Builds | Build */
|
105 => handle_build_start(state, id, parent_id, &text, &fields, now), /* Build */
|
||||||
108 => handle_substitute_start(state, id, &text, &fields, now), /* Substitute */
|
108 => handle_substitute_start(state, id, &text, &fields, now), /* Substitute */
|
||||||
101 => handle_transfer_start(state, id, &text, &fields, now, false), /* FileTransfer */
|
109 => handle_query_path_info_start(state, id, &text, &fields, now), /* QueryPathInfo */
|
||||||
100 | 103 => handle_transfer_start(state, id, &text, &fields, now, true), /* CopyPath | CopyPaths */
|
110 => handle_post_build_hook_start(state, id, &text, &fields, now), /* PostBuildHook */
|
||||||
_ => false,
|
101 => handle_file_transfer_start(state, id, &text, &fields, now), /* FileTransfer */
|
||||||
|
100 => handle_copy_path_start(state, id, &text, &fields, now), // CopyPath
|
||||||
|
102 | 103 | 104 | 106 | 107 | 111 | 112 => {
|
||||||
|
// Realise, CopyPaths, Builds, OptimiseStore, VerifyPaths, BuildWaiting,
|
||||||
|
// FetchTree These activities have no fields and are just tracked
|
||||||
|
true
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
debug!("Unknown activity type: {}", activity_u8);
|
||||||
|
false
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Track parent-child relationships for dependency tree
|
// Track parent-child relationships for dependency tree
|
||||||
if changed
|
if changed && activity_u8 == 105 && parent_id.is_some() {
|
||||||
&& (activity_u8 == 104 || activity_u8 == 105)
|
|
||||||
&& parent_id.is_some()
|
|
||||||
{
|
|
||||||
let parent_act_id = parent_id.unwrap();
|
let parent_act_id = parent_id.unwrap();
|
||||||
|
|
||||||
// Find parent and child derivation IDs
|
// Find parent and child derivation IDs
|
||||||
|
|
@ -112,8 +119,8 @@ fn handle_start(
|
||||||
if let Some(parent_drv_id) = parent_drv_id {
|
if let Some(parent_drv_id) = parent_drv_id {
|
||||||
if let Some(child_drv_id) = child_drv_id {
|
if let Some(child_drv_id) = child_drv_id {
|
||||||
debug!(
|
debug!(
|
||||||
"Establishing parent-child relationship: parent={}, child={}",
|
"Establishing parent-child relationship: parent={parent_drv_id}, \
|
||||||
parent_drv_id, child_drv_id
|
child={child_drv_id}"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add child as a dependency of parent
|
// Add child as a dependency of parent
|
||||||
|
|
@ -152,9 +159,19 @@ fn handle_stop(state: &mut State, id: Id, now: f64) -> bool {
|
||||||
state.activities.remove(&id);
|
state.activities.remove(&id);
|
||||||
|
|
||||||
match activity_status.activity {
|
match activity_status.activity {
|
||||||
104 | 105 => handle_build_stop(state, id, now), // Builds | Build
|
105 => handle_build_stop(state, id, now), // Build
|
||||||
108 => handle_substitute_stop(state, id, now), // Substitute
|
108 => handle_substitute_stop(state, id, now), // Substitute
|
||||||
101 | 100 | 103 => handle_transfer_stop(state, id, now), /* FileTransfer, CopyPath, CopyPaths */
|
101 | 100 => handle_transfer_stop(state, id, now), // FileTransfer,
|
||||||
|
// CopyPath
|
||||||
|
109 | 110 => {
|
||||||
|
// QueryPathInfo, PostBuildHook - just acknowledge stop
|
||||||
|
false
|
||||||
|
},
|
||||||
|
102 | 103 | 104 | 106 | 107 | 111 | 112 => {
|
||||||
|
// Realise, CopyPaths, Builds, OptimiseStore, VerifyPaths, BuildWaiting,
|
||||||
|
// FetchTree
|
||||||
|
false
|
||||||
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -168,7 +185,7 @@ fn handle_message(state: &mut State, level: Verbosity, msg: String) -> bool {
|
||||||
|
|
||||||
// Extract phase from log messages like "Running phase: configurePhase"
|
// Extract phase from log messages like "Running phase: configurePhase"
|
||||||
if let Some(phase_start) = msg.find("Running phase: ") {
|
if let Some(phase_start) = msg.find("Running phase: ") {
|
||||||
let phase_name = &msg[phase_start + 15..]; // Skip "Running phase: "
|
let phase_name = &msg[phase_start + 15..]; // skip "Running phase: "
|
||||||
let phase = phase_name.trim().to_string();
|
let phase = phase_name.trim().to_string();
|
||||||
|
|
||||||
// Find the active build and update its phase
|
// Find the active build and update its phase
|
||||||
|
|
@ -247,38 +264,70 @@ fn handle_message(state: &mut State, level: Verbosity, msg: String) -> bool {
|
||||||
fn handle_result(
|
fn handle_result(
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
id: Id,
|
id: Id,
|
||||||
activity: u8,
|
result_type: u8,
|
||||||
fields: Vec<serde_json::Value>,
|
fields: Vec<serde_json::Value>,
|
||||||
_now: f64,
|
_now: f64,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match activity {
|
// Result message types are DIFFERENT from Activity types
|
||||||
101 | 108 => {
|
// Type 100: FileLinked (2 ints)
|
||||||
// FileTransfer or Substitute
|
// Type 101: BuildLogLine (1 text)
|
||||||
// Fields contain progress information
|
// Type 102: UntrustedPath (1 text - store path)
|
||||||
// Format: [bytes_transferred, total_bytes]
|
// Type 103: CorruptedPath (1 text - store path)
|
||||||
|
// Type 104: SetPhase (1 text)
|
||||||
|
// Type 105: Progress (4 ints: done, expected, running, failed)
|
||||||
|
// Type 106: SetExpected (2 ints: activity type, count)
|
||||||
|
// Type 107: PostBuildLogLine (1 text)
|
||||||
|
// Type 108: FetchStatus (1 text)
|
||||||
|
|
||||||
|
match result_type {
|
||||||
|
100 => {
|
||||||
|
// FileLinked: 2 int fields
|
||||||
if fields.len() >= 2 {
|
if fields.len() >= 2 {
|
||||||
update_transfer_progress(state, id, &fields);
|
let _linked = fields[0].as_u64();
|
||||||
|
let _total = fields[1].as_u64();
|
||||||
|
// TODO: Track file linking progress
|
||||||
|
}
|
||||||
|
false
|
||||||
|
},
|
||||||
|
101 => {
|
||||||
|
// BuildLogLine: 1 text field
|
||||||
|
if let Some(line) = fields.first().and_then(|f| f.as_str()) {
|
||||||
|
state.build_logs.push(line.to_string());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
},
|
||||||
|
102 => {
|
||||||
|
// UntrustedPath: 1 text field (store path)
|
||||||
|
if let Some(path_str) = fields.first().and_then(|f| f.as_str()) {
|
||||||
|
debug!("Untrusted path: {}", path_str);
|
||||||
|
// TODO: Track untrusted paths
|
||||||
|
}
|
||||||
|
false
|
||||||
|
},
|
||||||
|
103 => {
|
||||||
|
// CorruptedPath: 1 text field (store path)
|
||||||
|
if let Some(path_str) = fields.first().and_then(|f| f.as_str()) {
|
||||||
|
state
|
||||||
|
.nix_errors
|
||||||
|
.push(format!("Corrupted path: {path_str}"));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
},
|
},
|
||||||
104 => {
|
104 => {
|
||||||
// Builds activity type - contains phase information or progress
|
// SetPhase: 1 text field
|
||||||
if !fields.is_empty() {
|
if let Some(phase_str) = fields.first().and_then(|f| f.as_str()) {
|
||||||
if let Some(phase_str) = fields[0].as_str() {
|
if let Some(activity) = state.activities.get_mut(&id) {
|
||||||
// Update the activity's phase field
|
activity.phase = Some(phase_str.to_string());
|
||||||
if let Some(activity) = state.activities.get_mut(&id) {
|
return true;
|
||||||
activity.phase = Some(phase_str.to_string());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
},
|
},
|
||||||
105 => {
|
105 => {
|
||||||
// Progress update (done, expected, running, failed)
|
// Progress: 4 int fields (done, expected, running, failed)
|
||||||
// OR Build completed (fields contain output path as string)
|
|
||||||
if fields.len() >= 4 {
|
if fields.len() >= 4 {
|
||||||
// This is a progress update: [done, expected, running, failed]
|
|
||||||
if let (Some(done), Some(expected), Some(running), Some(failed)) = (
|
if let (Some(done), Some(expected), Some(running), Some(failed)) = (
|
||||||
fields[0].as_u64(),
|
fields[0].as_u64(),
|
||||||
fields[1].as_u64(),
|
fields[1].as_u64(),
|
||||||
|
|
@ -294,19 +343,39 @@ fn handle_result(
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
false
|
||||||
if !fields.is_empty() && fields[0].is_string() {
|
},
|
||||||
// This is a build completion with output path
|
106 => {
|
||||||
complete_build(state, id)
|
// SetExpected: 2 int fields (activity type, count)
|
||||||
} else {
|
if fields.len() >= 2 {
|
||||||
// Legacy: just mark build as complete
|
let _activity_type = fields[0].as_u64();
|
||||||
complete_build(state, id)
|
let _expected_count = fields[1].as_u64();
|
||||||
}
|
// TODO: Track expected counts
|
||||||
|
}
|
||||||
|
false
|
||||||
|
},
|
||||||
|
107 => {
|
||||||
|
// PostBuildLogLine: 1 text field
|
||||||
|
if let Some(line) = fields.first().and_then(|f| f.as_str()) {
|
||||||
|
state.build_logs.push(format!("[post-build] {line}"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
},
|
||||||
|
108 => {
|
||||||
|
// FetchStatus: 1 text field
|
||||||
|
if let Some(status) = fields.first().and_then(|f| f.as_str()) {
|
||||||
|
debug!("Fetch status: {}", status);
|
||||||
|
// TODO: Track fetch status
|
||||||
|
}
|
||||||
|
false
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
debug!("Unknown result type: {}", result_type);
|
||||||
|
false
|
||||||
},
|
},
|
||||||
_ => false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,55 +427,19 @@ fn handle_build_start(
|
||||||
);
|
);
|
||||||
|
|
||||||
// Mark as forest root if no parent
|
// Mark as forest root if no parent
|
||||||
// Only add to forest roots if no parent
|
|
||||||
if parent_id.is_none() && !state.forest_roots.contains(&drv_id) {
|
if parent_id.is_none() && !state.forest_roots.contains(&drv_id) {
|
||||||
state.forest_roots.push(drv_id);
|
state.forest_roots.push(drv_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store activity -> derivation mapping
|
|
||||||
// Phase will be extracted from log messages
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
debug!("Failed to parse derivation from path: {}", drv_path);
|
debug!("Failed to parse derivation from path: {}", drv_path);
|
||||||
} else {
|
} else {
|
||||||
debug!(
|
debug!(
|
||||||
"No derivation path found - creating placeholder for activity {}",
|
"No derivation path in fields for Build activity {} - this should not \
|
||||||
|
happen",
|
||||||
id
|
id
|
||||||
);
|
);
|
||||||
// For shell/develop commands, nix doesn't report specific derivation paths
|
|
||||||
// Create a placeholder derivation to track that builds are happening
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
let placeholder_name = format!("building-{id}");
|
|
||||||
let placeholder_path = format!("/nix/store/placeholder-{id}.drv");
|
|
||||||
|
|
||||||
let placeholder_drv = Derivation {
|
|
||||||
path: PathBuf::from(placeholder_path),
|
|
||||||
name: placeholder_name,
|
|
||||||
};
|
|
||||||
|
|
||||||
let drv_id = state.get_or_create_derivation_id(placeholder_drv);
|
|
||||||
let host = extract_host(text);
|
|
||||||
|
|
||||||
let build_info = BuildInfo {
|
|
||||||
start: now,
|
|
||||||
host,
|
|
||||||
estimate: None,
|
|
||||||
activity_id: Some(id),
|
|
||||||
};
|
|
||||||
|
|
||||||
debug!(
|
|
||||||
"Setting placeholder derivation {} to Building status",
|
|
||||||
drv_id
|
|
||||||
);
|
|
||||||
state.update_build_status(drv_id, BuildStatus::Building(build_info));
|
|
||||||
|
|
||||||
// Mark as forest root if no parent
|
|
||||||
if parent_id.is_none() && !state.forest_roots.contains(&drv_id) {
|
|
||||||
state.forest_roots.push(drv_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
@ -512,45 +545,111 @@ fn handle_substitute_stop(state: &mut State, id: Id, now: f64) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_transfer_start(
|
fn handle_file_transfer_start(
|
||||||
|
_state: &mut State,
|
||||||
|
id: Id,
|
||||||
|
_text: &str,
|
||||||
|
fields: &[serde_json::Value],
|
||||||
|
_now: f64,
|
||||||
|
) -> bool {
|
||||||
|
// FileTransfer expects 1 text field: URL or description
|
||||||
|
if fields.is_empty() {
|
||||||
|
debug!("FileTransfer activity {} has no fields", id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just track the activity, actual progress comes via Result messages
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_copy_path_start(
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
id: Id,
|
id: Id,
|
||||||
text: &str,
|
_text: &str,
|
||||||
fields: &[serde_json::Value],
|
fields: &[serde_json::Value],
|
||||||
now: f64,
|
now: f64,
|
||||||
is_copy: bool,
|
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let path_str = if fields.is_empty() {
|
// CopyPath expects 3 text fields: path, from, to
|
||||||
extract_store_path(text)
|
if fields.len() < 3 {
|
||||||
} else {
|
debug!("CopyPath activity {} has insufficient fields", id);
|
||||||
fields[0].as_str().map(std::string::ToString::to_string)
|
return false;
|
||||||
};
|
}
|
||||||
|
|
||||||
if let Some(path_str) = path_str {
|
let path_str = fields[0].as_str();
|
||||||
if let Some(path) = StorePath::parse(&path_str) {
|
let _from_host = fields[1].as_str().map(|s| {
|
||||||
|
if s.is_empty() || s == "localhost" {
|
||||||
|
Host::Localhost
|
||||||
|
} else {
|
||||||
|
Host::Remote(s.to_string())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let to_host = fields[2].as_str().map(|s| {
|
||||||
|
if s.is_empty() || s == "localhost" {
|
||||||
|
Host::Localhost
|
||||||
|
} else {
|
||||||
|
Host::Remote(s.to_string())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if let (Some(path_str), Some(to)) = (path_str, to_host) {
|
||||||
|
if let Some(path) = StorePath::parse(path_str) {
|
||||||
let path_id = state.get_or_create_store_path_id(path);
|
let path_id = state.get_or_create_store_path_id(path);
|
||||||
let host = extract_host(text);
|
|
||||||
|
|
||||||
let transfer = TransferInfo {
|
let transfer = TransferInfo {
|
||||||
start: now,
|
start: now,
|
||||||
host,
|
host: to, // destination host
|
||||||
activity_id: id,
|
activity_id: id,
|
||||||
bytes_transferred: 0,
|
bytes_transferred: 0,
|
||||||
total_bytes: None,
|
total_bytes: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_copy {
|
// CopyPath is an upload from 'from' to 'to'
|
||||||
state.full_summary.running_uploads.insert(path_id, transfer);
|
state.full_summary.running_uploads.insert(path_id, transfer);
|
||||||
} else {
|
|
||||||
state
|
|
||||||
.full_summary
|
|
||||||
.running_downloads
|
|
||||||
.insert(path_id, transfer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_query_path_info_start(
|
||||||
|
_state: &mut State,
|
||||||
|
id: Id,
|
||||||
|
_text: &str,
|
||||||
|
fields: &[serde_json::Value],
|
||||||
|
_now: f64,
|
||||||
|
) -> bool {
|
||||||
|
// QueryPathInfo expects 2 text fields: path, host
|
||||||
|
if fields.len() < 2 {
|
||||||
|
debug!("QueryPathInfo activity {} has insufficient fields", id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just track the activity
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_post_build_hook_start(
|
||||||
|
_state: &mut State,
|
||||||
|
id: Id,
|
||||||
|
_text: &str,
|
||||||
|
fields: &[serde_json::Value],
|
||||||
|
_now: f64,
|
||||||
|
) -> bool {
|
||||||
|
// PostBuildHook expects 1 text field: derivation path
|
||||||
|
if fields.is_empty() {
|
||||||
|
debug!("PostBuildHook activity {} has no fields", id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let drv_path = fields[0].as_str();
|
||||||
|
if let Some(drv_path) = drv_path {
|
||||||
|
if let Some(_drv) = Derivation::parse(drv_path) {
|
||||||
|
// Just track that the hook is running
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -599,54 +698,6 @@ fn handle_transfer_stop(state: &mut State, id: Id, now: f64) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_transfer_progress(
|
|
||||||
state: &mut State,
|
|
||||||
id: Id,
|
|
||||||
fields: &[serde_json::Value],
|
|
||||||
) {
|
|
||||||
if fields.len() < 2 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let bytes_transferred = fields[0].as_u64().unwrap_or(0);
|
|
||||||
let total_bytes = fields[1].as_u64();
|
|
||||||
|
|
||||||
// Update running downloads
|
|
||||||
for transfer_info in state.full_summary.running_downloads.values_mut() {
|
|
||||||
if transfer_info.activity_id == id {
|
|
||||||
transfer_info.bytes_transferred = bytes_transferred;
|
|
||||||
transfer_info.total_bytes = total_bytes;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update running uploads
|
|
||||||
for transfer_info in state.full_summary.running_uploads.values_mut() {
|
|
||||||
if transfer_info.activity_id == id {
|
|
||||||
transfer_info.bytes_transferred = bytes_transferred;
|
|
||||||
transfer_info.total_bytes = total_bytes;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn complete_build(state: &mut State, id: Id) -> bool {
|
|
||||||
// Find the derivation that just completed
|
|
||||||
for (drv_id, info) in &state.derivation_infos.clone() {
|
|
||||||
if let BuildStatus::Building(build_info) = &info.build_status {
|
|
||||||
if build_info.activity_id == Some(id) {
|
|
||||||
let end = current_time();
|
|
||||||
state.update_build_status(*drv_id, BuildStatus::Built {
|
|
||||||
info: build_info.clone(),
|
|
||||||
end,
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_derivation_path(text: &str) -> Option<String> {
|
fn extract_derivation_path(text: &str) -> Option<String> {
|
||||||
// Look for .drv paths in the text
|
// Look for .drv paths in the text
|
||||||
if let Some(start) = text.find("/nix/store/") {
|
if let Some(start) = text.find("/nix/store/") {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue