Parse to a meaningful format in the nix output stream before hitting the running build.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
/work
|
/work
|
||||||
|
/example_logs
|
||||||
|
|||||||
@@ -28,7 +28,3 @@ url = { version = "2.5.8", default-features = false, features = ["std"] }
|
|||||||
inherits = "release"
|
inherits = "release"
|
||||||
lto = true
|
lto = true
|
||||||
strip = "symbols"
|
strip = "symbols"
|
||||||
|
|
||||||
[profile.dev.package.sqlx-macros]
|
|
||||||
# Faster compile-time verified macros
|
|
||||||
opt-level = 3
|
|
||||||
|
|||||||
@@ -5,13 +5,13 @@
|
|||||||
repo = "https://code.fizz.buzz/talexander/machine_setup.git"
|
repo = "https://code.fizz.buzz/talexander/machine_setup.git"
|
||||||
branch = "nix"
|
branch = "nix"
|
||||||
path = "nix/configuration"
|
path = "nix/configuration"
|
||||||
attr = "odo"
|
attr = "nixosConfigurations.odo.config.system.build.toplevel"
|
||||||
|
|
||||||
[[targets]]
|
[[targets]]
|
||||||
name = "odo_update"
|
name = "odo_update"
|
||||||
repo = "https://code.fizz.buzz/talexander/machine_setup.git"
|
repo = "https://code.fizz.buzz/talexander/machine_setup.git"
|
||||||
branch = "nix"
|
branch = "nix"
|
||||||
path = "nix/configuration"
|
path = "nix/configuration"
|
||||||
attr = "odo"
|
attr = "nixosConfigurations.odo.config.system.build.toplevel"
|
||||||
update = true
|
update = true
|
||||||
update_branch = "nix_update"
|
update_branch = "nix_update"
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ impl DbHandle {
|
|||||||
options.connect(&full_url).await?
|
options.connect(&full_url).await?
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
warn!("No sqlite_path set in config. Using an in-memory database.");
|
warn!("Using an in-memory database.");
|
||||||
// We force it to a single connection that never dies or else the data and schema in the in-memory DB is lost.
|
// We force it to a single connection that never dies or else the data and schema in the in-memory DB is lost.
|
||||||
options
|
options
|
||||||
.min_connections(1)
|
.min_connections(1)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::fmt::Display;
|
||||||
|
use std::num::TryFromIntError;
|
||||||
use std::str::Utf8Error;
|
use std::str::Utf8Error;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
|
|
||||||
@@ -16,6 +18,13 @@ pub(crate) enum CustomError {
|
|||||||
UrlParseError(#[allow(dead_code)] url::ParseError),
|
UrlParseError(#[allow(dead_code)] url::ParseError),
|
||||||
Migrate(#[allow(dead_code)] sqlx::migrate::MigrateError),
|
Migrate(#[allow(dead_code)] sqlx::migrate::MigrateError),
|
||||||
Sql(#[allow(dead_code)] sqlx::Error),
|
Sql(#[allow(dead_code)] sqlx::Error),
|
||||||
|
TryFromIntError(#[allow(dead_code)] TryFromIntError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for CustomError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{:?}", self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::Error> for CustomError {
|
impl From<std::io::Error> for CustomError {
|
||||||
@@ -95,3 +104,9 @@ impl From<sqlx::Error> for CustomError {
|
|||||||
CustomError::Sql(value)
|
CustomError::Sql(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<TryFromIntError> for CustomError {
|
||||||
|
fn from(value: TryFromIntError) -> Self {
|
||||||
|
CustomError::TryFromIntError(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ where
|
|||||||
reference
|
reference
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut command = Command::new("nixos-rebuild");
|
let mut command = Command::new("nix");
|
||||||
command.current_dir(build_path);
|
command.current_dir(build_path);
|
||||||
command.stdout(Stdio::piped());
|
command.stdout(Stdio::piped());
|
||||||
command.stderr(Stdio::piped());
|
command.stderr(Stdio::piped());
|
||||||
@@ -41,7 +41,6 @@ where
|
|||||||
command.args([
|
command.args([
|
||||||
"build",
|
"build",
|
||||||
"--show-trace",
|
"--show-trace",
|
||||||
"--sudo",
|
|
||||||
"--max-jobs",
|
"--max-jobs",
|
||||||
"1",
|
"1",
|
||||||
"--log-format",
|
"--log-format",
|
||||||
@@ -49,7 +48,6 @@ where
|
|||||||
"-vvvvvvvvvvv",
|
"-vvvvvvvvvvv",
|
||||||
"--keep-going",
|
"--keep-going",
|
||||||
]);
|
]);
|
||||||
command.arg("--flake");
|
|
||||||
command.arg(reference);
|
command.arg(reference);
|
||||||
command.kill_on_drop(true);
|
command.kill_on_drop(true);
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,83 @@
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
use tracing::warn;
|
||||||
|
|
||||||
use super::output_stream::OutputLineStream;
|
use super::output_stream::OutputLineStream;
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
|
||||||
|
macro_rules! warn_if_len {
|
||||||
|
($name:expr, $json:ident, $collection:expr, $($comparison:tt)*) => {{
|
||||||
|
match $collection {
|
||||||
|
Some(f) if f.len() $($comparison)* => {
|
||||||
|
warn!(
|
||||||
|
"Found {}.len() {} in {}: {}", stringify!($collection), stringify!($($comparison)*), stringify!($name), $json
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Some(_) => {},
|
||||||
|
_ => {
|
||||||
|
warn!(
|
||||||
|
"Found {} None in {}: {}", stringify!($collection), stringify!($name), $json
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! warn_if_optional_len {
|
||||||
|
($name:expr, $json:ident, $collection:expr, $($comparison:tt)*) => {{
|
||||||
|
match $collection {
|
||||||
|
Some(f) if f.len() $($comparison)* => {
|
||||||
|
warn!(
|
||||||
|
"Found {}.len() {} in {}: {}", stringify!($collection), stringify!($($comparison)*), stringify!($name), $json
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Some(_) => {},
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! warn_if_non_null {
|
||||||
|
($name:expr, $json:ident, $collection:expr) => {{
|
||||||
|
match $collection {
|
||||||
|
Some(_) => {
|
||||||
|
warn!(
|
||||||
|
"Found non-null {} in {}: {}",
|
||||||
|
stringify!($collection),
|
||||||
|
stringify!($name),
|
||||||
|
$json
|
||||||
|
);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
};
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! warn_if_non_empty_string {
|
||||||
|
($name:expr, $json:ident, $str:expr) => {{
|
||||||
|
if $str.len() != 0 {
|
||||||
|
warn!(
|
||||||
|
"Found non-empty string {} in {}: {}",
|
||||||
|
stringify!($str),
|
||||||
|
stringify!($name),
|
||||||
|
$json
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! warn_if {
|
||||||
|
($name:expr, $json:ident, $val:expr, $($comparison:tt)*) => {{
|
||||||
|
if $val $($comparison)* {
|
||||||
|
warn!(
|
||||||
|
"Found {} {} in {}: {}", stringify!($val), stringify!($($comparison)*), stringify!($name), $json
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct NixOutputStream<S> {
|
pub(crate) struct NixOutputStream<S> {
|
||||||
inner: S,
|
inner: S,
|
||||||
@@ -30,7 +103,8 @@ impl<S: OutputLineStream> NixOutputStream<S> {
|
|||||||
let payload = &line[4..];
|
let payload = &line[4..];
|
||||||
|
|
||||||
if let Ok(action) = serde_json::from_str(&payload) {
|
if let Ok(action) = serde_json::from_str(&payload) {
|
||||||
return Ok(Some(NixMessage::Action(action)));
|
let parsed_action = parse_action(action)?;
|
||||||
|
return Ok(Some(NixMessage::Action(parsed_action)));
|
||||||
}
|
}
|
||||||
if let Ok(parsed) = serde_json::from_str(&payload) {
|
if let Ok(parsed) = serde_json::from_str(&payload) {
|
||||||
return Ok(Some(NixMessage::Generic(parsed, line)));
|
return Ok(Some(NixMessage::Generic(parsed, line)));
|
||||||
@@ -39,6 +113,297 @@ impl<S: OutputLineStream> NixOutputStream<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_action(raw: RawNixAction) -> Result<NixAction> {
|
||||||
|
let original_json = serde_json::to_string(&raw)?;
|
||||||
|
match raw {
|
||||||
|
RawNixAction::Msg {
|
||||||
|
level,
|
||||||
|
msg,
|
||||||
|
raw_msg,
|
||||||
|
file,
|
||||||
|
line,
|
||||||
|
column,
|
||||||
|
trace,
|
||||||
|
} => Ok(NixAction::Msg(MsgMessage {
|
||||||
|
level,
|
||||||
|
msg,
|
||||||
|
raw_msg,
|
||||||
|
file,
|
||||||
|
line,
|
||||||
|
column,
|
||||||
|
trace,
|
||||||
|
})),
|
||||||
|
RawNixAction::Start {
|
||||||
|
id,
|
||||||
|
fields,
|
||||||
|
level,
|
||||||
|
parent,
|
||||||
|
text,
|
||||||
|
r#type,
|
||||||
|
} => {
|
||||||
|
match r#type {
|
||||||
|
ActivityType::Unknown => {
|
||||||
|
warn_if_non_null!(ActivityStartUnknown, original_json, &fields);
|
||||||
|
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::Unknown(
|
||||||
|
ActivityStartUnknown {
|
||||||
|
id,
|
||||||
|
parent,
|
||||||
|
level,
|
||||||
|
text,
|
||||||
|
},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::CopyPath => {
|
||||||
|
warn_if_len!(ActivityStartCopyPath, original_json, &fields, != 3);
|
||||||
|
warn_if!(ActivityStartCopyPath, original_json, level, != 3);
|
||||||
|
|
||||||
|
let missing_path = string_field(&fields, 0).to_owned();
|
||||||
|
let source = string_field(&fields, 1).to_owned();
|
||||||
|
let destination = string_field(&fields, 2).to_owned();
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::CopyPath(
|
||||||
|
ActivityStartCopyPath {
|
||||||
|
id,
|
||||||
|
parent,
|
||||||
|
text,
|
||||||
|
missing_path,
|
||||||
|
source,
|
||||||
|
destination,
|
||||||
|
},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::FileTransfer => {
|
||||||
|
warn_if_len!(ActivityStartFileTransfer, original_json, &fields, != 1);
|
||||||
|
warn_if!(ActivityStartFileTransfer, original_json, level, != 4);
|
||||||
|
let url = string_field(&fields, 0).to_owned();
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::FileTransfer(
|
||||||
|
ActivityStartFileTransfer {
|
||||||
|
id,
|
||||||
|
parent,
|
||||||
|
text,
|
||||||
|
url,
|
||||||
|
},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::Realize => {
|
||||||
|
warn_if_non_empty_string!(ActivityStartRealize, original_json, text);
|
||||||
|
warn_if_non_null!(ActivityStartRealize, original_json, &fields);
|
||||||
|
warn_if!(ActivityStartRealize, original_json, level, != 0);
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::Realize(
|
||||||
|
ActivityStartRealize { id, parent },
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::CopyPaths => {
|
||||||
|
warn_if_non_null!(ActivityStartCopyPaths, original_json, &fields);
|
||||||
|
// println!("{}", original_json);
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::CopyPaths(
|
||||||
|
ActivityStartCopyPaths {
|
||||||
|
id,
|
||||||
|
parent,
|
||||||
|
level,
|
||||||
|
text,
|
||||||
|
},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::Builds => {
|
||||||
|
// println!("{}", original_json);
|
||||||
|
warn_if_non_empty_string!(ActivityStartBuilds, original_json, text);
|
||||||
|
warn_if_non_null!(ActivityStartBuilds, original_json, &fields);
|
||||||
|
warn_if!(ActivityStartBuilds, original_json, level, != 0);
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::Builds(
|
||||||
|
ActivityStartBuilds { id, parent },
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::Build => {
|
||||||
|
// println!("{}", original_json);
|
||||||
|
let drv_path = string_field(&fields, 0).to_owned();
|
||||||
|
let machine_name = string_field(&fields, 1).to_owned();
|
||||||
|
let unknown_constant_1 = number_field(&fields, 2).to_owned();
|
||||||
|
let unknown_constant_2 = number_field(&fields, 3).to_owned();
|
||||||
|
warn_if!(ActivityStartBuild, original_json, unknown_constant_1, != 1);
|
||||||
|
warn_if!(ActivityStartBuild, original_json, unknown_constant_2, != 1);
|
||||||
|
warn_if!(ActivityStartBuild, original_json, level, != 3);
|
||||||
|
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::Build(
|
||||||
|
ActivityStartBuild {
|
||||||
|
id,
|
||||||
|
parent,
|
||||||
|
text,
|
||||||
|
drv_path,
|
||||||
|
machine_name,
|
||||||
|
},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::OptimizeStore => {
|
||||||
|
// println!("{}", original_json);
|
||||||
|
warn_if_non_empty_string!(ActivityStartOptimizeStore, original_json, text);
|
||||||
|
warn_if_non_null!(ActivityStartOptimizeStore, original_json, &fields);
|
||||||
|
warn_if!(ActivityStartOptimizeStore, original_json, level, != 0);
|
||||||
|
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::OptimizeStore(
|
||||||
|
ActivityStartOptimizeStore { id, parent },
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::VerifyPaths => {
|
||||||
|
// println!("{}", original_json);
|
||||||
|
warn_if_non_empty_string!(ActivityStartVerifyPaths, original_json, text);
|
||||||
|
warn_if_non_null!(ActivityStartVerifyPaths, original_json, &fields);
|
||||||
|
warn_if!(ActivityStartVerifyPaths, original_json, level, != 0);
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::VerifyPaths(
|
||||||
|
ActivityStartVerifyPaths { id, parent },
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::Substitute => {
|
||||||
|
warn_if_non_empty_string!(ActivityStartSubstitute, original_json, text);
|
||||||
|
warn_if_non_null!(ActivityStartSubstitute, original_json, &fields);
|
||||||
|
warn_if!(ActivityStartSubstitute, original_json, level, != 0);
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::Substitute(
|
||||||
|
ActivityStartSubstitute { id, parent },
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::QueryPathInfo => {
|
||||||
|
warn_if_non_empty_string!(ActivityStartQueryPathInfo, original_json, text);
|
||||||
|
warn_if_non_null!(ActivityStartQueryPathInfo, original_json, &fields);
|
||||||
|
warn_if!(ActivityStartQueryPathInfo, original_json, level, != 0);
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::QueryPathInfo(
|
||||||
|
ActivityStartQueryPathInfo { id, parent },
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::PostBuildHook => {
|
||||||
|
warn_if_non_empty_string!(ActivityStartPostBuildHook, original_json, text);
|
||||||
|
warn_if_non_null!(ActivityStartPostBuildHook, original_json, &fields);
|
||||||
|
warn_if!(ActivityStartPostBuildHook, original_json, level, != 0);
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::PostBuildHook(
|
||||||
|
ActivityStartPostBuildHook { id, parent },
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::BuildWaiting => {
|
||||||
|
warn_if_optional_len!(ActivityStartBuildWaiting, original_json, &fields, != 2);
|
||||||
|
warn_if!(ActivityStartBuildWaiting, original_json, parent, != 0);
|
||||||
|
let drv_path = optional_string_field(&fields, 0)
|
||||||
|
.to_owned()
|
||||||
|
.map(String::to_owned);
|
||||||
|
let path_resolved = optional_string_field(&fields, 1)
|
||||||
|
.to_owned()
|
||||||
|
.map(String::to_owned);
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::BuildWaiting(
|
||||||
|
ActivityStartBuildWaiting {
|
||||||
|
id,
|
||||||
|
level,
|
||||||
|
text,
|
||||||
|
drv_path,
|
||||||
|
path_resolved,
|
||||||
|
},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ActivityType::FetchTree => {
|
||||||
|
warn_if_non_empty_string!(ActivityStartFetchTree, original_json, text);
|
||||||
|
warn_if_non_null!(ActivityStartFetchTree, original_json, &fields);
|
||||||
|
warn_if!(ActivityStartFetchTree, original_json, level, != 0);
|
||||||
|
Ok(NixAction::Start(ActivityStartMessage::FetchTree(
|
||||||
|
ActivityStartFetchTree { id, parent },
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RawNixAction::Stop { id } => Ok(NixAction::Stop(StopMessage { id })),
|
||||||
|
RawNixAction::Result { id, fields, r#type } => {
|
||||||
|
// Wrap fields in an option to be able able to use the same utility functions we use for the fields from RawNixAction::Start
|
||||||
|
let fields = Some(fields);
|
||||||
|
match r#type {
|
||||||
|
ResultType::FileLinked => {
|
||||||
|
warn_if_len!(ActivityResultFileLinked, original_json, &fields, != 0);
|
||||||
|
warn_if!(ActivityResultFileLinked, original_json, id, != 0);
|
||||||
|
|
||||||
|
println!("{}", original_json);
|
||||||
|
Ok(NixAction::Result(ActivityResultMessage::FileLinked(
|
||||||
|
ActivityResultFileLinked {},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ResultType::BuildLogLine => {
|
||||||
|
warn_if_len!(ActivityResultBuildLogLine, original_json, &fields, != 1);
|
||||||
|
let log_line = string_field(&fields, 0).to_owned();
|
||||||
|
|
||||||
|
Ok(NixAction::Result(ActivityResultMessage::BuildLogLine(
|
||||||
|
ActivityResultBuildLogLine { id, log_line },
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ResultType::UntrustedPath => {
|
||||||
|
warn_if_len!(ActivityResultUntrustedPath, original_json, &fields, != 0);
|
||||||
|
warn_if!(ActivityResultUntrustedPath, original_json, id, != 0);
|
||||||
|
|
||||||
|
Ok(NixAction::Result(ActivityResultMessage::UntrustedPath(
|
||||||
|
ActivityResultUntrustedPath {},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ResultType::CorruptedPath => {
|
||||||
|
warn_if_len!(ActivityResultCorruptedPath, original_json, &fields, != 0);
|
||||||
|
warn_if!(ActivityResultCorruptedPath, original_json, id, != 0);
|
||||||
|
|
||||||
|
Ok(NixAction::Result(ActivityResultMessage::CorruptedPath(
|
||||||
|
ActivityResultCorruptedPath {},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ResultType::SetPhase => {
|
||||||
|
warn_if_len!(ActivityResultSetPhase, original_json, &fields, != 1);
|
||||||
|
let phase = string_field(&fields, 0).to_owned();
|
||||||
|
|
||||||
|
Ok(NixAction::Result(ActivityResultMessage::SetPhase(
|
||||||
|
ActivityResultSetPhase { id, phase },
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ResultType::Progress => {
|
||||||
|
warn_if_len!(ActivityResultProgress, original_json, &fields, != 4);
|
||||||
|
let done = number_field(&fields, 0).to_owned();
|
||||||
|
let expected = number_field(&fields, 1).to_owned();
|
||||||
|
let running = number_field(&fields, 2).to_owned().try_into()?;
|
||||||
|
let failed = number_field(&fields, 3).to_owned().try_into()?;
|
||||||
|
|
||||||
|
Ok(NixAction::Result(ActivityResultMessage::Progress(
|
||||||
|
ActivityResultProgress {
|
||||||
|
id,
|
||||||
|
done,
|
||||||
|
expected,
|
||||||
|
running,
|
||||||
|
failed,
|
||||||
|
},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ResultType::SetExpected => {
|
||||||
|
warn_if_len!(ActivityResultSetExpected, original_json, &fields, != 2);
|
||||||
|
// TODO: Maybe map activity_type to an enum?
|
||||||
|
let activity_type = number_field(&fields, 0).to_owned().try_into()?;
|
||||||
|
let expected = number_field(&fields, 1).to_owned();
|
||||||
|
|
||||||
|
Ok(NixAction::Result(ActivityResultMessage::SetExpected(
|
||||||
|
ActivityResultSetExpected {
|
||||||
|
id,
|
||||||
|
activity_type,
|
||||||
|
expected,
|
||||||
|
},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ResultType::PostBuildLogLine => {
|
||||||
|
warn_if_len!(ActivityResultPostBuildLogLine, original_json, &fields, != 0);
|
||||||
|
warn_if!(ActivityResultPostBuildLogLine, original_json, id, != 0);
|
||||||
|
|
||||||
|
Ok(NixAction::Result(ActivityResultMessage::PostBuildLogLine(
|
||||||
|
ActivityResultPostBuildLogLine {},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
ResultType::FetchStatus => {
|
||||||
|
warn_if_len!(ActivityResultFetchStatus, original_json, &fields, != 0);
|
||||||
|
warn_if!(ActivityResultFetchStatus, original_json, id, != 0);
|
||||||
|
|
||||||
|
Ok(NixAction::Result(ActivityResultMessage::FetchStatus(
|
||||||
|
ActivityResultFetchStatus {},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) enum NixMessage {
|
pub(crate) enum NixMessage {
|
||||||
ParseFailure(String),
|
ParseFailure(String),
|
||||||
@@ -46,9 +411,107 @@ pub(crate) enum NixMessage {
|
|||||||
Action(NixAction),
|
Action(NixAction),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[repr(u8)]
|
||||||
|
#[serde(try_from = "u64", into = "u8")]
|
||||||
|
pub(crate) enum ActivityType {
|
||||||
|
Unknown = 0,
|
||||||
|
CopyPath = 100,
|
||||||
|
FileTransfer = 101,
|
||||||
|
Realize = 102,
|
||||||
|
CopyPaths = 103,
|
||||||
|
Builds = 104,
|
||||||
|
Build = 105,
|
||||||
|
OptimizeStore = 106,
|
||||||
|
VerifyPaths = 107,
|
||||||
|
Substitute = 108,
|
||||||
|
QueryPathInfo = 109,
|
||||||
|
PostBuildHook = 110,
|
||||||
|
BuildWaiting = 111,
|
||||||
|
FetchTree = 112,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<u64> for ActivityType {
|
||||||
|
type Error = CustomError;
|
||||||
|
|
||||||
|
fn try_from(value: u64) -> std::result::Result<Self, Self::Error> {
|
||||||
|
Ok(match value {
|
||||||
|
0 => ActivityType::Unknown,
|
||||||
|
100 => ActivityType::CopyPath,
|
||||||
|
101 => ActivityType::FileTransfer,
|
||||||
|
102 => ActivityType::Realize,
|
||||||
|
103 => ActivityType::CopyPaths,
|
||||||
|
104 => ActivityType::Builds,
|
||||||
|
105 => ActivityType::Build,
|
||||||
|
106 => ActivityType::OptimizeStore,
|
||||||
|
107 => ActivityType::VerifyPaths,
|
||||||
|
108 => ActivityType::Substitute,
|
||||||
|
109 => ActivityType::QueryPathInfo,
|
||||||
|
110 => ActivityType::PostBuildHook,
|
||||||
|
111 => ActivityType::BuildWaiting,
|
||||||
|
112 => ActivityType::FetchTree,
|
||||||
|
_ => {
|
||||||
|
return Err(CustomError::String(format!(
|
||||||
|
"Unexpected ActivityType: {value}"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<u8> for ActivityType {
|
||||||
|
fn into(self) -> u8 {
|
||||||
|
self as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[repr(u8)]
|
||||||
|
#[serde(try_from = "u64", into = "u8")]
|
||||||
|
pub(crate) enum ResultType {
|
||||||
|
FileLinked = 100,
|
||||||
|
BuildLogLine = 101,
|
||||||
|
UntrustedPath = 102,
|
||||||
|
CorruptedPath = 103,
|
||||||
|
SetPhase = 104,
|
||||||
|
Progress = 105,
|
||||||
|
SetExpected = 106,
|
||||||
|
PostBuildLogLine = 107,
|
||||||
|
FetchStatus = 108,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<u64> for ResultType {
|
||||||
|
type Error = CustomError;
|
||||||
|
|
||||||
|
fn try_from(value: u64) -> std::result::Result<Self, Self::Error> {
|
||||||
|
Ok(match value {
|
||||||
|
100 => ResultType::FileLinked,
|
||||||
|
101 => ResultType::BuildLogLine,
|
||||||
|
102 => ResultType::UntrustedPath,
|
||||||
|
103 => ResultType::CorruptedPath,
|
||||||
|
104 => ResultType::SetPhase,
|
||||||
|
105 => ResultType::Progress,
|
||||||
|
106 => ResultType::SetExpected,
|
||||||
|
107 => ResultType::PostBuildLogLine,
|
||||||
|
108 => ResultType::FetchStatus,
|
||||||
|
_ => {
|
||||||
|
return Err(CustomError::String(format!(
|
||||||
|
"Unexpected ResultType: {value}"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<u8> for ResultType {
|
||||||
|
fn into(self) -> u8 {
|
||||||
|
self as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
#[serde(tag = "action", rename_all = "lowercase", deny_unknown_fields)]
|
#[serde(tag = "action", rename_all = "lowercase", deny_unknown_fields)]
|
||||||
pub(crate) enum NixAction {
|
pub(crate) enum RawNixAction {
|
||||||
Msg {
|
Msg {
|
||||||
level: u8,
|
level: u8,
|
||||||
msg: String,
|
msg: String,
|
||||||
@@ -64,6 +527,9 @@ pub(crate) enum NixAction {
|
|||||||
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
column: Option<u64>,
|
column: Option<u64>,
|
||||||
|
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
trace: Option<Vec<TraceEntry>>,
|
||||||
},
|
},
|
||||||
Start {
|
Start {
|
||||||
id: u64,
|
id: u64,
|
||||||
@@ -74,7 +540,7 @@ pub(crate) enum NixAction {
|
|||||||
level: u8,
|
level: u8,
|
||||||
parent: u64,
|
parent: u64,
|
||||||
text: String,
|
text: String,
|
||||||
r#type: u8,
|
r#type: ActivityType,
|
||||||
},
|
},
|
||||||
Stop {
|
Stop {
|
||||||
id: u64,
|
id: u64,
|
||||||
@@ -82,7 +548,7 @@ pub(crate) enum NixAction {
|
|||||||
Result {
|
Result {
|
||||||
id: u64,
|
id: u64,
|
||||||
fields: Vec<Field>,
|
fields: Vec<Field>,
|
||||||
r#type: u8,
|
r#type: ResultType,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,3 +558,331 @@ pub(crate) enum Field {
|
|||||||
Number(u64),
|
Number(u64),
|
||||||
Text(String),
|
Text(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub(crate) struct TraceEntry {
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
raw_msg: Option<String>,
|
||||||
|
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
file: Option<String>,
|
||||||
|
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
line: Option<u64>,
|
||||||
|
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
column: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub(crate) enum NixAction {
|
||||||
|
Msg(MsgMessage),
|
||||||
|
Start(ActivityStartMessage),
|
||||||
|
Stop(StopMessage),
|
||||||
|
Result(ActivityResultMessage),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct MsgMessage {
|
||||||
|
level: u8,
|
||||||
|
msg: String,
|
||||||
|
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
raw_msg: Option<String>,
|
||||||
|
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
file: Option<String>,
|
||||||
|
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
line: Option<u64>,
|
||||||
|
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
column: Option<u64>,
|
||||||
|
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
trace: Option<Vec<TraceEntry>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct StopMessage {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) enum ActivityStartMessage {
|
||||||
|
Unknown(ActivityStartUnknown),
|
||||||
|
CopyPath(ActivityStartCopyPath),
|
||||||
|
FileTransfer(ActivityStartFileTransfer),
|
||||||
|
Realize(ActivityStartRealize),
|
||||||
|
CopyPaths(ActivityStartCopyPaths),
|
||||||
|
Builds(ActivityStartBuilds),
|
||||||
|
Build(ActivityStartBuild),
|
||||||
|
OptimizeStore(ActivityStartOptimizeStore),
|
||||||
|
VerifyPaths(ActivityStartVerifyPaths),
|
||||||
|
Substitute(ActivityStartSubstitute),
|
||||||
|
QueryPathInfo(ActivityStartQueryPathInfo),
|
||||||
|
PostBuildHook(ActivityStartPostBuildHook),
|
||||||
|
BuildWaiting(ActivityStartBuildWaiting),
|
||||||
|
FetchTree(ActivityStartFetchTree),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActivityStartMessage {
|
||||||
|
fn get_type(&self) -> ActivityType {
|
||||||
|
match self {
|
||||||
|
ActivityStartMessage::Unknown(_) => ActivityType::Unknown,
|
||||||
|
ActivityStartMessage::CopyPath(_) => ActivityType::CopyPath,
|
||||||
|
ActivityStartMessage::FileTransfer(_) => ActivityType::FileTransfer,
|
||||||
|
ActivityStartMessage::Realize(_) => ActivityType::Realize,
|
||||||
|
ActivityStartMessage::CopyPaths(_) => ActivityType::CopyPaths,
|
||||||
|
ActivityStartMessage::Builds(_) => ActivityType::Builds,
|
||||||
|
ActivityStartMessage::Build(_) => ActivityType::Build,
|
||||||
|
ActivityStartMessage::OptimizeStore(_) => ActivityType::OptimizeStore,
|
||||||
|
ActivityStartMessage::VerifyPaths(_) => ActivityType::VerifyPaths,
|
||||||
|
ActivityStartMessage::Substitute(_) => ActivityType::Substitute,
|
||||||
|
ActivityStartMessage::QueryPathInfo(_) => ActivityType::QueryPathInfo,
|
||||||
|
ActivityStartMessage::PostBuildHook(_) => ActivityType::PostBuildHook,
|
||||||
|
ActivityStartMessage::BuildWaiting(_) => ActivityType::BuildWaiting,
|
||||||
|
ActivityStartMessage::FetchTree(_) => ActivityType::FetchTree,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_id(&self) -> u64 {
|
||||||
|
match self {
|
||||||
|
ActivityStartMessage::Unknown(activity_start_unknown) => activity_start_unknown.id,
|
||||||
|
ActivityStartMessage::CopyPath(activity_start_copy_path) => activity_start_copy_path.id,
|
||||||
|
ActivityStartMessage::FileTransfer(activity_start_file_transfer) => {
|
||||||
|
activity_start_file_transfer.id
|
||||||
|
}
|
||||||
|
ActivityStartMessage::Realize(activity_start_realize) => activity_start_realize.id,
|
||||||
|
ActivityStartMessage::CopyPaths(activity_start_copy_paths) => {
|
||||||
|
activity_start_copy_paths.id
|
||||||
|
}
|
||||||
|
ActivityStartMessage::Builds(activity_start_builds) => activity_start_builds.id,
|
||||||
|
ActivityStartMessage::Build(activity_start_build) => activity_start_build.id,
|
||||||
|
ActivityStartMessage::OptimizeStore(activity_start_optimize_store) => {
|
||||||
|
activity_start_optimize_store.id
|
||||||
|
}
|
||||||
|
ActivityStartMessage::VerifyPaths(activity_start_verify_paths) => {
|
||||||
|
activity_start_verify_paths.id
|
||||||
|
}
|
||||||
|
ActivityStartMessage::Substitute(activity_start_substitute) => {
|
||||||
|
activity_start_substitute.id
|
||||||
|
}
|
||||||
|
ActivityStartMessage::QueryPathInfo(activity_start_query_path_info) => {
|
||||||
|
activity_start_query_path_info.id
|
||||||
|
}
|
||||||
|
ActivityStartMessage::PostBuildHook(activity_start_post_build_hook) => {
|
||||||
|
activity_start_post_build_hook.id
|
||||||
|
}
|
||||||
|
ActivityStartMessage::BuildWaiting(activity_start_build_waiting) => {
|
||||||
|
activity_start_build_waiting.id
|
||||||
|
}
|
||||||
|
ActivityStartMessage::FetchTree(activity_start_fetch_tree) => {
|
||||||
|
activity_start_fetch_tree.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartUnknown {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
pub(crate) level: u8,
|
||||||
|
pub(crate) text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartCopyPath {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
pub(crate) text: String,
|
||||||
|
pub(crate) missing_path: String,
|
||||||
|
pub(crate) source: String,
|
||||||
|
pub(crate) destination: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartFileTransfer {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
pub(crate) text: String,
|
||||||
|
pub(crate) url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartRealize {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartCopyPaths {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
pub(crate) level: u8,
|
||||||
|
pub(crate) text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartBuilds {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartBuild {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
pub(crate) text: String,
|
||||||
|
pub(crate) drv_path: String,
|
||||||
|
pub(crate) machine_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartOptimizeStore {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartVerifyPaths {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartSubstitute {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartQueryPathInfo {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartPostBuildHook {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartBuildWaiting {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) level: u8,
|
||||||
|
pub(crate) text: String,
|
||||||
|
pub(crate) drv_path: Option<String>,
|
||||||
|
pub(crate) path_resolved: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityStartFetchTree {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) parent: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) enum ActivityResultMessage {
|
||||||
|
FileLinked(ActivityResultFileLinked),
|
||||||
|
BuildLogLine(ActivityResultBuildLogLine),
|
||||||
|
UntrustedPath(ActivityResultUntrustedPath),
|
||||||
|
CorruptedPath(ActivityResultCorruptedPath),
|
||||||
|
SetPhase(ActivityResultSetPhase),
|
||||||
|
Progress(ActivityResultProgress),
|
||||||
|
SetExpected(ActivityResultSetExpected),
|
||||||
|
PostBuildLogLine(ActivityResultPostBuildLogLine),
|
||||||
|
FetchStatus(ActivityResultFetchStatus),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActivityResultMessage {
|
||||||
|
fn get_type(&self) -> ResultType {
|
||||||
|
match self {
|
||||||
|
ActivityResultMessage::FileLinked(_) => ResultType::FileLinked,
|
||||||
|
ActivityResultMessage::BuildLogLine(_) => ResultType::BuildLogLine,
|
||||||
|
ActivityResultMessage::UntrustedPath(_) => ResultType::UntrustedPath,
|
||||||
|
ActivityResultMessage::CorruptedPath(_) => ResultType::CorruptedPath,
|
||||||
|
ActivityResultMessage::SetPhase(_) => ResultType::SetPhase,
|
||||||
|
ActivityResultMessage::Progress(_) => ResultType::Progress,
|
||||||
|
ActivityResultMessage::SetExpected(_) => ResultType::SetExpected,
|
||||||
|
ActivityResultMessage::PostBuildLogLine(_) => ResultType::PostBuildLogLine,
|
||||||
|
ActivityResultMessage::FetchStatus(_) => ResultType::FetchStatus,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityResultFileLinked {}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityResultBuildLogLine {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) log_line: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityResultUntrustedPath {}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityResultCorruptedPath {}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityResultSetPhase {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) phase: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityResultProgress {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) done: u64,
|
||||||
|
pub(crate) expected: u64,
|
||||||
|
pub(crate) running: u8,
|
||||||
|
pub(crate) failed: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityResultSetExpected {
|
||||||
|
pub(crate) id: u64,
|
||||||
|
pub(crate) activity_type: ActivityType,
|
||||||
|
pub(crate) expected: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityResultPostBuildLogLine {}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub(crate) struct ActivityResultFetchStatus {}
|
||||||
|
|
||||||
|
fn string_field(fields: &Option<Vec<Field>>, ind: usize) -> &String {
|
||||||
|
match fields {
|
||||||
|
Some(fields) => match &fields[ind] {
|
||||||
|
Field::Number(_n) => panic!("Expected field {ind} to be text, but it is a number."),
|
||||||
|
Field::Text(t) => t,
|
||||||
|
},
|
||||||
|
None => panic!("Expected fields but no fields present."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn optional_string_field(fields: &Option<Vec<Field>>, ind: usize) -> Option<&String> {
|
||||||
|
match fields {
|
||||||
|
Some(fields) => match &fields[ind] {
|
||||||
|
Field::Number(_n) => panic!("Expected field {ind} to be text, but it is a number."),
|
||||||
|
Field::Text(t) => Some(t),
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn number_field(fields: &Option<Vec<Field>>, ind: usize) -> &u64 {
|
||||||
|
match fields {
|
||||||
|
Some(fields) => match &fields[ind] {
|
||||||
|
Field::Number(n) => n,
|
||||||
|
Field::Text(t) => panic!("Expected field {ind} to be a number, but it is text."),
|
||||||
|
},
|
||||||
|
None => panic!("Expected fields but no fields present."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use sqlx::Row;
|
use sqlx::Row;
|
||||||
use tokio::process::Child;
|
use tokio::process::Child;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use tracing::warn;
|
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use crate::database::db_handle::DbHandle;
|
use crate::database::db_handle::DbHandle;
|
||||||
|
use crate::nix_util::nix_output_stream::ActivityStartMessage;
|
||||||
use crate::nix_util::nix_output_stream::NixAction;
|
use crate::nix_util::nix_output_stream::NixAction;
|
||||||
use crate::nix_util::nix_output_stream::NixOutputStream;
|
use crate::nix_util::nix_output_stream::NixOutputStream;
|
||||||
use crate::nix_util::output_stream::OutputStream;
|
use crate::nix_util::output_stream::OutputStream;
|
||||||
|
|
||||||
use super::nix_output_stream::Field;
|
use super::nix_output_stream::ActivityResultMessage;
|
||||||
use super::nix_output_stream::NixMessage;
|
use super::nix_output_stream::NixMessage;
|
||||||
|
|
||||||
const ACTIVITY_TYPE_: i32 = 10;
|
|
||||||
|
|
||||||
pub(crate) struct RunningBuild<'db> {
|
pub(crate) struct RunningBuild<'db> {
|
||||||
db_handle: &'db DbHandle,
|
db_handle: &'db DbHandle,
|
||||||
activity_tree: BTreeMap<u64, Activity>,
|
activity_tree: BTreeMap<u64, Activity>,
|
||||||
@@ -62,7 +61,7 @@ impl<'db> RunningBuild<'db> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let exit_status = exit_status_handle.await?;
|
let exit_status = exit_status_handle.await?;
|
||||||
println!("nixos-rebuild status was: {}", exit_status);
|
println!("nix build status was: {}", exit_status);
|
||||||
|
|
||||||
let update: u64 =
|
let update: u64 =
|
||||||
sqlx::query(r#"UPDATE build SET end_time=unixepoch('now'), status=? WHERE id=?"#)
|
sqlx::query(r#"UPDATE build SET end_time=unixepoch('now'), status=? WHERE id=?"#)
|
||||||
@@ -92,230 +91,136 @@ impl<'db> RunningBuild<'db> {
|
|||||||
}
|
}
|
||||||
NixMessage::Action(nix_action) => nix_action,
|
NixMessage::Action(nix_action) => nix_action,
|
||||||
};
|
};
|
||||||
match &message {
|
match message {
|
||||||
NixAction::Msg {
|
NixAction::Msg(msg_message) => {
|
||||||
level,
|
|
||||||
msg,
|
|
||||||
raw_msg,
|
|
||||||
file,
|
|
||||||
line,
|
|
||||||
column,
|
|
||||||
} => {
|
|
||||||
// For now we can ignore the messages.
|
// For now we can ignore the messages.
|
||||||
}
|
}
|
||||||
NixAction::Start {
|
NixAction::Start(activity_start_message) => {
|
||||||
id,
|
let id = activity_start_message.get_id();
|
||||||
fields,
|
let entry = self.activity_tree.entry(id);
|
||||||
level,
|
|
||||||
parent,
|
|
||||||
text,
|
|
||||||
r#type,
|
|
||||||
} => {
|
|
||||||
let entry = self.activity_tree.entry(*id);
|
|
||||||
let entry = match entry {
|
let entry = match entry {
|
||||||
std::collections::btree_map::Entry::Vacant(vacant_entry) => vacant_entry,
|
std::collections::btree_map::Entry::Vacant(vacant_entry) => vacant_entry,
|
||||||
std::collections::btree_map::Entry::Occupied(_occupied_entry) => {
|
std::collections::btree_map::Entry::Occupied(_occupied_entry) => {
|
||||||
panic!("Started an already started activity: {id}.")
|
panic!("Started an already started activity: {id}.")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match r#type {
|
match activity_start_message {
|
||||||
0 => {
|
ActivityStartMessage::Unknown(activity_start_unknown) => {
|
||||||
entry.insert(Activity::Unknown(ActivityUnknown {
|
entry.insert(Activity::Unknown(ActivityUnknown {
|
||||||
id: *id,
|
id: activity_start_unknown.id,
|
||||||
parent: *parent,
|
parent: activity_start_unknown.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
level: *level,
|
level: activity_start_unknown.level,
|
||||||
text: text.to_owned(),
|
text: activity_start_unknown.text,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
100 => {
|
ActivityStartMessage::CopyPath(activity_start_copy_path) => {
|
||||||
// TODO: Haven't seen any of these.
|
|
||||||
warn!("Found CopyPath: {}", serde_json::to_string(&message)?);
|
|
||||||
entry.insert(Activity::CopyPath(ActivityCopyPath {
|
entry.insert(Activity::CopyPath(ActivityCopyPath {
|
||||||
id: *id,
|
id: activity_start_copy_path.id,
|
||||||
parent: *parent,
|
parent: activity_start_copy_path.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
101 => {
|
ActivityStartMessage::FileTransfer(activity_start_file_transfer) => {
|
||||||
match fields {
|
|
||||||
Some(f) if f.len() > 1 => {
|
|
||||||
warn!(
|
|
||||||
"Found more than one field in ActivityFileTransfer: {}",
|
|
||||||
serde_json::to_string(&message)?
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
entry.insert(Activity::FileTransfer(ActivityFileTransfer {
|
entry.insert(Activity::FileTransfer(ActivityFileTransfer {
|
||||||
id: *id,
|
id: activity_start_file_transfer.id,
|
||||||
parent: *parent,
|
parent: activity_start_file_transfer.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
level: *level,
|
text: activity_start_file_transfer.text,
|
||||||
text: text.to_owned(),
|
url: activity_start_file_transfer.url,
|
||||||
url: string_field(fields, 0).to_owned(),
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
102 => {
|
ActivityStartMessage::Realize(activity_start_realize) => {
|
||||||
match fields {
|
|
||||||
Some(f) if f.len() > 0 => {
|
|
||||||
warn!(
|
|
||||||
"Found fields in ActivityRealize: {}",
|
|
||||||
serde_json::to_string(&message)?
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
if text.len() > 0 {
|
|
||||||
warn!(
|
|
||||||
"Found Realize with text: {}",
|
|
||||||
serde_json::to_string(&message)?
|
|
||||||
);
|
|
||||||
}
|
|
||||||
entry.insert(Activity::Realize(ActivityRealize {
|
entry.insert(Activity::Realize(ActivityRealize {
|
||||||
id: *id,
|
id: activity_start_realize.id,
|
||||||
parent: *parent,
|
parent: activity_start_realize.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
level: *level,
|
|
||||||
text: text.to_owned(),
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
103 => {
|
ActivityStartMessage::CopyPaths(activity_start_copy_paths) => {
|
||||||
match fields {
|
|
||||||
Some(f) if f.len() > 0 => {
|
|
||||||
warn!(
|
|
||||||
"Found fields in CopyPaths: {}",
|
|
||||||
serde_json::to_string(&message)?
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
if text.len() > 0 {
|
|
||||||
warn!(
|
|
||||||
"Found CopyPaths with text: {}",
|
|
||||||
serde_json::to_string(&message)?
|
|
||||||
);
|
|
||||||
}
|
|
||||||
entry.insert(Activity::CopyPaths(ActivityCopyPaths {
|
entry.insert(Activity::CopyPaths(ActivityCopyPaths {
|
||||||
id: *id,
|
id: activity_start_copy_paths.id,
|
||||||
parent: *parent,
|
parent: activity_start_copy_paths.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
level: *level,
|
level: activity_start_copy_paths.level,
|
||||||
text: text.to_owned(),
|
text: activity_start_copy_paths.text,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
104 => {
|
ActivityStartMessage::Builds(activity_start_builds) => {
|
||||||
match fields {
|
|
||||||
Some(f) if f.len() > 0 => {
|
|
||||||
warn!(
|
|
||||||
"Found fields in Builds: {}",
|
|
||||||
serde_json::to_string(&message)?
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
if text.len() > 0 {
|
|
||||||
warn!(
|
|
||||||
"Found Builds with text: {}",
|
|
||||||
serde_json::to_string(&message)?
|
|
||||||
);
|
|
||||||
}
|
|
||||||
entry.insert(Activity::Builds(ActivityBuilds {
|
entry.insert(Activity::Builds(ActivityBuilds {
|
||||||
id: *id,
|
id: activity_start_builds.id,
|
||||||
parent: *parent,
|
parent: activity_start_builds.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
level: *level,
|
|
||||||
text: text.to_owned(),
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
105 => {
|
ActivityStartMessage::Build(activity_start_build) => {
|
||||||
// TODO: What are the other fields ["/nix/store/j54kvd8mlj8cl9ycvlkh5987fqvzl4p5-m4-1.4.20.tar.bz2.drv","",1,1]
|
|
||||||
entry.insert(Activity::Build(ActivityBuild {
|
entry.insert(Activity::Build(ActivityBuild {
|
||||||
id: *id,
|
id: activity_start_build.id,
|
||||||
parent: *parent,
|
parent: activity_start_build.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
level: *level,
|
text: activity_start_build.text,
|
||||||
text: text.to_owned(),
|
drv_path: activity_start_build.drv_path,
|
||||||
path: string_field(fields, 0).to_owned(),
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
106 => {
|
ActivityStartMessage::OptimizeStore(activity_start_optimize_store) => {
|
||||||
// TODO: Haven't seen any of these.
|
|
||||||
warn!("Found OptimizeStore: {}", serde_json::to_string(&message)?);
|
|
||||||
entry.insert(Activity::OptimizeStore(ActivityOptimizeStore {
|
entry.insert(Activity::OptimizeStore(ActivityOptimizeStore {
|
||||||
id: *id,
|
id: activity_start_optimize_store.id,
|
||||||
parent: *parent,
|
parent: activity_start_optimize_store.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
107 => {
|
ActivityStartMessage::VerifyPaths(activity_start_verify_paths) => {
|
||||||
// TODO: Haven't seen any of these.
|
|
||||||
warn!("Found VerifyPath: {}", serde_json::to_string(&message)?);
|
|
||||||
entry.insert(Activity::VerifyPaths(ActivityVerifyPaths {
|
entry.insert(Activity::VerifyPaths(ActivityVerifyPaths {
|
||||||
id: *id,
|
id: activity_start_verify_paths.id,
|
||||||
parent: *parent,
|
parent: activity_start_verify_paths.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
108 => {
|
ActivityStartMessage::Substitute(activity_start_substitute) => {
|
||||||
// TODO: Haven't seen any of these.
|
|
||||||
warn!("Found Subtitute: {}", serde_json::to_string(&message)?);
|
|
||||||
entry.insert(Activity::Substitute(ActivitySubstitute {
|
entry.insert(Activity::Substitute(ActivitySubstitute {
|
||||||
id: *id,
|
id: activity_start_substitute.id,
|
||||||
parent: *parent,
|
parent: activity_start_substitute.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
109 => {
|
ActivityStartMessage::QueryPathInfo(activity_start_query_path_info) => {
|
||||||
// TODO: Haven't seen any of these.
|
|
||||||
warn!("Found QueryPathInfo: {}", serde_json::to_string(&message)?);
|
|
||||||
entry.insert(Activity::QueryPathInfo(ActivityQueryPathInfo {
|
entry.insert(Activity::QueryPathInfo(ActivityQueryPathInfo {
|
||||||
id: *id,
|
id: activity_start_query_path_info.id,
|
||||||
parent: *parent,
|
parent: activity_start_query_path_info.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
110 => {
|
ActivityStartMessage::PostBuildHook(activity_start_post_build_hook) => {
|
||||||
// TODO: Haven't seen any of these.
|
|
||||||
warn!("Found PostBuildHook: {}", serde_json::to_string(&message)?);
|
|
||||||
entry.insert(Activity::PostBuildHook(ActivityPostBuildHook {
|
entry.insert(Activity::PostBuildHook(ActivityPostBuildHook {
|
||||||
id: *id,
|
id: activity_start_post_build_hook.id,
|
||||||
parent: *parent,
|
parent: activity_start_post_build_hook.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
111 => {
|
ActivityStartMessage::BuildWaiting(activity_start_build_waiting) => {
|
||||||
// TODO: Haven't seen any of these.
|
|
||||||
warn!("Found BuildWaiting: {}", serde_json::to_string(&message)?);
|
|
||||||
entry.insert(Activity::BuildWaiting(ActivityBuildWaiting {
|
entry.insert(Activity::BuildWaiting(ActivityBuildWaiting {
|
||||||
id: *id,
|
id: activity_start_build_waiting.id,
|
||||||
parent: *parent,
|
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
112 => {
|
ActivityStartMessage::FetchTree(activity_start_fetch_tree) => {
|
||||||
// TODO: Haven't seen any of these.
|
|
||||||
warn!("Found FetchTree: {}", serde_json::to_string(&message)?);
|
|
||||||
entry.insert(Activity::FetchTree(ActivityFetchTree {
|
entry.insert(Activity::FetchTree(ActivityFetchTree {
|
||||||
id: *id,
|
id: activity_start_fetch_tree.id,
|
||||||
parent: *parent,
|
parent: activity_start_fetch_tree.parent,
|
||||||
state: ActivityState::default(),
|
state: ActivityState::default(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
_ => {
|
|
||||||
panic!(
|
|
||||||
"Unhandled start activity: {}",
|
|
||||||
serde_json::to_string(&message)?
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
self.print_current_status();
|
self.print_current_status();
|
||||||
}
|
}
|
||||||
NixAction::Stop { id } => {
|
NixAction::Stop(stop_message) => {
|
||||||
let entry = self.activity_tree.entry(*id);
|
let entry = self.activity_tree.entry(stop_message.id);
|
||||||
match entry {
|
match entry {
|
||||||
std::collections::btree_map::Entry::Vacant(_vacant_entry) => {
|
std::collections::btree_map::Entry::Vacant(_vacant_entry) => {
|
||||||
panic!("Stopped an activity that is not in the tree: {id}");
|
panic!(
|
||||||
|
"Stopped an activity that is not in the tree: {}",
|
||||||
|
stop_message.id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
std::collections::btree_map::Entry::Occupied(mut occupied_entry) => {
|
std::collections::btree_map::Entry::Occupied(mut occupied_entry) => {
|
||||||
occupied_entry.get_mut().stop();
|
occupied_entry.get_mut().stop();
|
||||||
@@ -324,56 +229,52 @@ impl<'db> RunningBuild<'db> {
|
|||||||
self.print_current_status();
|
self.print_current_status();
|
||||||
// println!("{}", serde_json::to_string(&message)?);
|
// println!("{}", serde_json::to_string(&message)?);
|
||||||
}
|
}
|
||||||
NixAction::Result { id, fields, r#type } => {
|
NixAction::Result(activity_result_message) => {
|
||||||
match r#type {
|
match activity_result_message {
|
||||||
100 => {
|
ActivityResultMessage::FileLinked(activity_result_file_linked) => {
|
||||||
// FileLinked
|
// FileLinked
|
||||||
// TODO: Haven't seen any of these.
|
// TODO: Haven't seen any of these.
|
||||||
warn!("Found FileLinked: {}", serde_json::to_string(&message)?);
|
// warn!("Found FileLinked: {}", serde_json::to_string(&message)?);
|
||||||
}
|
}
|
||||||
101 => {
|
ActivityResultMessage::BuildLogLine(activity_result_build_log_line) => {
|
||||||
// BuildLogLine
|
// BuildLogLine
|
||||||
// The first field is a string containing the log line
|
// The first field is a string containing the log line
|
||||||
}
|
}
|
||||||
102 => {
|
ActivityResultMessage::UntrustedPath(activity_result_untrusted_path) => {
|
||||||
// UntrustedPath
|
// UntrustedPath
|
||||||
// TODO: Haven't seen any of these.
|
// TODO: Haven't seen any of these.
|
||||||
warn!("Found UntrustedPath: {}", serde_json::to_string(&message)?);
|
// warn!("Found UntrustedPath: {}", serde_json::to_string(&message)?);
|
||||||
}
|
}
|
||||||
103 => {
|
ActivityResultMessage::CorruptedPath(activity_result_corrupted_path) => {
|
||||||
// CorruptedPath
|
// CorruptedPath
|
||||||
// TODO: Haven't seen any of these.
|
// TODO: Haven't seen any of these.
|
||||||
warn!("Found CorruptedPath: {}", serde_json::to_string(&message)?);
|
// warn!("Found CorruptedPath: {}", serde_json::to_string(&message)?);
|
||||||
}
|
}
|
||||||
104 => {
|
ActivityResultMessage::SetPhase(activity_result_set_phase) => { // SetPhase
|
||||||
// SetPhase
|
|
||||||
// The first field is the phase name
|
// The first field is the phase name
|
||||||
}
|
}
|
||||||
105 => {
|
ActivityResultMessage::Progress(activity_result_progress) => { // Progress
|
||||||
// Progress
|
|
||||||
// Fields numerator, denominator, running?, failed?
|
// Fields numerator, denominator, running?, failed?
|
||||||
}
|
}
|
||||||
106 => {
|
ActivityResultMessage::SetExpected(activity_result_set_expected) => { // SetExpected
|
||||||
// SetExpected
|
|
||||||
// Fields activity type?, expected?
|
// Fields activity type?, expected?
|
||||||
}
|
}
|
||||||
107 => {
|
ActivityResultMessage::PostBuildLogLine(
|
||||||
|
activity_result_post_build_log_line,
|
||||||
|
) => {
|
||||||
// PostBuildLogLine
|
// PostBuildLogLine
|
||||||
// TODO: Haven't seen any of these.
|
// TODO: Haven't seen any of these.
|
||||||
warn!(
|
// warn!(
|
||||||
"Found PostBuildLogLine: {}",
|
// "Found PostBuildLogLine: {}",
|
||||||
serde_json::to_string(&message)?
|
// serde_json::to_string(&message)?
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
108 => {
|
ActivityResultMessage::FetchStatus(activity_result_fetch_status) => {
|
||||||
// FetchStatus
|
// FetchStatus
|
||||||
// TODO: Haven't seen any of these.
|
// TODO: Haven't seen any of these.
|
||||||
warn!("Found FetchStatus: {}", serde_json::to_string(&message)?);
|
// warn!("Found FetchStatus: {}", serde_json::to_string(&message)?);
|
||||||
// println!("{}", serde_json::to_string(&message)?);
|
// println!("{}", serde_json::to_string(&message)?);
|
||||||
}
|
}
|
||||||
_ => {
|
|
||||||
panic!("Unhandled result: {}", serde_json::to_string(&message)?);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -381,41 +282,15 @@ impl<'db> RunningBuild<'db> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn print_current_status(&self) -> () {
|
fn print_current_status(&self) -> () {
|
||||||
// let in_progress = self
|
let in_progress = self
|
||||||
// .activity_tree
|
.activity_tree
|
||||||
// .iter()
|
.iter()
|
||||||
// .filter(|activity: &(&u64, &ActivityTreeEntry)| activity.1.is_active());
|
.filter(|activity: &(&u64, &Activity)| activity.1.is_active());
|
||||||
// let names: Vec<&str> = in_progress
|
let names: Vec<Cow<'_, str>> = in_progress
|
||||||
// .map(|activity| match activity.1 {
|
.filter_map(|(id, activity)| activity.display_name())
|
||||||
// ActivityTreeEntry::Unknown {
|
.collect();
|
||||||
// id,
|
let name_list = names.join(", ");
|
||||||
// parent,
|
// TODO: Make a meaningful current status.
|
||||||
// r#type,
|
|
||||||
// state,
|
|
||||||
// } => "unknown",
|
|
||||||
// ActivityTreeEntry::System {
|
|
||||||
// id,
|
|
||||||
// parent,
|
|
||||||
// r#type,
|
|
||||||
// state,
|
|
||||||
// } => "system",
|
|
||||||
// ActivityTreeEntry::Download {
|
|
||||||
// id,
|
|
||||||
// parent,
|
|
||||||
// r#type,
|
|
||||||
// state,
|
|
||||||
// url,
|
|
||||||
// } => url,
|
|
||||||
// ActivityTreeEntry::Build {
|
|
||||||
// id,
|
|
||||||
// parent,
|
|
||||||
// r#type,
|
|
||||||
// state,
|
|
||||||
// path,
|
|
||||||
// } => path,
|
|
||||||
// })
|
|
||||||
// .collect();
|
|
||||||
// let name_list = names.join(", ");
|
|
||||||
// println!("In progress: {name_list}");
|
// println!("In progress: {name_list}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,25 +335,6 @@ enum Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Activity {
|
impl Activity {
|
||||||
fn get_type(&self) -> u8 {
|
|
||||||
match self {
|
|
||||||
Activity::Unknown(_) => 0,
|
|
||||||
Activity::CopyPath(_) => 100,
|
|
||||||
Activity::FileTransfer(_) => 101,
|
|
||||||
Activity::Realize(_) => 102,
|
|
||||||
Activity::CopyPaths(_) => 103,
|
|
||||||
Activity::Builds(_) => 104,
|
|
||||||
Activity::Build(_) => 105,
|
|
||||||
Activity::OptimizeStore(_) => 106,
|
|
||||||
Activity::VerifyPaths(_) => 107,
|
|
||||||
Activity::Substitute(_) => 108,
|
|
||||||
Activity::QueryPathInfo(_) => 109,
|
|
||||||
Activity::PostBuildHook(_) => 110,
|
|
||||||
Activity::BuildWaiting(_) => 111,
|
|
||||||
Activity::FetchTree(_) => 112,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn stop(&mut self) -> () {
|
fn stop(&mut self) -> () {
|
||||||
match self {
|
match self {
|
||||||
Activity::Unknown(activity_unknown) => {
|
Activity::Unknown(activity_unknown) => {
|
||||||
@@ -525,6 +381,120 @@ impl Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_active(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Activity::Unknown(activity_unknown) => {
|
||||||
|
matches!(activity_unknown.state, ActivityState::Started { .. })
|
||||||
|
}
|
||||||
|
Activity::CopyPath(activity_copy_path) => {
|
||||||
|
matches!(activity_copy_path.state, ActivityState::Started { .. })
|
||||||
|
}
|
||||||
|
Activity::FileTransfer(activity_file_transfer) => {
|
||||||
|
matches!(activity_file_transfer.state, ActivityState::Started { .. })
|
||||||
|
}
|
||||||
|
Activity::Realize(activity_realize) => {
|
||||||
|
matches!(activity_realize.state, ActivityState::Started { .. })
|
||||||
|
}
|
||||||
|
Activity::CopyPaths(activity_copy_paths) => {
|
||||||
|
matches!(activity_copy_paths.state, ActivityState::Started { .. })
|
||||||
|
}
|
||||||
|
Activity::Builds(activity_builds) => {
|
||||||
|
matches!(activity_builds.state, ActivityState::Started { .. })
|
||||||
|
}
|
||||||
|
Activity::Build(activity_build) => {
|
||||||
|
matches!(activity_build.state, ActivityState::Started { .. })
|
||||||
|
}
|
||||||
|
Activity::OptimizeStore(activity_optimize_store) => {
|
||||||
|
matches!(activity_optimize_store.state, ActivityState::Started { .. })
|
||||||
|
}
|
||||||
|
Activity::VerifyPaths(activity_verify_paths) => {
|
||||||
|
matches!(activity_verify_paths.state, ActivityState::Started { .. })
|
||||||
|
}
|
||||||
|
Activity::Substitute(activity_substitute) => {
|
||||||
|
matches!(activity_substitute.state, ActivityState::Started { .. })
|
||||||
|
}
|
||||||
|
Activity::QueryPathInfo(activity_query_path_info) => {
|
||||||
|
matches!(
|
||||||
|
activity_query_path_info.state,
|
||||||
|
ActivityState::Started { .. }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Activity::PostBuildHook(activity_post_build_hook) => {
|
||||||
|
matches!(
|
||||||
|
activity_post_build_hook.state,
|
||||||
|
ActivityState::Started { .. }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Activity::BuildWaiting(activity_build_waiting) => {
|
||||||
|
matches!(activity_build_waiting.state, ActivityState::Started { .. })
|
||||||
|
}
|
||||||
|
Activity::FetchTree(activity_fetch_tree) => {
|
||||||
|
matches!(activity_fetch_tree.state, ActivityState::Started { .. })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_name(&self) -> Option<Cow<'_, str>> {
|
||||||
|
match self {
|
||||||
|
Activity::Unknown(activity_unknown) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("Unknown"))
|
||||||
|
}
|
||||||
|
Activity::CopyPath(activity_copy_path) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("CopyPath"))
|
||||||
|
}
|
||||||
|
Activity::FileTransfer(activity_file_transfer) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("FileTransfer"))
|
||||||
|
}
|
||||||
|
Activity::Realize(activity_realize) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("Realize"))
|
||||||
|
}
|
||||||
|
Activity::CopyPaths(activity_copy_paths) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("CopyPaths"))
|
||||||
|
}
|
||||||
|
Activity::Builds(activity_builds) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("Builds"))
|
||||||
|
}
|
||||||
|
Activity::Build(activity_build) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("Build"))
|
||||||
|
}
|
||||||
|
Activity::OptimizeStore(activity_optimize_store) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("OptimizeStore"))
|
||||||
|
}
|
||||||
|
Activity::VerifyPaths(activity_verify_paths) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("VerifyPaths"))
|
||||||
|
}
|
||||||
|
Activity::Substitute(activity_substitute) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("Substitute"))
|
||||||
|
}
|
||||||
|
Activity::QueryPathInfo(activity_query_path_info) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("QueryPathInfo"))
|
||||||
|
}
|
||||||
|
Activity::PostBuildHook(activity_post_build_hook) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("PostBuildHook"))
|
||||||
|
}
|
||||||
|
Activity::BuildWaiting(activity_build_waiting) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("BuildWaiting"))
|
||||||
|
}
|
||||||
|
Activity::FetchTree(activity_fetch_tree) => {
|
||||||
|
// TODO
|
||||||
|
Some(Cow::Borrowed("FetchTree"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ActivityUnknown {
|
struct ActivityUnknown {
|
||||||
@@ -543,7 +513,6 @@ struct ActivityFileTransfer {
|
|||||||
id: u64,
|
id: u64,
|
||||||
parent: u64,
|
parent: u64,
|
||||||
state: ActivityState,
|
state: ActivityState,
|
||||||
level: u8,
|
|
||||||
text: String,
|
text: String,
|
||||||
url: String,
|
url: String,
|
||||||
}
|
}
|
||||||
@@ -551,8 +520,6 @@ struct ActivityRealize {
|
|||||||
id: u64,
|
id: u64,
|
||||||
parent: u64,
|
parent: u64,
|
||||||
state: ActivityState,
|
state: ActivityState,
|
||||||
level: u8,
|
|
||||||
text: String,
|
|
||||||
}
|
}
|
||||||
struct ActivityCopyPaths {
|
struct ActivityCopyPaths {
|
||||||
id: u64,
|
id: u64,
|
||||||
@@ -565,16 +532,13 @@ struct ActivityBuilds {
|
|||||||
id: u64,
|
id: u64,
|
||||||
parent: u64,
|
parent: u64,
|
||||||
state: ActivityState,
|
state: ActivityState,
|
||||||
level: u8,
|
|
||||||
text: String,
|
|
||||||
}
|
}
|
||||||
struct ActivityBuild {
|
struct ActivityBuild {
|
||||||
id: u64,
|
id: u64,
|
||||||
parent: u64,
|
parent: u64,
|
||||||
state: ActivityState,
|
state: ActivityState,
|
||||||
level: u8,
|
|
||||||
text: String,
|
text: String,
|
||||||
path: String,
|
drv_path: String,
|
||||||
}
|
}
|
||||||
struct ActivityOptimizeStore {
|
struct ActivityOptimizeStore {
|
||||||
id: u64,
|
id: u64,
|
||||||
@@ -603,7 +567,6 @@ struct ActivityPostBuildHook {
|
|||||||
}
|
}
|
||||||
struct ActivityBuildWaiting {
|
struct ActivityBuildWaiting {
|
||||||
id: u64,
|
id: u64,
|
||||||
parent: u64,
|
|
||||||
state: ActivityState,
|
state: ActivityState,
|
||||||
}
|
}
|
||||||
struct ActivityFetchTree {
|
struct ActivityFetchTree {
|
||||||
@@ -611,51 +574,3 @@ struct ActivityFetchTree {
|
|||||||
parent: u64,
|
parent: u64,
|
||||||
state: ActivityState,
|
state: ActivityState,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ActivityResult {
|
|
||||||
FileLinked(ResultFileLinked),
|
|
||||||
BuildLogLine(ResultBuildLogLine),
|
|
||||||
UntrustedPath(ResultUntrustedPath),
|
|
||||||
CorruptedPath(ResultCorruptedPath),
|
|
||||||
SetPhase(ResultSetPhase),
|
|
||||||
Progress(ResultProgress),
|
|
||||||
SetExpected(ResultSetExpected),
|
|
||||||
PostBuildLogLine(ResultPostBuildLogLine),
|
|
||||||
FetchStatus(ResultFetchStatus),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ActivityResult {
|
|
||||||
fn get_type(&self) -> u8 {
|
|
||||||
match self {
|
|
||||||
ActivityResult::FileLinked(_) => 100,
|
|
||||||
ActivityResult::BuildLogLine(_) => 101,
|
|
||||||
ActivityResult::UntrustedPath(_) => 102,
|
|
||||||
ActivityResult::CorruptedPath(_) => 103,
|
|
||||||
ActivityResult::SetPhase(_) => 104,
|
|
||||||
ActivityResult::Progress(_) => 105,
|
|
||||||
ActivityResult::SetExpected(_) => 106,
|
|
||||||
ActivityResult::PostBuildLogLine(_) => 107,
|
|
||||||
ActivityResult::FetchStatus(_) => 108,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ResultFileLinked {}
|
|
||||||
struct ResultBuildLogLine {}
|
|
||||||
struct ResultUntrustedPath {}
|
|
||||||
struct ResultCorruptedPath {}
|
|
||||||
struct ResultSetPhase {}
|
|
||||||
struct ResultProgress {}
|
|
||||||
struct ResultSetExpected {}
|
|
||||||
struct ResultPostBuildLogLine {}
|
|
||||||
struct ResultFetchStatus {}
|
|
||||||
|
|
||||||
fn string_field(fields: &Option<Vec<Field>>, ind: usize) -> &String {
|
|
||||||
match fields {
|
|
||||||
Some(fields) => match &fields[ind] {
|
|
||||||
Field::Number(_n) => panic!("Expected field {ind} to be text, but it is a number."),
|
|
||||||
Field::Text(t) => t,
|
|
||||||
},
|
|
||||||
None => panic!("Expected fields but no fields present."),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user