initial commit
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I6a6a69644236ae18e7b46856fb6d6d6c998f8467
This commit is contained in:
commit
c07b295f71
29 changed files with 6780 additions and 0 deletions
86
cognos/Cargo.lock
generated
Normal file
86
cognos/Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "nous"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_repr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
|
||||
15
cognos/Cargo.toml
Normal file
15
cognos/Cargo.toml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "cognos"
|
||||
description = "Minimalistic parser for Nix's ATerm .drv and internal-json log formats"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
serde.workspace = true
|
||||
serde_repr.workspace = true
|
||||
serde_json.workspace = true
|
||||
414
cognos/src/aterm.rs
Normal file
414
cognos/src/aterm.rs
Normal file
|
|
@ -0,0 +1,414 @@
|
|||
//! `ATerm` and Nix .drv file parser
|
||||
//!
|
||||
//! Parses Nix .drv files in `ATerm` format to extract dependency information.
|
||||
use std::{fs, path::Path};
|
||||
|
||||
/// Parsed derivation information from a .drv file
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ParsedDerivation {
|
||||
pub outputs: Vec<(String, String)>,
|
||||
pub input_drvs: Vec<(String, Vec<String>)>,
|
||||
pub input_srcs: Vec<String>,
|
||||
pub platform: String,
|
||||
pub builder: String,
|
||||
pub args: Vec<String>,
|
||||
pub env: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
/// Parse a .drv file and extract its dependency information
|
||||
pub fn parse_drv_file<P: AsRef<Path>>(
|
||||
path: P,
|
||||
) -> Result<ParsedDerivation, String> {
|
||||
let content = fs::read_to_string(path)
|
||||
.map_err(|e| format!("Failed to read file: {e}"))?;
|
||||
parse_drv_content(&content)
|
||||
}
|
||||
|
||||
/// Parse the content of a .drv file
|
||||
pub fn parse_drv_content(content: &str) -> Result<ParsedDerivation, String> {
|
||||
let content = content.trim();
|
||||
|
||||
if !content.starts_with("Derive(") {
|
||||
return Err(
|
||||
"Invalid derivation format: must start with 'Derive('".to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
let inner = content
|
||||
.strip_prefix("Derive(")
|
||||
.and_then(|s| s.strip_suffix(")"))
|
||||
.ok_or("Invalid derivation format: missing closing parenthesis")?;
|
||||
|
||||
// XXX: The derivation has this structure:
|
||||
// Derive(outputs, inputDrvs, inputSrcs, platform, builder, args, env)
|
||||
let parts = parse_top_level_list(inner)?;
|
||||
|
||||
if parts.len() < 7 {
|
||||
return Err(format!(
|
||||
"Invalid derivation format: expected 7 parts, got {}",
|
||||
parts.len()
|
||||
));
|
||||
}
|
||||
|
||||
let outputs = parse_outputs(&parts[0])?;
|
||||
let input_drvs = parse_input_drvs(&parts[1])?;
|
||||
let input_srcs = parse_string_list(&parts[2])?;
|
||||
let platform = parse_string(&parts[3])?;
|
||||
let builder = parse_string(&parts[4])?;
|
||||
let args = parse_string_list(&parts[5])?;
|
||||
let env = parse_env(&parts[6])?;
|
||||
|
||||
Ok(ParsedDerivation {
|
||||
outputs,
|
||||
input_drvs,
|
||||
input_srcs,
|
||||
platform,
|
||||
builder,
|
||||
args,
|
||||
env,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse the top-level comma-separated list, respecting nested brackets
|
||||
fn parse_top_level_list(s: &str) -> Result<Vec<String>, String> {
|
||||
let mut parts = Vec::new();
|
||||
let mut current = String::new();
|
||||
let mut depth = 0;
|
||||
let mut in_string = false;
|
||||
let mut escape = false;
|
||||
|
||||
for ch in s.chars() {
|
||||
if escape {
|
||||
current.push(ch);
|
||||
escape = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
match ch {
|
||||
'\\' if in_string => {
|
||||
escape = true;
|
||||
current.push(ch);
|
||||
},
|
||||
'"' => {
|
||||
in_string = !in_string;
|
||||
current.push(ch);
|
||||
},
|
||||
'[' | '(' if !in_string => {
|
||||
depth += 1;
|
||||
current.push(ch);
|
||||
},
|
||||
']' | ')' if !in_string => {
|
||||
depth -= 1;
|
||||
current.push(ch);
|
||||
},
|
||||
',' if depth == 0 && !in_string => {
|
||||
parts.push(current.trim().to_string());
|
||||
current.clear();
|
||||
},
|
||||
_ => {
|
||||
current.push(ch);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if !current.trim().is_empty() {
|
||||
parts.push(current.trim().to_string());
|
||||
}
|
||||
|
||||
Ok(parts)
|
||||
}
|
||||
|
||||
/// Parse outputs: [("out","/nix/store/...","",""),...]
|
||||
fn parse_outputs(s: &str) -> Result<Vec<(String, String)>, String> {
|
||||
let s = s.trim();
|
||||
if s == "[]" {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
let inner = s
|
||||
.strip_prefix('[')
|
||||
.and_then(|s| s.strip_suffix(']'))
|
||||
.ok_or("Invalid outputs format")?;
|
||||
|
||||
let tuples = parse_top_level_list(inner)?;
|
||||
let mut outputs = Vec::new();
|
||||
|
||||
for tuple in tuples {
|
||||
let tuple = tuple.trim();
|
||||
let inner = tuple
|
||||
.strip_prefix('(')
|
||||
.and_then(|s| s.strip_suffix(')'))
|
||||
.ok_or("Invalid output tuple format")?;
|
||||
|
||||
let parts = parse_top_level_list(inner)?;
|
||||
if parts.len() >= 2 {
|
||||
let name = parse_string(&parts[0])?;
|
||||
let path = parse_string(&parts[1])?;
|
||||
outputs.push((name, path));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(outputs)
|
||||
}
|
||||
|
||||
/// Parse input derivations: [("/nix/store/foo.drv",["out"]),...]
|
||||
fn parse_input_drvs(s: &str) -> Result<Vec<(String, Vec<String>)>, String> {
|
||||
let s = s.trim();
|
||||
if s == "[]" {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
let inner = s
|
||||
.strip_prefix('[')
|
||||
.and_then(|s| s.strip_suffix(']'))
|
||||
.ok_or("Invalid input drvs format")?;
|
||||
|
||||
let tuples = parse_top_level_list(inner)?;
|
||||
let mut input_drvs = Vec::new();
|
||||
|
||||
for tuple in tuples {
|
||||
let tuple = tuple.trim();
|
||||
let inner = tuple
|
||||
.strip_prefix('(')
|
||||
.and_then(|s| s.strip_suffix(')'))
|
||||
.ok_or("Invalid input drv tuple format")?;
|
||||
|
||||
let parts = parse_top_level_list(inner)?;
|
||||
if parts.len() >= 2 {
|
||||
let drv_path = parse_string(&parts[0])?;
|
||||
let outputs = parse_string_list(&parts[1])?;
|
||||
input_drvs.push((drv_path, outputs));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(input_drvs)
|
||||
}
|
||||
|
||||
/// Parse environment variables: [("name","value"),...]
|
||||
fn parse_env(s: &str) -> Result<Vec<(String, String)>, String> {
|
||||
let s = s.trim();
|
||||
if s == "[]" {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
let inner = s
|
||||
.strip_prefix('[')
|
||||
.and_then(|s| s.strip_suffix(']'))
|
||||
.ok_or("Invalid env format")?;
|
||||
|
||||
let tuples = parse_top_level_list(inner)?;
|
||||
let mut env = Vec::new();
|
||||
|
||||
for tuple in tuples {
|
||||
let tuple = tuple.trim();
|
||||
let inner = tuple
|
||||
.strip_prefix('(')
|
||||
.and_then(|s| s.strip_suffix(')'))
|
||||
.ok_or("Invalid env tuple format")?;
|
||||
|
||||
let parts = parse_top_level_list(inner)?;
|
||||
if parts.len() >= 2 {
|
||||
let name = parse_string(&parts[0])?;
|
||||
let value = parse_string(&parts[1])?;
|
||||
env.push((name, value));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(env)
|
||||
}
|
||||
|
||||
/// Parse a list of strings: ["foo","bar",...]
|
||||
fn parse_string_list(s: &str) -> Result<Vec<String>, String> {
|
||||
let s = s.trim();
|
||||
if s == "[]" {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
let inner = s
|
||||
.strip_prefix('[')
|
||||
.and_then(|s| s.strip_suffix(']'))
|
||||
.ok_or("Invalid string list format")?;
|
||||
|
||||
let items = parse_top_level_list(inner)?;
|
||||
items.into_iter().map(|item| parse_string(&item)).collect()
|
||||
}
|
||||
|
||||
/// Parse a quoted string: "foo" -> foo
|
||||
fn parse_string(s: &str) -> Result<String, String> {
|
||||
let s = s.trim();
|
||||
let inner = s
|
||||
.strip_prefix('"')
|
||||
.and_then(|s| s.strip_suffix('"'))
|
||||
.ok_or_else(|| format!("Invalid string format: {s}"))?;
|
||||
|
||||
// Unescape the string
|
||||
Ok(unescape_string(inner))
|
||||
}
|
||||
|
||||
/// Unescape a string (handle \n, \t, \\, \", etc.)
|
||||
fn unescape_string(s: &str) -> String {
|
||||
let mut result = String::new();
|
||||
let mut chars = s.chars();
|
||||
|
||||
while let Some(ch) = chars.next() {
|
||||
if ch == '\\' {
|
||||
match chars.next() {
|
||||
Some('n') => result.push('\n'),
|
||||
Some('t') => result.push('\t'),
|
||||
Some('r') => result.push('\r'),
|
||||
Some('\\') => result.push('\\'),
|
||||
Some('"') => result.push('"'),
|
||||
Some(c) => {
|
||||
result.push('\\');
|
||||
result.push(c);
|
||||
},
|
||||
None => result.push('\\'),
|
||||
}
|
||||
} else {
|
||||
result.push(ch);
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Extract all input derivation paths from a .drv file
|
||||
pub fn get_input_derivations<P: AsRef<Path>>(
|
||||
path: P,
|
||||
) -> Result<Vec<String>, String> {
|
||||
let parsed = parse_drv_file(path)?;
|
||||
Ok(
|
||||
parsed
|
||||
.input_drvs
|
||||
.into_iter()
|
||||
.map(|(path, _)| path)
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Extract pname from environment variables
|
||||
#[must_use]
|
||||
pub fn extract_pname(env: &[(String, String)]) -> Option<String> {
|
||||
env
|
||||
.iter()
|
||||
.find(|(k, _)| k == "pname")
|
||||
.map(|(_, v)| v.clone())
|
||||
}
|
||||
|
||||
/// Extract version from environment variables
|
||||
#[must_use]
|
||||
pub fn extract_version(env: &[(String, String)]) -> Option<String> {
|
||||
env
|
||||
.iter()
|
||||
.find(|(k, _)| k == "version")
|
||||
.map(|(_, v)| v.clone())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_string() {
|
||||
assert_eq!(parse_string(r#""hello""#).unwrap(), "hello");
|
||||
assert_eq!(parse_string(r#""hello world""#).unwrap(), "hello world");
|
||||
assert_eq!(parse_string(r#""hello\nworld""#).unwrap(), "hello\nworld");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_string_list() {
|
||||
let list = r#"["foo","bar","baz"]"#;
|
||||
let result = parse_string_list(list).unwrap();
|
||||
assert_eq!(result, vec!["foo", "bar", "baz"]);
|
||||
|
||||
let empty = "[]";
|
||||
let result = parse_string_list(empty).unwrap();
|
||||
assert_eq!(result, Vec::<String>::new());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_outputs() {
|
||||
let outputs = r#"[("out","/nix/store/abc-foo","","")]"#;
|
||||
let result = parse_outputs(outputs).unwrap();
|
||||
assert_eq!(result.len(), 1);
|
||||
assert_eq!(result[0].0, "out");
|
||||
assert_eq!(result[0].1, "/nix/store/abc-foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_input_drvs() {
|
||||
let input = r#"[("/nix/store/abc-foo.drv",["out"]),("/nix/store/def-bar.drv",["out","dev"])]"#;
|
||||
let result = parse_input_drvs(input).unwrap();
|
||||
assert_eq!(result.len(), 2);
|
||||
assert_eq!(result[0].0, "/nix/store/abc-foo.drv");
|
||||
assert_eq!(result[0].1, vec!["out"]);
|
||||
assert_eq!(result[1].0, "/nix/store/def-bar.drv");
|
||||
assert_eq!(result[1].1, vec!["out", "dev"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_minimal_drv() {
|
||||
let drv = r#"Derive([("out","/nix/store/output","","")],[],[],"x86_64-linux","/bin/sh",[],[("name","value")])"#;
|
||||
let result = parse_drv_content(drv).unwrap();
|
||||
assert_eq!(result.outputs.len(), 1);
|
||||
assert_eq!(result.outputs[0].0, "out");
|
||||
assert_eq!(result.platform, "x86_64-linux");
|
||||
assert_eq!(result.builder, "/bin/sh");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_with_dependencies() {
|
||||
let drv = r#"Derive([("out","/nix/store/abc-foo","","")],[("/nix/store/dep1.drv",["out"]),("/nix/store/dep2.drv",["out","dev"])],[],"x86_64-linux","/bin/sh",[],[("name","foo")])"#;
|
||||
let result = parse_drv_content(drv).unwrap();
|
||||
assert_eq!(result.input_drvs.len(), 2);
|
||||
assert_eq!(result.input_drvs[0].0, "/nix/store/dep1.drv");
|
||||
assert_eq!(result.input_drvs[0].1, vec!["out"]);
|
||||
assert_eq!(result.input_drvs[1].0, "/nix/store/dep2.drv");
|
||||
assert_eq!(result.input_drvs[1].1, vec!["out", "dev"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_real_world_hello_drv() {
|
||||
// Stripped down version of a real hello.drv
|
||||
let drv = r#"Derive([("out","/nix/store/b1ayn0ln6n8bm2spz441csqc2ss66az3-hello-2.12.2","","")],[("/nix/store/1s1ir3vhwq86x0c7ikhhp3c9cin4095k-hello-2.12.2.tar.gz.drv",["out"]),("/nix/store/bjsb6wdjykafnkixq156qdvmxhsm2bai-bash-5.3p3.drv",["out"]),("/nix/store/lzvy25g887aypn07ah8igv72z7b9jb88-version-check-hook.drv",["out"]),("/nix/store/p76r0cwlf6k97ibprrpfd8xw0r8wc3nx-stdenv-linux.drv",["out"])],["/nix/store/l622p70vy8k5sh7y5wizi5f2mic6ynpg-source-stdenv.sh","/nix/store/shkw4qm9qcw5sc5n1k5jznc83ny02r39-default-builder.sh"],"x86_64-linux","/nix/store/q7sqwn7i6w2b67adw0bmix29pxg85x3w-bash-5.3p3/bin/bash",["-e","/nix/store/l622p70vy8k5sh7y5wizi5f2mic6ynpg-source-stdenv.sh"],[("name","hello-2.12.2"),("pname","hello"),("version","2.12.2"),("system","x86_64-linux")])"#;
|
||||
|
||||
let result = parse_drv_content(drv).unwrap();
|
||||
|
||||
// Verify outputs
|
||||
assert_eq!(result.outputs.len(), 1);
|
||||
assert_eq!(result.outputs[0].0, "out");
|
||||
assert!(result.outputs[0].1.contains("hello-2.12.2"));
|
||||
|
||||
// Verify input derivations
|
||||
assert_eq!(result.input_drvs.len(), 4);
|
||||
assert!(result.input_drvs[0].0.contains("hello-2.12.2.tar.gz.drv"));
|
||||
assert!(result.input_drvs[1].0.contains("bash-5.3p3.drv"));
|
||||
assert!(result.input_drvs[2].0.contains("version-check-hook.drv"));
|
||||
assert!(result.input_drvs[3].0.contains("stdenv-linux.drv"));
|
||||
|
||||
// Verify all inputs have "out" output
|
||||
for (_, outputs) in &result.input_drvs {
|
||||
assert_eq!(outputs, &vec!["out"]);
|
||||
}
|
||||
|
||||
// Verify platform
|
||||
assert_eq!(result.platform, "x86_64-linux");
|
||||
|
||||
// Verify builder
|
||||
assert!(result.builder.contains("bash"));
|
||||
|
||||
// Verify environment
|
||||
assert_eq!(extract_pname(&result.env), Some("hello".to_string()));
|
||||
assert_eq!(extract_version(&result.env), Some("2.12.2".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_input_derivations() {
|
||||
let drv = r#"Derive([("out","/nix/store/out","","")],[("/nix/store/dep.drv",["out"])],[],"x86_64-linux","/bin/sh",[],[("pname","hello"),("version","1.0")])"#;
|
||||
let result = parse_drv_content(drv).unwrap();
|
||||
assert_eq!(result.input_drvs.len(), 1);
|
||||
assert_eq!(result.input_drvs[0].0, "/nix/store/dep.drv");
|
||||
assert_eq!(extract_pname(&result.env).unwrap(), "hello");
|
||||
assert_eq!(extract_version(&result.env).unwrap(), "1.0");
|
||||
}
|
||||
}
|
||||
67
cognos/src/internal_json.rs
Normal file
67
cognos/src/internal_json.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
use serde::Deserialize;
|
||||
use serde_repr::Deserialize_repr;
|
||||
|
||||
#[derive(Deserialize_repr, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum Activities {
|
||||
Unknown = 0,
|
||||
CopyPath = 100,
|
||||
FileTransfer = 101,
|
||||
Realise = 102,
|
||||
CopyPaths = 103,
|
||||
Builds = 104,
|
||||
Build = 105,
|
||||
OptimiseStore = 106,
|
||||
VerifyPath = 107,
|
||||
Substitute = 108,
|
||||
QueryPathInfo = 109,
|
||||
PostBuildHook = 110,
|
||||
BuildWaiting = 111,
|
||||
FetchTree = 112,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Deserialize_repr, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
|
||||
)]
|
||||
#[repr(u8)]
|
||||
pub enum Verbosity {
|
||||
Error = 0,
|
||||
Warning = 1,
|
||||
Notice = 2,
|
||||
Info = 3,
|
||||
Talkative = 4,
|
||||
Chatty = 5,
|
||||
Debug = 6,
|
||||
Vomit = 7,
|
||||
}
|
||||
|
||||
pub type Id = u64;
|
||||
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
#[serde(tag = "action")]
|
||||
pub enum Actions {
|
||||
#[serde(rename = "start")]
|
||||
Start {
|
||||
id: Id,
|
||||
level: Verbosity,
|
||||
#[serde(default)]
|
||||
parent: Id,
|
||||
text: String,
|
||||
#[serde(rename = "type")]
|
||||
activity: Activities,
|
||||
#[serde(default)]
|
||||
fields: Vec<serde_json::Value>,
|
||||
},
|
||||
#[serde(rename = "stop")]
|
||||
Stop { id: Id },
|
||||
#[serde(rename = "msg")]
|
||||
Message { level: Verbosity, msg: String },
|
||||
#[serde(rename = "result")]
|
||||
Result {
|
||||
#[serde(default)]
|
||||
fields: Vec<serde_json::Value>,
|
||||
id: Id,
|
||||
#[serde(rename = "type")]
|
||||
activity: Activities,
|
||||
},
|
||||
}
|
||||
12
cognos/src/lib.rs
Normal file
12
cognos/src/lib.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
pub mod aterm;
|
||||
mod internal_json;
|
||||
mod state;
|
||||
|
||||
pub use aterm::{
|
||||
ParsedDerivation,
|
||||
extract_pname,
|
||||
extract_version,
|
||||
parse_drv_file,
|
||||
};
|
||||
pub use internal_json::{Actions, Activities, Id, Verbosity};
|
||||
pub use state::{BuildInfo, BuildStatus, Derivation, Host, State};
|
||||
73
cognos/src/state.rs
Normal file
73
cognos/src/state.rs
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use crate::internal_json::Actions;
|
||||
|
||||
pub type Id = u64;
|
||||
|
||||
pub enum StorePath {
|
||||
Downloading,
|
||||
Uploading,
|
||||
Downloaded,
|
||||
Uploaded,
|
||||
}
|
||||
|
||||
pub enum BuildStatus {
|
||||
Planned,
|
||||
Running,
|
||||
Complete,
|
||||
Failed,
|
||||
}
|
||||
|
||||
pub enum Progress {
|
||||
JustStarted,
|
||||
InputReceived,
|
||||
Finished,
|
||||
}
|
||||
|
||||
pub enum OutputName {
|
||||
Out,
|
||||
Doc,
|
||||
Dev,
|
||||
Bin,
|
||||
Info,
|
||||
Lib,
|
||||
Man,
|
||||
Dist,
|
||||
Other(String),
|
||||
}
|
||||
|
||||
pub enum Host {
|
||||
Local,
|
||||
Host(String),
|
||||
}
|
||||
|
||||
pub struct Derivation {
|
||||
store_path: PathBuf,
|
||||
}
|
||||
|
||||
pub struct BuildInfo {
|
||||
start: f64,
|
||||
host: Host,
|
||||
estimate: Option<u64>,
|
||||
activity_id: Id,
|
||||
state: BuildStatus,
|
||||
}
|
||||
|
||||
pub enum DependencyState {
|
||||
Planned,
|
||||
Running,
|
||||
Completed,
|
||||
}
|
||||
|
||||
pub struct Dependencies {
|
||||
deps: HashMap<Id, BuildInfo>,
|
||||
}
|
||||
|
||||
// #[derive(Default)]
|
||||
pub struct State {
|
||||
progress: Progress,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn imbibe(&mut self, update: Actions) {}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue