feat: add cuddle ci draft
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
e29615cb05
commit
8cf148726a
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -320,6 +320,17 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cuddle-ci"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"clap",
|
||||
"dagger-sdk",
|
||||
"eyre",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cuddle-components"
|
||||
version = "0.1.0"
|
||||
|
@ -23,3 +23,7 @@ eyre = "0.6.9"
|
||||
tokio = "1.34.0"
|
||||
dotenv = "0.15.0"
|
||||
async-trait = "0.1.74"
|
||||
color-eyre = "*"
|
||||
clap = {version = "4", features = ["derive"]}
|
||||
futures = "0.3.28"
|
||||
async-scoped = { version = "0.7.1", features = ["tokio", "use-tokio"] }
|
||||
|
19
crates/cuddle-ci/Cargo.toml
Normal file
19
crates/cuddle-ci/Cargo.toml
Normal file
@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "cuddle-ci"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
readme.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
dagger-sdk.workspace = true
|
||||
eyre.workspace = true
|
||||
clap.workspace = true
|
||||
async-trait.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
tokio.workspace = true
|
152
crates/cuddle-ci/src/lib.rs
Normal file
152
crates/cuddle-ci/src/lib.rs
Normal file
@ -0,0 +1,152 @@
|
||||
use std::{env::Args, sync::Arc};
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
pub struct CuddleCI {
|
||||
pr_action: Arc<dyn PullRequestAction + Send + Sync>,
|
||||
main_action: Arc<dyn MainAction + Send + Sync>,
|
||||
release_action: Arc<dyn ReleaseAction + Send + Sync>,
|
||||
}
|
||||
|
||||
impl CuddleCI {
|
||||
pub fn new(
|
||||
pr: Arc<dyn PullRequestAction + Send + Sync>,
|
||||
main: Arc<dyn MainAction + Send + Sync>,
|
||||
release: Arc<dyn ReleaseAction + Send + Sync>,
|
||||
) -> Self {
|
||||
Self {
|
||||
pr_action: pr,
|
||||
main_action: main,
|
||||
release_action: release,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_pull_request(&mut self, pr: Arc<dyn PullRequestAction + Send + Sync>) -> &mut Self {
|
||||
self.pr_action = pr;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_main(&mut self, main: Arc<dyn MainAction + Send + Sync>) -> &mut Self {
|
||||
self.main_action = main;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_release(&mut self, release: Arc<dyn ReleaseAction + Send + Sync>) -> &mut Self {
|
||||
self.release_action = release;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn execute(&mut self, args: impl IntoIterator<Item = &str>) -> eyre::Result<()> {
|
||||
let matches = clap::Command::new("cuddle-ci")
|
||||
.about("is a wrapper around common CI actions")
|
||||
.subcommand(clap::Command::new("pr"))
|
||||
.subcommand(clap::Command::new("main"))
|
||||
.subcommand(clap::Command::new("release"))
|
||||
.subcommand_required(true)
|
||||
.try_get_matches_from(args.into_iter())?;
|
||||
|
||||
match matches.subcommand() {
|
||||
Some((name, args)) => match (name, args) {
|
||||
("pr", args) => {
|
||||
eprintln!("starting pr validate");
|
||||
self.pr_action.validate().await?;
|
||||
eprintln!("finished pr validate");
|
||||
}
|
||||
("main", args) => {
|
||||
eprintln!("starting main validate");
|
||||
self.main_action.validate().await?;
|
||||
eprintln!("finished main validate");
|
||||
}
|
||||
("release", args) => {
|
||||
eprintln!("starting release validate");
|
||||
self.release_action.validate().await?;
|
||||
eprintln!("finished release validate");
|
||||
}
|
||||
(command_name, _) => {
|
||||
eyre::bail!("command is not recognized: {}", command_name)
|
||||
}
|
||||
},
|
||||
None => eyre::bail!("command required a subcommand [pr, main, release] etc."),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CuddleCI {
|
||||
fn default() -> Self {
|
||||
Self::new(
|
||||
Arc::new(DefaultPullRequestAction {}),
|
||||
Arc::new(DefaultMainAction {}),
|
||||
Arc::new(DefaultReleaseAction {}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait PullRequestAction {
|
||||
async fn validate(&self) -> eyre::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DefaultPullRequestAction {}
|
||||
#[async_trait]
|
||||
impl PullRequestAction for DefaultPullRequestAction {}
|
||||
|
||||
#[async_trait]
|
||||
pub trait MainAction {
|
||||
async fn validate(&self) -> eyre::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DefaultMainAction {}
|
||||
#[async_trait]
|
||||
impl MainAction for DefaultMainAction {}
|
||||
|
||||
#[async_trait]
|
||||
pub trait ReleaseAction {
|
||||
async fn validate(&self) -> eyre::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DefaultReleaseAction {}
|
||||
#[async_trait]
|
||||
impl ReleaseAction for DefaultReleaseAction {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_can_call_default() -> eyre::Result<()> {
|
||||
CuddleCI::default().execute(["cuddle-ci", "pr"]).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_fails_on_no_command() -> eyre::Result<()> {
|
||||
let res = CuddleCI::default().execute(["cuddle-ci"]).await;
|
||||
|
||||
assert!(res.is_err());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_fails_on_wrong_command() -> eyre::Result<()> {
|
||||
let res = CuddleCI::default()
|
||||
.execute(["cuddle-ci", "something"])
|
||||
.await;
|
||||
|
||||
assert!(res.is_err());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user