treewide: move rom's parser logic to cognos

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I6a6a6964960ab80b5555a6cca7b20e11c8ac0ea2
This commit is contained in:
raf 2025-10-10 09:26:03 +03:00
commit 5fea07c768
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
7 changed files with 57 additions and 119 deletions

View file

@ -9,4 +9,13 @@ pub use aterm::{
parse_drv_file, parse_drv_file,
}; };
pub use internal_json::{Actions, Activities, Id, Verbosity}; pub use internal_json::{Actions, Activities, Id, Verbosity};
pub use state::{BuildInfo, BuildStatus, Derivation, Host, State}; pub use state::{BuildInfo, BuildStatus, Derivation, Host, OutputName, State, ProgressState};
/// Process a list of actions and return the resulting state
pub fn process_actions(actions: Vec<Actions>) -> State {
let mut state = State { progress: ProgressState::JustStarted };
for action in actions {
state.imbibe(action);
}
state
}

View file

@ -18,12 +18,14 @@ pub enum BuildStatus {
Failed, Failed,
} }
pub enum Progress { #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ProgressState {
JustStarted, JustStarted,
InputReceived, InputReceived,
Finished, Finished,
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum OutputName { pub enum OutputName {
Out, Out,
Doc, Doc,
@ -36,9 +38,37 @@ pub enum OutputName {
Other(String), Other(String),
} }
impl OutputName {
#[must_use]
pub fn parse(name: &str) -> Self {
match name.to_lowercase().as_str() {
"out" => Self::Out,
"doc" => Self::Doc,
"dev" => Self::Dev,
"bin" => Self::Bin,
"info" => Self::Info,
"lib" => Self::Lib,
"man" => Self::Man,
"dist" => Self::Dist,
_ => Self::Other(name.to_string()),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Host { pub enum Host {
Local, Localhost,
Host(String), Remote(String),
}
impl Host {
#[must_use]
pub fn name(&self) -> &str {
match self {
Self::Localhost => "localhost",
Self::Remote(name) => name,
}
}
} }
pub struct Derivation { pub struct Derivation {
@ -65,7 +95,7 @@ pub struct Dependencies {
// #[derive(Default)] // #[derive(Default)]
pub struct State { pub struct State {
progress: Progress, pub progress: ProgressState,
} }
impl State { impl State {

View file

@ -6,6 +6,7 @@ use std::{
}; };
use clap::Parser; use clap::Parser;
use cognos::ProgressState;
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
#[command(name = "rom", version, about = "ROM - A Nix build output monitor")] #[command(name = "rom", version, about = "ROM - A Nix build output monitor")]
@ -582,7 +583,7 @@ fn run_monitored_command(
if !silent { if !silent {
if has_activity if has_activity
|| state.progress_state != crate::state::ProgressState::JustStarted || state.progress_state != ProgressState::JustStarted
{ {
// Clear any previous timer display // Clear any previous timer display
if last_timer_display.is_some() { if last_timer_display.is_some() {

View file

@ -66,7 +66,6 @@ pub struct Display<W: Write> {
writer: W, writer: W,
config: DisplayConfig, config: DisplayConfig,
last_lines: usize, last_lines: usize,
using_alt_screen: bool,
} }
struct TreeNode { struct TreeNode {
@ -80,7 +79,6 @@ impl<W: Write> Display<W> {
writer, writer,
config, config,
last_lines: 0, last_lines: 0,
using_alt_screen: false,
}) })
} }
@ -860,27 +858,7 @@ impl<W: Write> Display<W> {
lines lines
} }
fn is_active_or_has_active_descendants(
&self,
state: &State,
drv_id: DerivationId,
) -> bool {
if let Some(info) = state.get_derivation_info(drv_id) {
match info.build_status {
BuildStatus::Building(_) => return true,
BuildStatus::Failed { .. } => return true,
_ => {},
}
// Check children
for input in &info.input_derivations {
if self.is_active_or_has_active_descendants(state, input.derivation) {
return true;
}
}
}
false
}
fn build_active_forest( fn build_active_forest(
&self, &self,

View file

@ -12,6 +12,7 @@ use crate::{
types::{Config, InputMode}, types::{Config, InputMode},
update, update,
}; };
use cognos::Host;
/// Main monitor that processes nix output and displays progress /// Main monitor that processes nix output and displays progress
pub struct Monitor<W: Write> { pub struct Monitor<W: Write> {
@ -152,7 +153,7 @@ impl<W: Write> Monitor<W> {
let build_info = crate::state::BuildInfo { let build_info = crate::state::BuildInfo {
start: now, start: now,
host: crate::state::Host::Localhost, host: Host::Localhost,
estimate: None, estimate: None,
activity_id: None, activity_id: None,
}; };
@ -175,7 +176,7 @@ impl<W: Write> Monitor<W> {
let transfer = crate::state::TransferInfo { let transfer = crate::state::TransferInfo {
start: now, start: now,
host: crate::state::Host::Localhost, host: Host::Localhost,
activity_id: 0, // No activity ID in human mode activity_id: 0, // No activity ID in human mode
bytes_transferred: 0, bytes_transferred: 0,
total_bytes: None, total_bytes: None,

View file

@ -6,7 +6,7 @@ use std::{
time::{Duration, SystemTime}, time::{Duration, SystemTime},
}; };
use cognos::Id; use cognos::{Host, Id, OutputName, ProgressState};
use indexmap::IndexMap; use indexmap::IndexMap;
/// Unique identifier for store paths /// Unique identifier for store paths
@ -18,35 +18,9 @@ pub type DerivationId = usize;
/// Unique identifier for activities /// Unique identifier for activities
pub type ActivityId = Id; pub type ActivityId = Id;
/// Overall progress state
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProgressState {
JustStarted,
InputReceived,
Finished,
}
/// Build host information
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Host {
Localhost,
Remote(String),
}
impl Host {
#[must_use]
pub const fn is_local(&self) -> bool {
matches!(self, Self::Localhost)
}
#[must_use]
pub fn name(&self) -> &str {
match self {
Self::Localhost => "localhost",
Self::Remote(name) => name,
}
}
}
/// Store path representation /// Store path representation
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@ -111,36 +85,8 @@ impl Derivation {
} }
} }
/// Output name for derivations
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum OutputName {
Out,
Doc,
Dev,
Bin,
Info,
Lib,
Man,
Dist,
Other(String),
}
impl OutputName {
#[must_use]
pub fn parse(name: &str) -> Self {
match name.to_lowercase().as_str() {
"out" => Self::Out,
"doc" => Self::Doc,
"dev" => Self::Dev,
"bin" => Self::Bin,
"info" => Self::Info,
"lib" => Self::Lib,
"man" => Self::Man,
"dist" => Self::Dist,
_ => Self::Other(name.to_string()),
}
}
}
/// Transfer information (download/upload) /// Transfer information (download/upload)
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -603,7 +549,7 @@ impl State {
// Create output set // Create output set
let mut output_set = HashSet::new(); let mut output_set = HashSet::new();
for output in outputs { for output in outputs {
output_set.insert(parse_output_name(&output)); output_set.insert(OutputName::parse(&output));
} }
// Add to parent's input derivations // Add to parent's input derivations
@ -728,19 +674,7 @@ pub fn current_time() -> f64 {
.as_secs_f64() .as_secs_f64()
} }
fn parse_output_name(name: &str) -> OutputName {
match name {
"out" => OutputName::Out,
"doc" => OutputName::Doc,
"dev" => OutputName::Dev,
"bin" => OutputName::Bin,
"info" => OutputName::Info,
"lib" => OutputName::Lib,
"man" => OutputName::Man,
"dist" => OutputName::Dist,
_ => OutputName::Other(name.to_string()),
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View file

@ -1,6 +1,6 @@
//! State update logic for processing nix messages //! State update logic for processing nix messages
use cognos::{Actions, Activities, Id, Verbosity}; use cognos::{Actions, Activities, Host, Id, ProgressState, Verbosity};
use tracing::{debug, trace}; use tracing::{debug, trace};
use crate::state::{ use crate::state::{
@ -14,10 +14,7 @@ use crate::state::{
DerivationId, DerivationId,
FailType, FailType,
FailedBuildInfo, FailedBuildInfo,
Host,
InputDerivation, InputDerivation,
OutputName,
ProgressState,
State, State,
StorePath, StorePath,
StorePathId, StorePathId,
@ -887,17 +884,5 @@ pub fn finish_state(state: &mut State) {
} }
} }
/// Parse output name string to `OutputName` enum
fn parse_output_name(s: &str) -> Option<OutputName> {
match s {
"out" => Some(OutputName::Out),
"doc" => Some(OutputName::Doc),
"dev" => Some(OutputName::Dev),
"bin" => Some(OutputName::Bin),
"info" => Some(OutputName::Info),
"lib" => Some(OutputName::Lib),
"man" => Some(OutputName::Man),
"dist" => Some(OutputName::Dist),
other => Some(OutputName::Other(other.to_string())),
}
}