feat: add scripts to model

This commit is contained in:
Kasper Juul Hermansen 2025-02-18 20:44:26 +01:00
parent 61cd888620
commit 84219f46e0
Signed by: kjuulh
SSH Key Fingerprint: SHA256:RjXh0p7U6opxnfd3ga/Y9TCo18FYlHFdSpRIV72S/QM
7 changed files with 352 additions and 13 deletions

265
Cargo.lock generated
View File

@ -17,6 +17,15 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "anstream" name = "anstream"
version = "0.6.18" version = "0.6.18"
@ -100,6 +109,21 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.8.0" version = "2.8.0"
@ -115,12 +139,31 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "bstr"
version = "1.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0"
dependencies = [
"memchr",
"serde",
]
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.10.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9"
[[package]]
name = "cc"
version = "1.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c3d1b2e905a3a7b00a6141adb0e4c0bb941d11caf55349d863942a1cc44e3c9"
dependencies = [
"shlex",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
@ -182,6 +225,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "crypto-common" name = "crypto-common"
version = "0.1.6" version = "0.1.6"
@ -229,6 +281,28 @@ version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "flate2"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]] [[package]]
name = "forest" name = "forest"
version = "0.1.0" version = "0.1.0"
@ -241,6 +315,9 @@ dependencies = [
"minijinja", "minijinja",
"rusty-s3", "rusty-s3",
"serde", "serde",
"serde_json",
"syntect",
"syntect-assets",
"tokio", "tokio",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
@ -292,6 +369,25 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "globset"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19"
dependencies = [
"aho-corasick",
"bstr",
"log",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "hashbrown"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.5.0" version = "0.5.0"
@ -446,6 +542,16 @@ dependencies = [
"icu_properties", "icu_properties",
] ]
[[package]]
name = "indexmap"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]] [[package]]
name = "is_terminal_polyfill" name = "is_terminal_polyfill"
version = "1.70.1" version = "1.70.1"
@ -482,6 +588,12 @@ version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]] [[package]]
name = "litemap" name = "litemap"
version = "0.7.4" version = "0.7.4"
@ -676,6 +788,28 @@ version = "1.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
[[package]]
name = "onig"
version = "6.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
dependencies = [
"bitflags 1.3.2",
"libc",
"once_cell",
"onig_sys",
]
[[package]]
name = "onig_sys"
version = "69.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7"
dependencies = [
"cc",
"pkg-config",
]
[[package]] [[package]]
name = "overload" name = "overload"
version = "0.1.1" version = "0.1.1"
@ -717,6 +851,25 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pkg-config"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "plist"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
dependencies = [
"base64",
"indexmap",
"quick-xml 0.32.0",
"serde",
"time",
]
[[package]] [[package]]
name = "powerfmt" name = "powerfmt"
version = "0.2.0" version = "0.2.0"
@ -732,6 +885,15 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "quick-xml"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "quick-xml" name = "quick-xml"
version = "0.37.2" version = "0.37.2"
@ -757,9 +919,26 @@ version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.8.0",
] ]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.24" version = "0.1.24"
@ -776,7 +955,7 @@ dependencies = [
"hmac", "hmac",
"md-5", "md-5",
"percent-encoding", "percent-encoding",
"quick-xml", "quick-xml 0.37.2",
"serde", "serde",
"serde_json", "serde_json",
"sha2", "sha2",
@ -806,6 +985,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.217" version = "1.0.217"
@ -838,6 +1023,19 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap",
"itoa",
"ryu",
"serde",
"unsafe-libyaml",
]
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.10.8" version = "0.10.8"
@ -858,6 +1056,12 @@ dependencies = [
"lazy_static", "lazy_static",
] ]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]] [[package]]
name = "signal-hook-registry" name = "signal-hook-registry"
version = "1.4.2" version = "1.4.2"
@ -923,6 +1127,46 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "syntect"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1"
dependencies = [
"bincode",
"bitflags 1.3.2",
"flate2",
"fnv",
"once_cell",
"onig",
"plist",
"regex-syntax",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"walkdir",
"yaml-rust",
]
[[package]]
name = "syntect-assets"
version = "0.23.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9555fce7f4031d83b10a9ca0e9c2fe8eba1542c06e2182b7a342e0f2ec2a38e"
dependencies = [
"bincode",
"flate2",
"globset",
"log",
"once_cell",
"semver",
"serde",
"serde_yaml",
"syntect",
"thiserror",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.69" version = "1.0.69"
@ -1099,6 +1343,12 @@ version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]] [[package]]
name = "url" name = "url"
version = "2.5.4" version = "2.5.4"
@ -1302,7 +1552,7 @@ version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.8.0",
] ]
[[package]] [[package]]
@ -1317,6 +1567,15 @@ version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]] [[package]]
name = "yoke" name = "yoke"
version = "0.7.5" version = "0.7.5"

