configuration is more flexible; targets can specify their base file, introduced palettes, and targets can specify & override variables
This commit is contained in:
parent
502e5a7615
commit
7fab543476
6 changed files with 58 additions and 28 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "oink"
|
||||
version = "0.1.1"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
@ -15,9 +15,10 @@ use toml::{
|
|||
Value
|
||||
};
|
||||
|
||||
use crate::error;
|
||||
use crate::{ error, util };
|
||||
|
||||
pub type Context = BTreeMap<String, ContextValue>;
|
||||
pub type Table = toml::map::Map<String, Value>;
|
||||
|
||||
/// configuration struct
|
||||
pub struct Config {
|
||||
|
@ -55,25 +56,38 @@ impl Config {
|
|||
}
|
||||
}
|
||||
|
||||
/// build tera context from "vars" and "colors" config sections
|
||||
pub fn context(&self) -> Context {
|
||||
/// build context from "vars" and "colors" config sections
|
||||
pub fn context(&self, target: &Table) -> Context {
|
||||
let mut output = Context::new();
|
||||
|
||||
let vars = self.inner.get("vars");
|
||||
if vars.is_some() {
|
||||
let vars = vars.unwrap().as_table().unwrap();
|
||||
// pull global vars
|
||||
if let Some(Value::Table(vars)) = self.inner.get("vars") {
|
||||
for (key, value) in vars.iter() {
|
||||
output.insert(key.to_owned(), value.as_str().into());
|
||||
}
|
||||
}
|
||||
let colors = self.inner.get("colors");
|
||||
if colors.is_some() {
|
||||
let colors = colors.unwrap().as_table().unwrap();
|
||||
let mut map = Context::new();
|
||||
for (key, value) in colors.iter() {
|
||||
map.insert(key.to_owned(), value.as_str().unwrap().into());
|
||||
|
||||
// pull target values
|
||||
for (key, value) in target.iter() {
|
||||
if key.to_uppercase() == *key {
|
||||
output.insert(key.to_owned(), value.as_str().unwrap().into());
|
||||
}
|
||||
}
|
||||
|
||||
// pull palette
|
||||
let palette_name: Option<String> =
|
||||
if let Some(Value::String(name)) = target.get("use_palette") { Some(name.clone()) }
|
||||
else if let Some(Value::String(name)) = self.inner.get("use_palette") { Some(name.clone()) }
|
||||
else { None };
|
||||
if let Some(Value::Array(array)) = self.inner.get("palette") {
|
||||
let palette = util::matches(array.to_owned(), palette_name.unwrap_or("default".to_string()));
|
||||
if let Some(Value::Table(palette)) = palette {
|
||||
let colors = Context::new();
|
||||
for(key, value) in palette.iter() {
|
||||
output.insert(key.to_owned(), value.as_str().unwrap().into());
|
||||
}
|
||||
output.insert("palette".to_string(), colors.into());
|
||||
}
|
||||
output.insert("colors".to_owned(), map.into());
|
||||
}
|
||||
|
||||
output
|
||||
|
|
|
@ -3,6 +3,11 @@ use std::{
|
|||
process::exit
|
||||
};
|
||||
|
||||
pub fn no_command() {
|
||||
crate::help_text();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pub fn no_targets() {
|
||||
println!("oink: configuration has no targets");
|
||||
exit(2);
|
||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -1,10 +1,10 @@
|
|||
use std::process::exit;
|
||||
|
||||
use pico_args::Arguments;
|
||||
|
||||
mod config;
|
||||
mod error;
|
||||
mod operation;
|
||||
mod util;
|
||||
|
||||
use crate::config::Config;
|
||||
|
||||
|
@ -27,23 +27,18 @@ fn main() {
|
|||
|
||||
match operation.as_deref() {
|
||||
Some("apply")
|
||||
=> {
|
||||
operation::apply(&targets);
|
||||
},
|
||||
=> operation::apply(&targets),
|
||||
|
||||
Some("build")
|
||||
=> {
|
||||
operation::build(&targets, template_dir, &config);
|
||||
},
|
||||
=> operation::build(&targets, template_dir, &config),
|
||||
|
||||
Some("full")
|
||||
=> {
|
||||
operation::build(&targets, template_dir, &config);
|
||||
operation::apply(&targets);
|
||||
},
|
||||
_
|
||||
=> {
|
||||
help_text();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_ => error::no_command()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,9 +69,9 @@ pub fn build(targets: &Vec<Map<String, Value>>, template_dir: String, config: &C
|
|||
println!("running build:");
|
||||
|
||||
let engine = Engine::new();
|
||||
let context = config.context();
|
||||
|
||||
for target in targets {
|
||||
let context = config.context(target);
|
||||
// get name property
|
||||
let i_name = target.get("name");
|
||||
// handle empty names gracefully
|
||||
|
@ -87,7 +87,9 @@ pub fn build(targets: &Vec<Map<String, Value>>, template_dir: String, config: &C
|
|||
// compile
|
||||
println!(" {ITALIC}compiling{RESET}");
|
||||
let mut path = PathBuf::from(&template_dir);
|
||||
path.push(name);
|
||||
if let Some(Value::String(base)) = target.get("base") { path.push(base); }
|
||||
else { path.push(name); }
|
||||
|
||||
let content = read_to_string(path).unwrap();
|
||||
let template = engine.compile(&content);
|
||||
if template.is_err() {
|
||||
|
|
14
src/util.rs
Normal file
14
src/util.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
use toml::{ value::Array, Value };
|
||||
|
||||
pub fn matches(array: Array, to_match: String) -> Option<Value> {
|
||||
array.iter().filter(|value| {
|
||||
if let Value::Table(table) = value {
|
||||
if let Some(Value::String(name)) = table.get("name") {
|
||||
return *name == to_match;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}).map(|value| value.to_owned()).nth(0)
|
||||
}
|
||||
|
Loading…
Reference in a new issue