diff --git a/src/config/mod.rs b/src/config/mod.rs index 04d7132..bdbbfaf 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, fmt::Debug, fs::File, io::BufReader, path::PathBuf}; +use std::{collections::HashMap, fmt::Debug, fs::File, io::BufReader, path::PathBuf, process::Command}; use git2; use libpt::log::{debug, error, trace}; @@ -146,16 +146,64 @@ impl YamlConfigSection for ApiType { } } +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum Version { + Text(String), + Cmd(String), + Cargo, +} + +impl Version { + pub fn get_version(&self) -> String { + // TODO: Error handling + match self { + Self::Text(ver) => ver.clone(), + Self::Cmd(shell_command) => { + match Command::new("/bin/bash").arg("-c").arg(shell_command).output() { + Ok(output) => { + // TODO: check status + String::from_utf8(output.stdout).unwrap() + } + Err(err) => { + panic!("{err:?}"); + } + } + }, + Self::Cargo => todo!(), + } + } +} + +impl YamlConfigSection for Version { + fn check(&self) -> Result<()> { + match self { + Self::Text(_) => (), + Self::Cmd(_cmd) => { + // TODO: get the version with a command + todo!("verion from cmd not implemented") + } + Self::Cargo => { + // TODO: get the version as specified in a Cargo.toml + todo!("verion from cargo not implemented") + } + } + Ok(()) + } +} + #[derive(Debug, Clone, Deserialize)] pub struct YamlConfig { pub changelog: Changelog, pub uses: Uses, pub api: HashMap, + pub version: Version, } impl YamlConfigSection for YamlConfig { fn check(&self) -> Result<()> { self.changelog.check()?; self.uses.check()?; + self.version.check()?; for api in self.api.values() { api.check()?; } diff --git a/src/git/mod.rs b/src/git/mod.rs index 89893df..99ecd01 100644 --- a/src/git/mod.rs +++ b/src/git/mod.rs @@ -1,13 +1,52 @@ +use std::process::Command; + +use git2; + use crate::{config::Config, error::Result}; -pub async fn tag(_cfg: &Config) -> Result { - todo!() +pub async fn tag(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 + .find_object( + cfg.repo.head().unwrap().target().unwrap(), + Some(git2::ObjectType::Commit), + ) + .unwrap(); + let tagger = cfg.repo.signature().expect("could not get signature"); + let message = String::new(); + let force = true; + let tag = cfg + .repo + .tag( + // &cfg.yaml.version.get_version(), + "importantversion", + &target, + &tagger, + &message, + force, + ) + .unwrap(); + let tag: git2::Tag = cfg.repo.find_tag(tag).unwrap(); + Ok(tag) } -pub async fn push(_cfg: &Config) -> Result<()> { - todo!() +pub async fn push(cfg: &Config) -> Result<()> { + // TODO: error handling + // TODO: maybe using git as lib is fancier? + Command::new("git").arg("push").status().unwrap(); + Ok(()) } -pub async fn get_commit_sig(_cfg: &Config) -> Result { - todo!() +pub async fn get_commit_sig(cfg: &Config) -> Result { + // TODO: error handling + // TODO: maybe using git as cmd is fancier? + let target = cfg + .repo + .find_commit(cfg.repo.head().unwrap().target().unwrap()) + .unwrap(); + Ok(target.id().to_string()) } diff --git a/src/release/mod.rs b/src/release/mod.rs index 266c849..18e8abe 100644 --- a/src/release/mod.rs +++ b/src/release/mod.rs @@ -19,7 +19,8 @@ pub struct ReleaseContext { } pub async fn release(cfg: &Config, apis: &mut ApiCollection) -> Result<()> { - let tag: String = tag(cfg).await?; + // TODO: Error handling + let tag = tag(cfg).await?.name().unwrap().to_string(); let commit_sig = get_commit_sig(cfg).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 diff --git a/src/serverapi/forgejo.rs b/src/serverapi/forgejo.rs index 4482e1a..7e5adfc 100644 --- a/src/serverapi/forgejo.rs +++ b/src/serverapi/forgejo.rs @@ -1,3 +1,5 @@ +use std::str::FromStr; + use crate::{ config::{Api, Config}, error::*, @@ -21,8 +23,9 @@ impl Forgejo { if api.auth.is_some() { let _ = headers.insert( "Authorization", - HeaderValue::from_str(api.auth.clone().unwrap().pass.get_pass()?.as_str()) - .map_err(ServerApiError::from)?, + // HeaderValue::from_str(api.auth.clone().unwrap().pass.get_pass()?.as_str()) + // .map_err(ServerApiError::from)?, + HeaderValue::from_str("hardcoded").map_err(ServerApiError::from)? ); } let client = super::client_builder() @@ -39,7 +42,7 @@ impl Forgejo { #[async_trait] impl ServerApi for Forgejo { async fn init(&mut self, _cfg: &Config) -> Result<()> { - todo!() + Ok(()) } async fn push_release(&mut self, rc: ReleaseContext) -> Result<()> { let raw_url = format!(