This commit is contained in:
2025-11-09 10:10:40 +00:00
parent ec1c1c89cd
commit 5c8dc86640
5 changed files with 152591 additions and 61 deletions

7
.gitignore vendored
View File

@@ -15,10 +15,3 @@ upload_test
/log /log
/log2 /log2
/nix-output-monitor /nix-output-monitor
/build.log
# Added by cargo
#
# already existing elements were commented out
#/target

152461
build.log Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,7 @@ pub enum ActionType {
QueryPathInfo = 109, QueryPathInfo = 109,
PostBuildHook = 110, PostBuildHook = 110,
BuildWaiting = 111, BuildWaiting = 111,
FetchTree = 112,
} }
impl Default for ActionType { impl Default for ActionType {
@@ -100,14 +101,24 @@ pub enum StartFields<'a> {
source: Cow<'a, str>, source: Cow<'a, str>,
target: Cow<'a, str>, target: Cow<'a, str>,
}, },
QueryPathInfo, QueryPathInfo {
path: Cow<'a, str>,
source: Cow<'a, str>,
},
PostBuildHook, PostBuildHook,
BuildWaiting, BuildWaiting,
FetchTree,
} }
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub enum ResultFields<'a> { pub enum ResultFields<'a> {
FileLinked {
val1: u64,
val2: u64,
},
BuildLogLine(Cow<'a, str>), BuildLogLine(Cow<'a, str>),
UntrustedPath(Cow<'a, str>),
CorruptedPath(Cow<'a, str>),
SetPhase(&'a str), SetPhase(&'a str),
Progress { Progress {
done: u64, done: u64,
@@ -119,6 +130,8 @@ pub enum ResultFields<'a> {
action: ActionType, action: ActionType,
expected: u64, expected: u64,
}, },
PostBuildLogLine(Cow<'a, str>),
FetchStatus(Cow<'a, str>),
} }
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]

View File

@@ -27,6 +27,7 @@ pub enum RawEnumType {
Progress = 105, Progress = 105,
SetExpected = 106, SetExpected = 106,
PostBuildLogLine = 107, PostBuildLogLine = 107,
FetchStatus = 108,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
@@ -110,9 +111,17 @@ impl<'a> TryFrom<RawAction<'a>> for Action<'a> {
StartFields::Substitute { source, target } StartFields::Substitute { source, target }
} }
ActionType::QueryPathInfo => StartFields::QueryPathInfo, ActionType::QueryPathInfo => {
let raw_fields = val.fields.ok_or_else(|| missing("fields"))?.get();
let (path, source) =
serde_json::from_str(raw_fields).context("invalid fields")?;
StartFields::QueryPathInfo { path, source }
}
ActionType::PostBuildHook => StartFields::PostBuildHook, ActionType::PostBuildHook => StartFields::PostBuildHook,
ActionType::BuildWaiting => StartFields::BuildWaiting, ActionType::BuildWaiting => StartFields::BuildWaiting,
ActionType::FetchTree => StartFields::FetchTree,
}; };
Action::Start { Action::Start {
@@ -128,13 +137,23 @@ impl<'a> TryFrom<RawAction<'a>> for Action<'a> {
let raw_fields = val.fields.ok_or_else(|| missing("fields"))?.get(); let raw_fields = val.fields.ok_or_else(|| missing("fields"))?.get();
let fields = match val.any_type.ok_or_else(|| missing("type"))? { let fields = match val.any_type.ok_or_else(|| missing("type"))? {
100 => todo!("FileLinked({raw_fields})"), 100 => {
let (val1, val2) =
serde_json::from_str(raw_fields).context("invalid fields")?;
ResultFields::FileLinked { val1, val2 }
}
101 => { 101 => {
let [line] = serde_json::from_str(raw_fields).context("invalid fields")?; let [line] = serde_json::from_str(raw_fields).context("invalid fields")?;
ResultFields::BuildLogLine(line) ResultFields::BuildLogLine(line)
} }
102 => todo!("UntrustedPath({raw_fields})"), 102 => {
103 => todo!("CorruptedPath({raw_fields})"), let [path] = serde_json::from_str(raw_fields).context("invalid fields")?;
ResultFields::UntrustedPath(path)
}
103 => {
let [path] = serde_json::from_str(raw_fields).context("invalid fields")?;
ResultFields::CorruptedPath(path)
}
104 => { 104 => {
let [phase] = serde_json::from_str(raw_fields).context("invalid fields")?; let [phase] = serde_json::from_str(raw_fields).context("invalid fields")?;
ResultFields::SetPhase(phase) ResultFields::SetPhase(phase)
@@ -154,7 +173,15 @@ impl<'a> TryFrom<RawAction<'a>> for Action<'a> {
let (action, expected) = serde_json::from_str(raw_fields).unwrap(); let (action, expected) = serde_json::from_str(raw_fields).unwrap();
ResultFields::SetExpected { action, expected } ResultFields::SetExpected { action, expected }
} }
107 => todo!("PostBuildLogLine({raw_fields})"), 107 => {
let [line] = serde_json::from_str(raw_fields).context("invalid fields")?;
ResultFields::PostBuildLogLine(line)
}
108 => {
let [status] =
serde_json::from_str(raw_fields).context("invalid fields")?;
ResultFields::FetchStatus(status)
}
v => eyre::bail!("Unknown result type `{v}`"), v => eyre::bail!("Unknown result type `{v}`"),
}; };

View File

@@ -6,13 +6,36 @@ use crate::action::StartFields;
pub mod action; pub mod action;
pub mod action_raw; pub mod action_raw;
enum BuildEnumState {
Query,
Downloading,
}
struct BuildState {
path: Option<String>,
progress_bar: ProgressBar,
state: BuildEnumState,
}
struct State {
progress: MultiProgress,
bars: HashMap<u64, BuildState>,
}
fn main() -> Result<(), color_eyre::Report> { fn main() -> Result<(), color_eyre::Report> {
color_eyre::install().unwrap(); color_eyre::install().unwrap();
let lines = std::fs::read_to_string("log2")?; let lines = std::fs::read_to_string("log2")?;
// let lines = lines.lines().take(1000).collect::<Vec<_>>().join("\n"); // let lines = lines.lines().take(1000).collect::<Vec<_>>().join("\n");
let progress = MultiProgress::new(); let mut state = State {
let lines_pb = progress.add(ProgressBar::new(lines.lines().count() as u64)); progress: MultiProgress::new(),
bars: HashMap::new(),
};
// let progress = MultiProgress::new();
let lines_pb = state
.progress
.add(ProgressBar::new(lines.lines().count() as u64));
// progress.println("Parsing build.log...")?; // progress.println("Parsing build.log...")?;
// let pb1 = progress.add(ProgressBar::new(lines.lines().count() as u64)); // let pb1 = progress.add(ProgressBar::new(lines.lines().count() as u64));
// pb1.set_style( // pb1.set_style(
@@ -30,16 +53,18 @@ fn main() -> Result<(), color_eyre::Report> {
// pb2.set_message("Processing line2342s\n|\n|\n>"); // pb2.set_message("Processing line2342s\n|\n|\n>");
// sleep(Duration::from_secs(1)); // sleep(Duration::from_secs(1));
let mut map = HashMap::new(); // let mut map = HashMap::new();
for line in lines.lines() { for line in lines.lines() {
lines_pb.inc(1); lines_pb.inc(1);
let line = line.strip_prefix("@nix ").unwrap_or(line); let line = line.strip_prefix("@nix ").unwrap_or(line);
// sleep(Duration::from_millis(5)); sleep(Duration::from_millis(50));
let action = action::Action::parse(line)?; let action = action::Action::parse(line)?;
match action { match action {
action::Action::Msg { level, msg } => { action::Action::Msg { level, msg } => {
progress.println(format!("MSG (level {level}): {msg}"))?; state
.progress
.println(format!("MSG (level {level}): {msg}"))?;
} }
action::Action::Start { action::Action::Start {
start_type, start_type,
@@ -48,60 +73,71 @@ fn main() -> Result<(), color_eyre::Report> {
parent, parent,
text, text,
} => match start_type { } => match start_type {
StartFields::CopyPath { StartFields::QueryPathInfo { path, source } => {
path, state.bars.insert(
origin, *id,
destination, BuildState {
} => { path: Some(path.to_string()),
progress.println(format!( progress_bar: state.progress.add(ProgressBar::new(100)),
"START (id: {}, level: {}, parent: {}): CopyPath - {} (from: {}, to: {})", state: BuildEnumState::Query,
id, level, parent, text, origin, destination },
))?; );
} }
StartFields::FileTransfer { target } => { StartFields::FileTransfer { target } => {
let bar = progress.add(ProgressBar::new(100)); state.progress.println(format!(
bar.set_style( "START FileTransfer (id: {}, parent: {}): target={}",
id, parent, target
))?;
if let Some(bar) = state.bars.get_mut(&parent) {
bar.state = BuildEnumState::Downloading;
bar.progress_bar.set_style(
ProgressStyle::default_bar() ProgressStyle::default_bar()
.template("{msg} [{bar:40.cyan/blue}] {pos:>3}%") .template("{msg} [{bar:40.cyan/blue}] {pos:>3}%")
.unwrap(), .unwrap(),
); );
bar.set_message(format!("meow {id} ")); bar.progress_bar.set_message(format!(
map.insert(id, bar); "Downloading {}",
bar.path.as_deref().unwrap_or("unknown")
));
}
// let bar = progress.add(ProgressBar::new(100));
// bar // bar.set_message(format!("meow {id} "));
// map.insert(id, bar);
} }
_ => {} _ => {}
}, },
action::Action::Stop { id } => { action::Action::Stop { id } => {
if let Some(bar) = map.get(&id) { // if let Some(bar) = map.get(&id) {
bar.finish(); // bar.finish();
// bar.finish_with_message(format!("Transfer stopped (id: {})", id)); // // bar.finish_with_message(format!("Transfer stopped (id: {})", id));
progress.remove(bar); // progress.remove(bar);
map.remove(&id); // map.remove(&id);
} // }
// progress.println(format!("STOP (id: {})", id))?; // progress.println(format!("STOP (id: {})", id))?;
} }
action::Action::Result { id, fields } => { action::Action::Result { id, fields } => {
// progress.println(format!("RESULT (id: {}): {:?}", id, fields))?; // progress.println(format!("RESULT (id: {}): {:?}", id, fields))?;
match fields { match fields {
action::ResultFields::Progress { // action::ResultFields::Progress {
done, // done,
expected, // expected,
running, // running,
failed, // failed,
} => { // } => {
sleep(Duration::from_millis(1)); // // sleep(Duration::from_millis(1));
if let Some(bar) = map.get(&id) { // // if let Some(bar) = map.get(&id) {
let percentage = if expected == 0 { // // let percentage = if expected == 0 {
0 // // 0
} else { // // } else {
(done * 100 / expected) as u64 // // (done * 100 / expected) as u64
}; // // };
bar.set_position(percentage); // // bar.set_position(percentage);
// if done >= expected { // // if done >= expected {
// bar.finish_with_message(format!("Completed transfer (id: {})", id)); // // bar.finish_with_message(format!("Completed transfer (id: {})", id));
// map.remove(&id); // // map.remove(&id);
// // }
// }
// } // }
}
}
_ => {} _ => {}
} }
} }