View File

@ -19,3 +19,6 @@ kdl = "6.3.3"
walkdir = "2.5.0" walkdir = "2.5.0"
minijinja = "2.7.0" minijinja = "2.7.0"
glob = "0.3.2" glob = "0.3.2"
serde_json = "1.0.138"
syntect = "5.2.0"
syntect-assets = "0.23.6"

View File

@ -3,6 +3,13 @@ use std::{net::SocketAddr, path::PathBuf};
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use kdl::KdlDocument; use kdl::KdlDocument;
use rusty_s3::{Bucket, Credentials, S3Action}; use rusty_s3::{Bucket, Credentials, S3Action};
use syntect::{
easy::HighlightLines,
highlighting::{Style, ThemeSet},
parsing::SyntaxSet,
util::{as_24_bit_terminal_escaped, LinesWithEndings},
};
use syntect_assets::assets::HighlightingAssets;
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
use crate::{ use crate::{
@ -31,6 +38,8 @@ enum Commands {
Template {}, Template {},
Info {},
Serve { Serve {
#[arg(env = "FOREST_HOST", long, default_value = "127.0.0.1:3000")] #[arg(env = "FOREST_HOST", long, default_value = "127.0.0.1:3000")]
host: SocketAddr, host: SocketAddr,
@ -93,6 +102,23 @@ pub async fn execute() -> anyhow::Result<()> {
tracing::trace!("found context: {:?}", context); tracing::trace!("found context: {:?}", context);
} }
Commands::Info {} => {
let output = serde_json::to_string_pretty(&context)?;
let assets = HighlightingAssets::from_binary();
let theme = assets.get_theme("OneHalfDark");
let ss = SyntaxSet::load_defaults_nonewlines();
let syntax = ss.find_syntax_by_extension("json").unwrap();
let mut h = HighlightLines::new(syntax, theme);
for line in LinesWithEndings::from(&output) {
let ranges: Vec<(Style, &str)> = h.highlight_line(line, &ss).unwrap();
print!("{}", as_24_bit_terminal_escaped(&ranges[..], true));
}
println!()
}
Commands::Template {} => { Commands::Template {} => {
tracing::info!("templating"); tracing::info!("templating");

View File

@ -1,14 +1,15 @@
use std::{collections::BTreeMap, fmt::Debug, path::PathBuf}; use std::{collections::BTreeMap, fmt::Debug, path::PathBuf};
use kdl::{KdlDocument, KdlEntry, KdlNode, KdlValue}; use kdl::{KdlDocument, KdlEntry, KdlNode, KdlValue};
use serde::Serialize;
#[derive(Debug, Clone)] #[derive(Debug, Clone, Serialize)]
pub struct Context { pub struct Context {
pub project: Project, pub project: Project,
pub plan: Option<Plan>, pub plan: Option<Plan>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, Serialize)]
pub struct Plan { pub struct Plan {
pub name: String, pub name: String,
} }
@ -38,7 +39,8 @@ impl TryFrom<KdlDocument> for Plan {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, Serialize)]
#[serde(untagged)]
pub enum ProjectPlan { pub enum ProjectPlan {
Local { path: PathBuf }, Local { path: PathBuf },
NoPlan, NoPlan,
@ -66,7 +68,8 @@ impl TryFrom<&KdlNode> for ProjectPlan {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, Serialize)]
#[serde(untagged)]
pub enum GlobalVariable { pub enum GlobalVariable {
Map(BTreeMap<String, GlobalVariable>), Map(BTreeMap<String, GlobalVariable>),
String(String), String(String),
@ -125,7 +128,7 @@ impl TryFrom<&KdlValue> for GlobalVariable {
} }
} }
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Serialize, Default)]
pub struct Global { pub struct Global {
items: BTreeMap<String, GlobalVariable>, items: BTreeMap<String, GlobalVariable>,
} }
@ -153,14 +156,15 @@ impl TryFrom<&KdlNode> for Global {
} }
} }
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Serialize, Default)]
pub enum TemplateType { pub enum TemplateType {
#[default] #[default]
Jinja2, Jinja2,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, Serialize)]
pub struct Templates { pub struct Templates {
#[serde(rename = "type")]
pub ty: TemplateType, pub ty: TemplateType,
pub path: String, pub path: String,
pub output: PathBuf, pub output: PathBuf,
@ -219,13 +223,50 @@ impl TryFrom<&KdlNode> for Templates {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, Serialize)]
pub struct Action {}
#[derive(Debug, Clone, Serialize)]
pub struct Scripts {
pub path: PathBuf,
pub actions: BTreeMap<String, Action>,
}
impl TryFrom<&KdlNode> for Scripts {
type Error = anyhow::Error;
fn try_from(value: &KdlNode) -> Result<Self, Self::Error> {
let val = Self {
path: value
.get("path")
.and_then(|p| p.as_string())
.map(PathBuf::from)
.unwrap_or(PathBuf::from("scripts/")),
actions: value
.children()
.and_then(|c| c.get("actions"))
.and_then(|a| a.children())
.map(|d| {
d.nodes()
.iter()
.map(|n| (n.name().value().to_string(), Action {}))
.collect::<BTreeMap<String, Action>>()
})
.unwrap_or_default(),
};
Ok(val)
}
}
#[derive(Debug, Clone, Serialize)]
pub struct Project { pub struct Project {
pub name: String, pub name: String,
pub description: Option<String>, pub description: Option<String>,
pub plan: Option<ProjectPlan>, pub plan: Option<ProjectPlan>,
pub global: Global, pub global: Global,
pub templates: Option<Templates>, pub templates: Option<Templates>,
pub scripts: Option<Scripts>,
} }
impl TryFrom<KdlDocument> for Project { impl TryFrom<KdlDocument> for Project {
@ -274,6 +315,10 @@ impl TryFrom<KdlDocument> for Project {
.get("templates") .get("templates")
.map(|t| t.try_into()) .map(|t| t.try_into())
.transpose()?, .transpose()?,
scripts: project_children
.get("scripts")
.map(|m| m.try_into())
.transpose()?,
}) })
} }
} }

View File

@ -25,5 +25,12 @@ project {
path "templates/*.jinja2" path "templates/*.jinja2"
output "output/" output "output/"
} }
scripts type=shell {
path "scripts/"
actions {
build
}
}
} }

View File

@ -21,7 +21,7 @@
"type": "item", "type": "item",
"title": "should be able to template from a remote plan", "title": "should be able to template from a remote plan",
"description": "", "description": "",
"state": "not-done" "state": "done"
}, },
"should be able to use scripts from a remote plan": { "should be able to use scripts from a remote plan": {
"type": "item", "type": "item",

View File

@ -1 +0,0 @@
hyperlog-lock