From ab3d1d9817ad526d2d3d5b48ca7effd014b2ad6e Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sun, 11 Feb 2024 16:56:22 +0100 Subject: [PATCH] feat: with release manager Signed-off-by: kjuulh --- Cargo.lock | 35 ++++++++++- crates/flux-releaser/Cargo.toml | 3 + crates/flux-releaser/src/cli.rs | 4 +- crates/flux-releaser/src/grpc.rs | 37 ++++++++++-- crates/flux-releaser/src/services.rs | 1 + .../flux-releaser/src/services/file_store.rs | 28 +++++++++ .../src/services/file_store/extensions.rs | 14 +++++ .../src/services/release_manager.rs | 58 ++++++++++++++----- .../src/services/release_manager/default.rs | 11 ---- .../services/release_manager/extensions.rs | 13 +++++ .../src/services/release_manager/models.rs | 22 +++++++ .../src/services/release_manager/traits.rs | 4 -- 12 files changed, 192 insertions(+), 38 deletions(-) create mode 100644 crates/flux-releaser/src/services/file_store.rs create mode 100644 crates/flux-releaser/src/services/file_store/extensions.rs delete mode 100644 crates/flux-releaser/src/services/release_manager/default.rs create mode 100644 crates/flux-releaser/src/services/release_manager/extensions.rs create mode 100644 crates/flux-releaser/src/services/release_manager/models.rs delete mode 100644 crates/flux-releaser/src/services/release_manager/traits.rs diff --git a/Cargo.lock b/Cargo.lock index 538e888..925e881 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,15 +90,21 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "atomic" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" + [[package]] name = "autocfg" version = "1.1.0" @@ -334,16 +340,19 @@ name = "flux-releaser" version = "0.1.0" dependencies = [ "anyhow", + "async-trait", "axum 0.7.4", "clap", "dotenv", "mockall", + "mockall_double", "prost", "tokio", "tonic", "tonic-build", "tracing", "tracing-subscriber", + "uuid", ] [[package]] @@ -790,6 +799,18 @@ dependencies = [ "syn", ] +[[package]] +name = "mockall_double" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1ca96e5ac35256ae3e13536edd39b172b88f41615e1d7b653c8ad24524113e8" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "multimap" version = "0.8.3" @@ -1482,6 +1503,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "uuid" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +dependencies = [ + "atomic", + "getrandom", +] + [[package]] name = "valuable" version = "0.1.0" diff --git a/crates/flux-releaser/Cargo.toml b/crates/flux-releaser/Cargo.toml index 71c66ea..6119faa 100644 --- a/crates/flux-releaser/Cargo.toml +++ b/crates/flux-releaser/Cargo.toml @@ -13,6 +13,9 @@ dotenv.workspace = true axum.workspace = true prost = "0.12.3" tonic = "0.11.0" +uuid = { version = "1.7.0", features = ["v7", "v4"] } +async-trait = "0.1.77" +mockall_double = "0.3.1" [build-dependencies] tonic-build = "0.11.0" diff --git a/crates/flux-releaser/src/cli.rs b/crates/flux-releaser/src/cli.rs index 27862a2..442a859 100644 --- a/crates/flux-releaser/src/cli.rs +++ b/crates/flux-releaser/src/cli.rs @@ -32,10 +32,10 @@ impl Command { let app = SharedApp::new(); tokio::select! { - res = axum_serve(host, app) => { + res = axum_serve(host, app.clone()) => { res?; }, - res = tonic_serve(grpc_host) => { + res = tonic_serve(grpc_host, app.clone()) => { res?; }, }; diff --git a/crates/flux-releaser/src/grpc.rs b/crates/flux-releaser/src/grpc.rs index a694e30..d37a4fb 100644 --- a/crates/flux-releaser/src/grpc.rs +++ b/crates/flux-releaser/src/grpc.rs @@ -2,32 +2,57 @@ use std::net::SocketAddr; use tonic::transport::Server; +use crate::{ + app::SharedApp, + services::release_manager::{ + extensions::ReleaseManagerExt, models::CommitArtifact, ReleaseManager, + }, +}; + use self::gen::{greeter_server, HelloReply, HelloRequest}; mod gen { tonic::include_proto!("flux_releaser"); } -#[derive(Debug, Default)] -pub struct FluxReleaserGrpc {} +pub struct FluxReleaserGrpc { + release_manager: ReleaseManager, +} + +impl FluxReleaserGrpc { + pub fn new(app: SharedApp) -> Self { + Self { + release_manager: app.release_manager(), + } + } +} + #[tonic::async_trait] impl greeter_server::Greeter for FluxReleaserGrpc { async fn say_hello( &self, request: tonic::Request, ) -> std::result::Result, tonic::Status> { + self.release_manager + .commit_artifact(CommitArtifact { + app: "some-app".into(), + branch: "some-branch".into(), + }) + .await + .unwrap(); + Ok(tonic::Response::new(HelloReply { message: "something".into(), })) } } -pub async fn tonic_serve(host: SocketAddr) -> anyhow::Result<()> { +pub async fn tonic_serve(host: SocketAddr, app: SharedApp) -> anyhow::Result<()> { tracing::info!("grpc listening on: {}", host); Server::builder() - .add_service(greeter_server::GreeterServer::new( - FluxReleaserGrpc::default(), - )) + .add_service(greeter_server::GreeterServer::new(FluxReleaserGrpc::new( + app, + ))) .serve(host) .await?; diff --git a/crates/flux-releaser/src/services.rs b/crates/flux-releaser/src/services.rs index 69311ed..d77da38 100644 --- a/crates/flux-releaser/src/services.rs +++ b/crates/flux-releaser/src/services.rs @@ -1 +1,2 @@ +mod file_store; pub mod release_manager; diff --git a/crates/flux-releaser/src/services/file_store.rs b/crates/flux-releaser/src/services/file_store.rs new file mode 100644 index 0000000..02fdaa3 --- /dev/null +++ b/crates/flux-releaser/src/services/file_store.rs @@ -0,0 +1,28 @@ +use std::{path::PathBuf, sync::Arc}; + +use super::release_manager::models::ArtifactID; + +pub mod extensions; + +#[derive(Clone)] +pub struct FileStore {} + +#[cfg(test)] +use mockall::{automock, mock, predicate::*}; + +#[cfg_attr(test, automock)] +impl FileStore { + pub fn new() -> Self { + Self {} + } + + pub async fn upload_files( + &self, + artifact_id: ArtifactID, + files: Vec, + ) -> anyhow::Result<()> { + tracing::trace!("uploading files: {}", artifact_id.to_string()); + + Ok(()) + } +} diff --git a/crates/flux-releaser/src/services/file_store/extensions.rs b/crates/flux-releaser/src/services/file_store/extensions.rs new file mode 100644 index 0000000..5c20961 --- /dev/null +++ b/crates/flux-releaser/src/services/file_store/extensions.rs @@ -0,0 +1,14 @@ +use crate::app::SharedApp; + +#[mockall_double::double] +use super::FileStore; + +pub trait FileStoreExt { + fn file_store(&self) -> FileStore; +} + +impl FileStoreExt for SharedApp { + fn file_store(&self) -> FileStore { + FileStore::new() + } +} diff --git a/crates/flux-releaser/src/services/release_manager.rs b/crates/flux-releaser/src/services/release_manager.rs index 9711aff..cb5b48b 100644 --- a/crates/flux-releaser/src/services/release_manager.rs +++ b/crates/flux-releaser/src/services/release_manager.rs @@ -1,25 +1,57 @@ -mod default; -pub mod traits; +#[mockall_double::double] +use crate::services::file_store::FileStore; -use std::sync::Arc; +use self::models::{ArtifactID, CommitArtifact}; -#[derive(Clone)] pub struct ReleaseManager { - inner: Arc, + file_store: FileStore, } impl ReleaseManager { - pub fn get_default() -> Self { - Self { - inner: Arc::new(default::ReleaseManager::new()), - } + pub fn new(file_store: FileStore) -> Self { + Self { file_store } + } + + pub async fn commit_artifact(&self, request: CommitArtifact) -> anyhow::Result { + tracing::debug!("committing artifact: {:?}", request); + let artifact_id = ArtifactID::new(); + + self.file_store + .upload_files(artifact_id.clone(), Vec::new()) + .await?; + + // publish domain event that it has been published + + Ok(artifact_id) } } -impl std::ops::Deref for ReleaseManager { - type Target = Arc; +pub mod extensions; +pub mod models; - fn deref(&self) -> &Self::Target { - &self.inner +#[cfg(test)] +mod test { + use crate::services::file_store::MockFileStore; + + use super::*; + + #[tokio::test] + async fn generated_artifact_id() -> anyhow::Result<()> { + let mut file_store = MockFileStore::new(); + file_store + .expect_upload_files() + .times(1) + .returning(|_, _| Ok(())); + + let releaser_manager = ReleaseManager::new(file_store); + + releaser_manager + .commit_artifact(CommitArtifact { + app: "app".into(), + branch: "branch".into(), + }) + .await?; + + Ok(()) } } diff --git a/crates/flux-releaser/src/services/release_manager/default.rs b/crates/flux-releaser/src/services/release_manager/default.rs deleted file mode 100644 index 2d9ae42..0000000 --- a/crates/flux-releaser/src/services/release_manager/default.rs +++ /dev/null @@ -1,11 +0,0 @@ -use super::traits; - -pub struct ReleaseManager {} - -impl ReleaseManager { - pub fn new() -> Self { - Self {} - } -} - -impl traits::ReleaseManager for ReleaseManager {} diff --git a/crates/flux-releaser/src/services/release_manager/extensions.rs b/crates/flux-releaser/src/services/release_manager/extensions.rs new file mode 100644 index 0000000..f96900c --- /dev/null +++ b/crates/flux-releaser/src/services/release_manager/extensions.rs @@ -0,0 +1,13 @@ +use crate::{app::SharedApp, services::file_store::extensions::FileStoreExt}; + +use super::ReleaseManager; + +pub trait ReleaseManagerExt { + fn release_manager(&self) -> ReleaseManager; +} + +impl ReleaseManagerExt for SharedApp { + fn release_manager(&self) -> ReleaseManager { + ReleaseManager::new(self.file_store()) + } +} diff --git a/crates/flux-releaser/src/services/release_manager/models.rs b/crates/flux-releaser/src/services/release_manager/models.rs new file mode 100644 index 0000000..6cd69cc --- /dev/null +++ b/crates/flux-releaser/src/services/release_manager/models.rs @@ -0,0 +1,22 @@ +#[derive(Clone, Debug)] +pub struct CommitArtifact { + pub app: String, + pub branch: String, +} + +#[derive(Debug, Clone)] +pub struct ArtifactID(uuid::Uuid); + +impl ArtifactID { + pub fn new() -> Self { + Self(uuid::Uuid::now_v7()) + } +} + +impl std::ops::Deref for ArtifactID { + type Target = uuid::Uuid; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/crates/flux-releaser/src/services/release_manager/traits.rs b/crates/flux-releaser/src/services/release_manager/traits.rs deleted file mode 100644 index 275d272..0000000 --- a/crates/flux-releaser/src/services/release_manager/traits.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[cfg(test)] -use mockall::{automock, mock, predicate::*}; -#[cfg_attr(test, automock)] -pub trait ReleaseManager {}