diff --git a/Cargo.lock b/Cargo.lock index 30ef808..b5eadbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,6 +105,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.8" @@ -115,12 +121,40 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + [[package]] name = "libc" version = "0.2.153" @@ -156,6 +190,9 @@ name = "rask" version = "0.1.0" dependencies = [ "clap", + "glob", + "serde", + "serde_yaml", ] [[package]] @@ -171,6 +208,45 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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]] name = "strsim" version = "0.11.0" @@ -219,6 +295,12 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + [[package]] name = "utf8parse" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index b7c8fff..dac7f64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,9 @@ edition = "2021" [dependencies] clap = { version = "4.4.8", features = ["derive", "unicode", "wrap_help"] } +glob = "0.3.1" +serde = { version = "1.0.197", features = ["derive"] } +serde_yaml = "0.9.34" [profile.release] strip = true # Automatically strip symbols from the binary. diff --git a/examples/full-spec/foo/bar/rask.yaml b/examples/full-spec/foo/bar/rask.yaml new file mode 100644 index 0000000..fc66a7c --- /dev/null +++ b/examples/full-spec/foo/bar/rask.yaml @@ -0,0 +1,5 @@ +name: bar + +tasks: + dev: echo 'Hello from bar!' + test: echo 'Testing from bar' diff --git a/examples/full-spec/hello/rask.yaml b/examples/full-spec/hello/rask.yaml new file mode 100644 index 0000000..ee8757a --- /dev/null +++ b/examples/full-spec/hello/rask.yaml @@ -0,0 +1,4 @@ +name: hello + +tasks: + dev: echo 'Hello from hello?' \ No newline at end of file diff --git a/examples/full-spec/rask.yaml b/examples/full-spec/rask.yaml new file mode 100644 index 0000000..9cd7aa8 --- /dev/null +++ b/examples/full-spec/rask.yaml @@ -0,0 +1,10 @@ +# Required +name: main + +directories: + - foo/** + - hello + +tasks: + dev: echo 'Hello from main!' + build: echo 'Building from main!' \ No newline at end of file diff --git a/src/commands/run.rs b/src/commands/run.rs index f6d8e14..58e6a69 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -1,16 +1,23 @@ use clap::Args; +use crate::utils::config_reader::parse_config; use crate::utils::file_resolvers::resolve_configuration_file; #[derive(Args, Debug)] pub struct Arguments { + #[arg()] + command: String, #[arg(default_value = ".")] - target: String + target: String, } pub fn run (arguments: &Arguments) -> Result<(), String> { - let target = resolve_configuration_file(&arguments.target)?; + let Arguments { target, command } = arguments; - println!("{:?}", target); + let target = resolve_configuration_file(target)?; + + let config = parse_config(&target)?; + + println!("{:?}", config); Ok(()) } \ No newline at end of file diff --git a/src/utils/config_reader.rs b/src/utils/config_reader.rs new file mode 100644 index 0000000..4f7d3aa --- /dev/null +++ b/src/utils/config_reader.rs @@ -0,0 +1,81 @@ +use std::collections::HashMap; +use serde::Deserialize; +use std::fs::File; +use std::io::BufReader; +use std::path::PathBuf; +use glob::glob; + +#[derive(Debug, Deserialize, Default)] +struct ConfigFile { + name: String, + #[serde(default)] + directories: Vec, + #[serde(default)] + tasks: HashMap, +} + +fn read_config_file(path_buf: &PathBuf) -> Result { + let file = File::open(path_buf).expect("Failed to read file"); + + let reader = BufReader::new(file); + + let config: ConfigFile = serde_yaml::from_reader(reader).expect("Failed to parse YAML"); + + Ok(config) +} + +#[derive(Debug)] +pub struct ConfigTask { + tag: String, + command: String +} + +#[derive(Debug)] +pub struct SubConfig { + config: Config, + path: PathBuf, +} + +#[derive(Debug)] +pub struct Config { + name: String, + tasks: Vec, + sub_configs: Vec, +} + +pub fn parse_config(path_buf: &PathBuf) -> Result { + let config_file = read_config_file(path_buf)?; + + let name = config_file.name; + + let tasks = config_file.tasks + .iter() + .map(|(tag, command)| ConfigTask{tag: tag.clone(), command: command.clone()}) + .collect(); + + let mut sub_configs: Vec = Vec::new(); + + let parent_dir = path_buf.parent().ok_or("Failed to get parent directory")?; + + for directory in config_file.directories { + let mut pattern: PathBuf = parent_dir.to_path_buf(); + pattern.push(&directory); + if !pattern.ends_with(".yaml") { + pattern.push("rask.yaml"); + } + + for entry in glob(pattern.to_str().unwrap()).map_err(|e| format!("Failed to read glob pattern: {}", e))? { + if let Ok(config_path) = entry { + let sub_config = SubConfig { + config: parse_config(&config_path)?, + path: config_path, + }; + sub_configs.push(sub_config); + } + } + } + + let config = Config{name, tasks, sub_configs}; + + Ok(config) +} \ No newline at end of file diff --git a/src/utils/mod.rs b/src/utils/mod.rs index b207fa4..6eb0168 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1 +1,2 @@ pub mod file_resolvers; +pub mod config_reader;