From ce84eac3c3faebdaf3ad96140a3bd393f0591c16 Mon Sep 17 00:00:00 2001 From: Joakim Hulthe Date: Thu, 27 May 2021 23:34:46 +0200 Subject: [PATCH] Addd flag to list used template variables --- manager/Cargo.lock | 16 +++---- manager/src/builder.rs | 10 +---- manager/src/main.rs | 18 ++++++-- manager/src/peeker.rs | 98 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 21 deletions(-) create mode 100644 manager/src/peeker.rs diff --git a/manager/Cargo.lock b/manager/Cargo.lock index 16da2cc..2602878 100644 --- a/manager/Cargo.lock +++ b/manager/Cargo.lock @@ -74,8 +74,8 @@ dependencies = [ [[package]] name = "blueprint" -version = "0.3.0" -source = "git+https://git.nubo.sh/hulthe/blueprint.git#0af5d72005bebca426eeff628c1f010d2e850f06" +version = "0.4.0" +source = "git+https://git.nubo.sh/hulthe/blueprint.git#6d382f9a34f1339bec524e7b8f1adb8e3488e635" dependencies = [ "nom", "structopt", @@ -295,9 +295,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" +checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" [[package]] name = "lock_api" @@ -648,18 +648,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" +checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" +checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" dependencies = [ "proc-macro2", "quote", diff --git a/manager/src/builder.rs b/manager/src/builder.rs index d78162e..9282771 100644 --- a/manager/src/builder.rs +++ b/manager/src/builder.rs @@ -3,21 +3,13 @@ use crate::Config; use async_recursion::async_recursion; use blueprint::{parse_template, Env, Value}; use futures::future::join_all; -use serde::Serialize; use std::ffi::OsStr; use std::io::ErrorKind; use std::path::PathBuf; use tokio::fs::{copy, create_dir, read_dir, read_to_string, write}; use tokio::join; -#[derive(Serialize)] -struct TemplateContext<'a> { - hostname: &'a str, - lightmode: bool, - darkmode: bool, -} - -const TEMPLATE_EXTENSION: &str = "tpl"; +pub const TEMPLATE_EXTENSION: &str = "tpl"; pub async fn build_tree(cfg: &Config) -> Result<(), Errors> { let hostname_path: PathBuf = "/etc/hostname".into(); diff --git a/manager/src/main.rs b/manager/src/main.rs index e50caed..70c7cc1 100644 --- a/manager/src/main.rs +++ b/manager/src/main.rs @@ -4,11 +4,13 @@ extern crate log; mod builder; mod error; mod linker; +mod peeker; use builder::build_tree; use error::Errors; use linker::link_tree; use log::LevelFilter; +use peeker::peek_tree; use std::env; use std::path::PathBuf; use structopt::StructOpt; @@ -24,6 +26,9 @@ struct Opt { #[structopt(short, long)] link_dir: Option, + #[structopt(short, long)] + print_variables: bool, + #[structopt(short, parse(from_occurrences))] verbosity: u8, @@ -75,11 +80,16 @@ async fn run() -> Result<(), Errors> { flags: opt.flags, }; - info!("building tree"); - build_tree(&cfg).await?; + if opt.print_variables { + info!("peeking tree"); + peek_tree(&cfg).await?; + } else { + info!("building tree"); + build_tree(&cfg).await?; - info!("linking tree"); - link_tree(&cfg).await?; + info!("linking tree"); + link_tree(&cfg).await?; + } Ok(()) } diff --git a/manager/src/peeker.rs b/manager/src/peeker.rs new file mode 100644 index 0000000..6bb3ed3 --- /dev/null +++ b/manager/src/peeker.rs @@ -0,0 +1,98 @@ +use crate::builder::TEMPLATE_EXTENSION; +use crate::error::{Error, ErrorLocation, Errors}; +use crate::Config; +use async_recursion::async_recursion; +use blueprint::parse_template; +use futures::future::join_all; +use std::ffi::OsStr; +use std::path::PathBuf; +use tokio::fs::{read_dir, read_to_string}; +use tokio::join; + +pub async fn peek_tree(cfg: &Config) -> Result<(), Errors> { + for var in dir(cfg, PathBuf::new()).await? { + println!("{}", var); + } + + Ok(()) +} + +#[async_recursion] +async fn dir(cfg: &Config, relative: PathBuf) -> Result, Errors> { + let template_path = cfg.template_dir.join(&relative); + + info!("traversing {:?}", template_path); + + let mut walker = read_dir(&template_path) + .await + .with_location(&template_path)?; + + let mut dir_tasks = vec![]; + let mut file_tasks = vec![]; + + while let Some(entry) = walker.next_entry().await.with_location(&&template_path)? { + let meta = entry.metadata().await.with_location(&entry.path())?; + let new_relative = relative.join(entry.file_name()); + + if meta.is_dir() { + dir_tasks.push(dir(cfg, new_relative)); + } else if meta.is_file() { + file_tasks.push(file(cfg, new_relative)); + } + } + + let dirs = async { join_all(dir_tasks).await.into_iter().collect::>() }; + let files = async { join_all(file_tasks).await.into_iter().collect::>() }; + let (dirs, files) = join!(dirs, files); + + let mut vars = vec![]; + let mut errors = vec![]; + + for result in files.into_iter() { + match result { + Ok(mut more_vars) => vars.append(&mut more_vars), + Err(error) => errors.push(error), + } + } + + let mut errors: Errors = errors.into(); + + for result in dirs.into_iter() { + match result { + Ok(mut more_vars) => vars.append(&mut more_vars), + Err(error) => errors.join(error), + } + } + + if errors.is_empty() { + vars.sort_unstable(); + vars.dedup(); + Ok(vars) + } else { + Err(errors) + } +} + +async fn file(cfg: &Config, relative: PathBuf) -> Result, Error> { + let template_path = cfg.template_dir.join(&relative); + + if template_path.extension() != Some(OsStr::new(TEMPLATE_EXTENSION)) { + return Ok(vec![]); + } + + debug!("reading {:?}", template_path); + + // parse template + let file_str = read_to_string(&template_path) + .await + .with_location(&template_path)?; + + let vars = parse_template(&file_str) + .with_location(&template_path)? + .list_variables() + .into_iter() + .map(|s| s.to_string()) + .collect(); + + Ok(vars) +}