From 5bb4072e245d318f177cf3a8b3fbfd16dff870f8 Mon Sep 17 00:00:00 2001 From: PlexSheep Date: Fri, 26 Apr 2024 10:03:52 +0200 Subject: [PATCH] remodeling our structure with git a bit --- .autocrate.yaml | 14 +++++++------- src/config/mod.rs | 17 +++++++++++++++-- src/git/mod.rs | 35 +++++++++++++++++++++++------------ src/release/mod.rs | 13 ++++++++----- src/serverapi/forgejo.rs | 9 ++++----- src/serverapi/gitea.rs | 13 +++++-------- src/serverapi/github.rs | 7 ++----- src/serverapi/gitlab.rs | 13 +++++-------- src/serverapi/mod.rs | 14 +++++--------- 9 files changed, 74 insertions(+), 61 deletions(-) diff --git a/.autocrate.yaml b/.autocrate.yaml index 427c875..f1cec2b 100644 --- a/.autocrate.yaml +++ b/.autocrate.yaml @@ -13,13 +13,13 @@ uses: - cscherr api: - # github: - # type: github - # repository: autocrate - # auth: - # user: PlexSheep - # pass: - # !env TOKEN_GH + github: + type: github + repository: autocrate + auth: + user: PlexSheep + pass: + !env TOKEN_GH cscherr: type: forgejo endpoint: https://git.cscherr.de diff --git a/src/config/mod.rs b/src/config/mod.rs index dbede01..04aa38a 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -119,6 +119,20 @@ pub struct Api { /// Name of the repository on the Git server, as git itself has no concept of repository name pub repository: String, } +impl std::fmt::Display for Api { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self.server_type { + ApiType::Github => write!( + f, + "{}", + self.server_type + .default_endpoint() + .expect("no default endpoint set for github") + ), + _ => write!(f, "{}", self.endpoint.clone().expect("no endpoint set")), + } + } +} impl YamlConfigSection for Api { fn check(&self) -> Result<()> { self.server_type.check()?; @@ -259,10 +273,10 @@ impl YamlConfig { } } +#[derive(Clone)] pub struct Config { pub yaml: YamlConfig, pub cli: Cli, - pub repo: git2::Repository, pub path: PathBuf, } @@ -319,7 +333,6 @@ impl Config { Ok(Config { yaml, - repo, path, cli: cli.clone(), }) diff --git a/src/git/mod.rs b/src/git/mod.rs index bac89fc..0597fc2 100644 --- a/src/git/mod.rs +++ b/src/git/mod.rs @@ -1,26 +1,38 @@ use std::process::Command; use git2; +use libpt::log::error; +use crate::error::ConfigError; use crate::{config::Config, error::Result}; -pub async fn tag(cfg: &Config) -> Result { +pub(crate) fn get_repo() -> Result { + let repo = match git2::Repository::open_from_env() { + Ok(repo) => repo, + Err(_err) => { + let err = ConfigError::GitRepoNotFound.into(); + error!("{err}"); + return Err(err); + } + }; + Ok(repo) +} + +pub async fn tag<'repo>(repo: &'repo mut git2::Repository, cfg: &Config) -> Result> { // TODO: error handling // TODO: allow force // TODO: allow setting a message // TODO: maybe using git as cmd is fancier? - let target = cfg - .repo + let target = repo .find_object( - cfg.repo.head().unwrap().target().unwrap(), + repo.head().unwrap().target().unwrap(), Some(git2::ObjectType::Commit), ) .unwrap(); - let tagger = cfg.repo.signature().expect("could not get signature"); + let tagger = repo.signature().expect("could not get signature"); let message = String::new(); let force = true; - let tag = cfg - .repo + let tag = repo .tag( &cfg.yaml.version.get_version(), // "importantversion", @@ -30,7 +42,7 @@ pub async fn tag(cfg: &Config) -> Result { force, ) .unwrap(); - let tag: git2::Tag = cfg.repo.find_tag(tag).unwrap(); + let tag: git2::Tag = repo.find_tag(tag).unwrap(); Ok(tag) } @@ -41,12 +53,11 @@ pub async fn push(_cfg: &Config) -> Result<()> { Ok(()) } -pub async fn get_commit_sig(cfg: &Config) -> Result { +pub async fn get_commit_sig<'repo>(repo: &'repo git2::Repository) -> Result { // TODO: error handling // TODO: maybe using git as cmd is fancier? - let target = cfg - .repo - .find_commit(cfg.repo.head().unwrap().target().unwrap()) + let target = repo + .find_commit(repo.head().unwrap().target().unwrap()) .unwrap(); Ok(target.id().to_string()) } diff --git a/src/release/mod.rs b/src/release/mod.rs index 9494ebc..af81679 100644 --- a/src/release/mod.rs +++ b/src/release/mod.rs @@ -1,11 +1,12 @@ use crate::{ config::Config, error::*, - git::{get_commit_sig, push, tag}, + git::{self, get_commit_sig, push, tag}, serverapi::ApiCollection, }; use futures::{self, stream::FuturesUnordered, StreamExt}; +use libpt::log::info; #[derive(Debug, Clone, PartialEq, Hash)] pub struct ReleaseContext { @@ -21,8 +22,9 @@ pub struct ReleaseContext { pub async fn release(cfg: &Config, apis: &mut ApiCollection) -> Result<()> { // TODO: Error handling let _changelog = crate::changelog::Changelog::build(cfg)?.to_string(); - let tag = tag(cfg).await?.name().unwrap().to_string(); - let commit_sig = get_commit_sig(cfg).await?; + let mut repo = git::get_repo()?; + let tag = tag(&mut repo, cfg).await?.name().unwrap().to_string(); + let commit_sig = get_commit_sig(&repo).await?; push(cfg).await?; // we assume that we only need to push the current branch to the singular // remote, expecting that the repositories are somehow mirrored // TODO: push to multiple remotes? @@ -34,16 +36,17 @@ pub async fn release(cfg: &Config, apis: &mut ApiCollection) -> Result<()> { draft: true, prerelease: true, username: api - .get_cfg() + .get_inner() .clone() .auth .expect("no auth but trying to publish") .user, - repository: api.get_cfg().repository.clone(), + repository: api.get_inner().repository.clone(), text: crate::changelog::Changelog::build(cfg)?.to_string(), tag: tag.clone(), commit_sig: commit_sig.clone(), }; + info!("pushing release for {}", api.get_inner()); results.push(api.push_release(specific_rc)); } diff --git a/src/serverapi/forgejo.rs b/src/serverapi/forgejo.rs index 511f1b6..5609e6a 100644 --- a/src/serverapi/forgejo.rs +++ b/src/serverapi/forgejo.rs @@ -8,11 +8,12 @@ use forgejo_api; pub struct Forgejo { api: Api, + cfg: Config, api_wrapper: forgejo_api::Forgejo, } impl Forgejo { - pub async fn build(api: &Api) -> Result { + pub async fn build(api: &Api, cfg: &Config) -> Result { let api_wrapper: forgejo_api::Forgejo = forgejo_api::Forgejo::new( forgejo_api::Auth::Token(&api.auth.clone().unwrap().pass.get_pass()?), api.endpoint.clone().unwrap(), @@ -20,6 +21,7 @@ impl Forgejo { .map_err(ServerApiError::from)?; Ok(Self { api: api.clone(), + cfg: cfg.clone(), api_wrapper, }) } @@ -27,9 +29,6 @@ impl Forgejo { #[async_trait] impl ServerApi for Forgejo { - async fn init(&mut self, _cfg: &Config) -> Result<()> { - Ok(()) - } async fn push_release(&mut self, rc: ReleaseContext) -> Result<()> { let body: forgejo_api::structs::CreateReleaseOption = forgejo_api::structs::CreateReleaseOption { @@ -52,7 +51,7 @@ impl ServerApi for Forgejo { async fn push_pkg(&mut self, _pc: PublishContext) -> Result<()> { todo!() } - fn get_cfg(&self) -> &Api { + fn get_inner(&self) -> &Api { &self.api } } diff --git a/src/serverapi/gitea.rs b/src/serverapi/gitea.rs index 3e6460a..9b87b3f 100644 --- a/src/serverapi/gitea.rs +++ b/src/serverapi/gitea.rs @@ -6,14 +6,11 @@ use crate::{ error::*, }; pub struct Gitea { - cfg: Api, + api: Api, } #[async_trait] impl ServerApi for Gitea { - async fn init(&mut self, _cfg: &Config) -> Result<()> { - todo!() - } async fn push_release(&mut self, _rc: ReleaseContext) -> Result<()> { todo!() } @@ -23,13 +20,13 @@ impl ServerApi for Gitea { async fn push_pkg(&mut self, _pc: PublishContext) -> Result<()> { todo!() } - fn get_cfg(&self) -> &Api { - &self.cfg + fn get_inner(&self) -> &Api { + &self.api } } impl Gitea { - pub async fn build(api: &Api) -> Result { - Ok(Self { cfg: api.clone() }) + pub async fn build(api: &Api, cfg: &Config) -> Result { + Ok(Self { api: api.clone() }) } } diff --git a/src/serverapi/github.rs b/src/serverapi/github.rs index 429dbcb..913c8a0 100644 --- a/src/serverapi/github.rs +++ b/src/serverapi/github.rs @@ -11,7 +11,7 @@ pub struct Github { } impl Github { - pub async fn build(api: &Api) -> Result { + pub async fn build(api: &Api, cfg: &Config) -> Result { Ok(Self { api: api.to_owned(), }) @@ -20,9 +20,6 @@ impl Github { #[async_trait] impl ServerApi for Github { - async fn init(&mut self, _cfg: &Config) -> Result<()> { - Ok(()) - } async fn push_release(&mut self, rc: ReleaseContext) -> Result<()> { let _response = octocrab::instance() .repos(rc.username, rc.repository) @@ -44,7 +41,7 @@ impl ServerApi for Github { async fn push_pkg(&mut self, _pc: PublishContext) -> Result<()> { todo!() } - fn get_cfg(&self) -> &Api { + fn get_inner(&self) -> &Api { &self.api } } diff --git a/src/serverapi/gitlab.rs b/src/serverapi/gitlab.rs index 2706b11..71fe98a 100644 --- a/src/serverapi/gitlab.rs +++ b/src/serverapi/gitlab.rs @@ -6,14 +6,11 @@ use crate::{ error::*, }; pub struct Gitlab { - cfg: Api, + api: Api, } #[async_trait] impl ServerApi for Gitlab { - async fn init(&mut self, _cfg: &Config) -> Result<()> { - todo!() - } async fn push_release(&mut self, _rc: ReleaseContext) -> Result<()> { todo!() } @@ -23,13 +20,13 @@ impl ServerApi for Gitlab { async fn push_pkg(&mut self, _pc: PublishContext) -> Result<()> { todo!() } - fn get_cfg(&self) -> &Api { - &self.cfg + fn get_inner(&self) -> &Api { + &self.api } } impl Gitlab { - pub async fn build(api: &Api) -> Result { - Ok(Self { cfg: api.clone() }) + pub async fn build(api: &Api, cfg: &Config) -> Result { + Ok(Self { api: api.clone() }) } } diff --git a/src/serverapi/mod.rs b/src/serverapi/mod.rs index b1894da..0e77e74 100644 --- a/src/serverapi/mod.rs +++ b/src/serverapi/mod.rs @@ -26,11 +26,10 @@ pub static USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_P // The `async_trait` crate can be used to work around this limitation. #[async_trait] pub trait ServerApi { - async fn init(&mut self, cfg: &Config) -> Result<()>; async fn push_release(&mut self, rc: ReleaseContext) -> Result<()>; async fn push_release_artifact(&mut self, rc: ReleaseContext) -> Result<()>; async fn push_pkg(&mut self, pc: PublishContext) -> Result<()>; - fn get_cfg(&self) -> &config::Api; + fn get_inner(&self) -> &config::Api; } pub(crate) type ApiCollectionInner = Vec>; @@ -45,22 +44,19 @@ impl ApiCollection { for api in &cfg.yaml.api { match api.1.server_type { ApiType::Gitea => { - collection.push(Box::new(Gitea::build(api.1).await?)); + collection.push(Box::new(Gitea::build(api.1, cfg).await?)); } ApiType::Gitlab => { - collection.push(Box::new(Gitlab::build(api.1).await?)); + collection.push(Box::new(Gitlab::build(api.1, cfg).await?)); } ApiType::Github => { - collection.push(Box::new(Github::build(api.1).await?)); + collection.push(Box::new(Github::build(api.1, cfg).await?)); } ApiType::Forgejo => { - collection.push(Box::new(Forgejo::build(api.1).await?)); + collection.push(Box::new(Forgejo::build(api.1, cfg).await?)); } } } - for api in collection.iter_mut() { - api.init(cfg).await?; - } Ok(ApiCollection { collection }) }