diff --git a/Cargo.lock b/Cargo.lock index d1074ec..f8f6172 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" [[package]] name = "autocfg" @@ -194,6 +194,17 @@ dependencies = [ "serde_json", ] +[[package]] +name = "cuddle-actions" +version = "0.1.0" +source = "git+ssh://git@git.front.kjuulh.io/kjuulh/cuddle-v2#dfa70b348593a9053b2ab7f866ff4ab2bcddfeea" +dependencies = [ + "anyhow", + "clap", + "serde", + "serde_json", +] + [[package]] name = "diff" version = "0.1.13" @@ -427,6 +438,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "rust" +version = "0.1.0" +dependencies = [ + "anyhow", + "cuddle-actions 0.1.0 (git+ssh://git@git.front.kjuulh.io/kjuulh/cuddle-v2)", + "tokio", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -555,9 +575,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.39.3" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 3592167..2bea466 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["crates/*"] +members = ["crates/*", "**/actions/rust"] resolver = "2" [workspace.package] diff --git a/crates/cuddle/examples/actions/project/actions/rust/Cargo.lock b/crates/cuddle/examples/actions/project/actions/rust/Cargo.lock new file mode 100644 index 0000000..11693ad --- /dev/null +++ b/crates/cuddle/examples/actions/project/actions/rust/Cargo.lock @@ -0,0 +1,528 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "cuddle-actions" +version = "0.1.0" +source = "git+ssh://git@git.front.kjuulh.io/kjuulh/cuddle-v2#dfa70b348593a9053b2ab7f866ff4ab2bcddfeea" +dependencies = [ + "anyhow", + "clap", + "serde", + "serde_json", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[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.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rust" +version = "0.1.0" +dependencies = [ + "anyhow", + "cuddle-actions", + "tokio", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tokio" +version = "1.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/crates/cuddle/examples/actions/project/actions/rust/Cargo.toml b/crates/cuddle/examples/actions/project/actions/rust/Cargo.toml new file mode 100644 index 0000000..2afb665 --- /dev/null +++ b/crates/cuddle/examples/actions/project/actions/rust/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0.91" +cuddle-actions = { git = "ssh://git@git.front.kjuulh.io/kjuulh/cuddle-v2", version = "0.1.0" } +tokio = { version = "1.41.0", features = ["full"] } diff --git a/crates/cuddle/examples/actions/project/actions/rust/rust-analyzer.toml b/crates/cuddle/examples/actions/project/actions/rust/rust-analyzer.toml new file mode 100644 index 0000000..e69de29 diff --git a/crates/cuddle/examples/actions/project/actions/rust/src/main.rs b/crates/cuddle/examples/actions/project/actions/rust/src/main.rs new file mode 100644 index 0000000..9f27314 --- /dev/null +++ b/crates/cuddle/examples/actions/project/actions/rust/src/main.rs @@ -0,0 +1,12 @@ +use cuddle_actions::AddActionOptions; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + println!("Hello, world!"); + + cuddle_actions::CuddleActions::default() + .add_action("something", || Ok(()), &AddActionOptions::default()) + .execute()?; + + Ok(()) +} diff --git a/crates/cuddle/examples/actions/project/cuddle.toml b/crates/cuddle/examples/actions/project/cuddle.toml new file mode 100644 index 0000000..a600aec --- /dev/null +++ b/crates/cuddle/examples/actions/project/cuddle.toml @@ -0,0 +1,5 @@ +[project] +name = "action" + +[project.actions] +rust = true diff --git a/crates/cuddle/src/actions.rs b/crates/cuddle/src/actions.rs new file mode 100644 index 0000000..c8e17de --- /dev/null +++ b/crates/cuddle/src/actions.rs @@ -0,0 +1,93 @@ +use std::{ + collections::BTreeMap, + path::{Path, PathBuf}, +}; + +use rust_builder::RustActionsBuilder; + +use crate::state::validated_project::Value; + +pub mod builder; + +pub mod rust_builder { + use std::path::PathBuf; + + use super::ExecutableActions; + + pub struct RustActionsBuilder { + root_path: PathBuf, + } + + impl RustActionsBuilder { + pub fn new(root_path: PathBuf) -> Self { + Self { root_path } + } + + pub async fn build(&self) -> anyhow::Result { + Ok(ExecutableActions::default()) + } + } +} + +pub struct Actions { + variants: Vec, +} + +impl Actions { + pub async fn new(path: &Path, value: &Value) -> anyhow::Result> { + let Some(project) = value.get(&["project", "actions"]) else { + tracing::debug!("found no actions folder"); + return Ok(None); + }; + + let mut variants = Vec::default(); + if let Some(Value::Bool(true)) = project.get(&["rust"]) { + tracing::debug!("rust actions enabled"); + variants.push(ActionVariant::Rust { + root_path: path.to_path_buf(), + }); + } else { + tracing::trace!("rust actions not enabled"); + } + + Ok(Some(Self { variants })) + } + + pub async fn build(&mut self) -> anyhow::Result> { + let mut executable_actions = Vec::default(); + + for variant in &mut self.variants { + match variant { + ActionVariant::Rust { root_path } => { + let actions = RustActionsBuilder::new(root_path.clone()).build().await?; + + executable_actions.push(actions); + } + ActionVariant::Docker => todo!(), + } + } + + Ok(executable_actions) + } +} + +pub enum ActionVariant { + Rust { root_path: PathBuf }, + Docker, +} + +#[derive(Default)] +pub struct ExecutableActions { + actions: Vec, +} + +pub struct ExecutableAction { + name: String, + description: String, + flags: BTreeMap, +} + +pub enum ExecutableActionFlag { + String, + Bool, +} diff --git a/crates/cuddle/src/actions/builder.rs b/crates/cuddle/src/actions/builder.rs new file mode 100644 index 0000000..04bc07d --- /dev/null +++ b/crates/cuddle/src/actions/builder.rs @@ -0,0 +1 @@ +pub struct ActionsBuilder {} diff --git a/crates/cuddle/src/cli.rs b/crates/cuddle/src/cli.rs index 51a746a..a26b924 100644 --- a/crates/cuddle/src/cli.rs +++ b/crates/cuddle/src/cli.rs @@ -1,17 +1,24 @@ -use std::{borrow::BorrowMut, io::Write}; +use std::io::Write; use anyhow::anyhow; +use clap::{FromArgMatches, Subcommand}; use get_command::GetCommand; use crate::{cuddle_state::Cuddle, state::ValidatedState}; mod get_command; +mod init_command; pub struct Cli { cli: clap::Command, cuddle: Cuddle, } +#[derive(clap::Parser, Debug)] +pub enum Subcommands { + Init(init_command::InitCommand), +} + impl Cli { pub fn new(cuddle: Cuddle) -> Self { let cli = clap::Command::new("cuddle").subcommand_required(true); @@ -24,6 +31,8 @@ impl Cli { self.cli = self.cli.subcommands(commands); + self.cli = Subcommands::augment_subcommands(self.cli); + // TODO: Add global // TODO: Add components @@ -44,9 +53,17 @@ impl Cli { } pub async fn execute(self) -> anyhow::Result<()> { - match self - .cli - .get_matches_from(std::env::args()) + let matches = self.cli.get_matches_from(std::env::args()); + + if let Ok(subcommand) = Subcommands::from_arg_matches(&matches) { + match subcommand { + Subcommands::Init(init_command) => { + init_command.execute(&self.cuddle).await?; + } + } + } + + match matches .subcommand() .ok_or(anyhow::anyhow!("failed to find subcommand"))? { diff --git a/crates/cuddle/src/cli/init_command.rs b/crates/cuddle/src/cli/init_command.rs new file mode 100644 index 0000000..9a0fcfd --- /dev/null +++ b/crates/cuddle/src/cli/init_command.rs @@ -0,0 +1,31 @@ +use clap::Parser; +use rust_action::RustAction; + +use crate::{cuddle_state::Cuddle, state::ValidatedState}; + +pub mod rust_action; + +#[derive(Parser, Debug)] +#[command(subcommand_required = true)] +pub struct InitCommand { + #[clap(subcommand)] + commands: InitCommands, +} + +#[derive(clap::Parser, Debug)] +pub enum InitCommands { + #[clap(name = "actions:rust")] + RustAction(RustAction), +} + +impl InitCommand { + pub async fn execute(&self, cuddle: &Cuddle) -> anyhow::Result<()> { + match &self.commands { + InitCommands::RustAction(rust_action) => { + rust_action.execute(cuddle).await?; + } + } + + Ok(()) + } +} diff --git a/crates/cuddle/src/cli/init_command/rust_action.rs b/crates/cuddle/src/cli/init_command/rust_action.rs new file mode 100644 index 0000000..a89922f --- /dev/null +++ b/crates/cuddle/src/cli/init_command/rust_action.rs @@ -0,0 +1,13 @@ +use crate::{cuddle_state::Cuddle, state::ValidatedState}; + +#[derive(clap::Parser, Debug)] +pub struct RustAction {} + +impl RustAction { + pub async fn execute(&self, cuddle: &Cuddle) -> anyhow::Result<()> { + let project = cuddle.must_project()?; + let root = &project.root; + + Ok(()) + } +} diff --git a/crates/cuddle/src/cuddle_state.rs b/crates/cuddle/src/cuddle_state.rs index 460aa9d..a33031c 100644 --- a/crates/cuddle/src/cuddle_state.rs +++ b/crates/cuddle/src/cuddle_state.rs @@ -1,5 +1,6 @@ use crate::plan::{ClonedPlan, Plan}; use crate::project::ProjectPlan; +use crate::state::validated_project::Project; use crate::state::{self, ValidatedState}; pub struct Start {} @@ -54,7 +55,7 @@ impl Cuddle { impl Cuddle { pub async fn build_state(&self) -> anyhow::Result> { - let state = if let Some(project) = &self.state.project { + let mut state = if let Some(project) = &self.state.project { let state = state::State::new(); let raw_state = state.build_state(project, &self.state.plan).await?; @@ -63,6 +64,8 @@ impl Cuddle { ValidatedState::default() }; + state.build_actions().await?; + Ok(Cuddle { state }) } } @@ -79,4 +82,13 @@ impl Cuddle { false } + + pub fn project(&self) -> Option<&Project> { + self.state.project.as_ref() + } + + pub fn must_project(&self) -> anyhow::Result<&Project> { + self.project() + .ok_or(anyhow::anyhow!("project is not available in this context")) + } } diff --git a/crates/cuddle/src/main.rs b/crates/cuddle/src/main.rs index a591d43..fa4f24f 100644 --- a/crates/cuddle/src/main.rs +++ b/crates/cuddle/src/main.rs @@ -1,6 +1,7 @@ use cli::Cli; use cuddle_state::Cuddle; +mod actions; mod cli; mod cuddle_state; mod plan; diff --git a/crates/cuddle/src/state.rs b/crates/cuddle/src/state.rs index 4e7f8f5..4eb7594 100644 --- a/crates/cuddle/src/state.rs +++ b/crates/cuddle/src/state.rs @@ -1,6 +1,7 @@ use validated_project::Project; use crate::{ + actions::Actions, plan::{self, ClonedPlan, PlanPathExt}, project::{self, ProjectPlan}, schema_validator::SchemaValidator, @@ -42,6 +43,7 @@ impl State { Ok(ValidatedState { project: Some(project), plan: None, + actions: LocalActions::default(), }) } } @@ -55,6 +57,51 @@ pub struct RawState { pub struct ValidatedState { pub project: Option, pub plan: Option, + + pub actions: LocalActions, +} + +impl ValidatedState { + pub(crate) async fn build_actions(&mut self) -> anyhow::Result<&mut Self> { + tracing::debug!("building actions"); + + if let Some(project) = &self.project { + if let Some(actions) = Actions::new(&project.root, &project.value).await? { + self.actions.add(actions); + } + } + + self.actions.build().await?; + + Ok(self) + } } pub struct Plan {} + +#[derive(Default)] +pub struct LocalActions(Vec); + +impl LocalActions { + pub fn add(&mut self, actions: Actions) -> &mut Self { + self.0.push(actions); + + self + } + + pub async fn build(&mut self) -> anyhow::Result<&mut Self> { + for actions in &mut self.0 { + actions.build().await?; + } + + Ok(self) + } +} + +impl std::ops::Deref for LocalActions { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/crates/cuddle/src/state/validated_project.rs b/crates/cuddle/src/state/validated_project.rs index c057bbb..d027022 100644 --- a/crates/cuddle/src/state/validated_project.rs +++ b/crates/cuddle/src/state/validated_project.rs @@ -73,3 +73,18 @@ impl From<&toml::Value> for Value { } } } + +impl Value { + pub fn get(&self, path: &[&str]) -> Option<&Value> { + match path.split_first() { + Some((current, rest)) => match self { + Value::Map(map) => match map.get(¤t.to_string()) { + Some(value) => value.get(rest), + None => None, + }, + _ => None, + }, + None => Some(self), + } + } +}