refactor(gitforge): disolve gitforge:errors module

This commit is contained in:
Paul Campbell 2024-05-23 08:01:16 +01:00
parent c92e41ee56
commit 564e14a370
7 changed files with 54 additions and 69 deletions

View file

@ -1,41 +0,0 @@
use git_next_config::BranchName;
#[derive(Debug)]
pub enum ForgeFileError {
NotFound(String),
ParseContent,
DecodeFromBase64,
DecodeFromUtf8,
UnknownEncoding(String),
NotFile(String),
Unknown(String),
}
impl std::error::Error for ForgeFileError {}
impl std::fmt::Display for ForgeFileError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::NotFound(file_path) => write!(f, "File not found: {file_path}"),
Self::NotFile(file_path) => write!(f, "Not a file: {file_path}"),
Self::DecodeFromBase64 => write!(f, "Unable to decode from base64"),
Self::DecodeFromUtf8 => write!(f, "Unable to decode from UTF-8"),
Self::UnknownEncoding(encoding) => write!(f, "Unknown file encoding: {encoding}"),
Self::ParseContent => write!(f, "Unable to parse file contents"),
Self::Unknown(status) => write!(f, "Unknown error (status: {status})"),
}
}
}
#[derive(Debug)]
pub enum ForgeBranchError {
NotFound(BranchName),
NoneFound,
}
impl std::error::Error for ForgeBranchError {}
impl std::fmt::Display for ForgeBranchError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::NotFound(branch_name) => write!(f, "Branch not found: {branch_name}"),
Self::NoneFound => write!(f, "Unable to find any branches"),
}
}
}

View file

@ -3,12 +3,10 @@ use git_next_git::RepoDetails;
use kxio::network::{self, Network}; use kxio::network::{self, Network};
use tracing::error; use tracing::error;
use crate::ForgeBranchError;
pub async fn get_all( pub async fn get_all(
repo_details: &RepoDetails, repo_details: &RepoDetails,
net: &Network, net: &Network,
) -> Result<Vec<BranchName>, ForgeBranchError> { ) -> Result<Vec<BranchName>, crate::branch::Error> {
let hostname = &repo_details.forge.hostname(); let hostname = &repo_details.forge.hostname();
let repo_path = &repo_details.repo_path; let repo_path = &repo_details.repo_path;
use secrecy::ExposeSecret; use secrecy::ExposeSecret;
@ -30,7 +28,7 @@ pub async fn get_all(
let result = net.get::<Vec<Branch>>(request).await; let result = net.get::<Vec<Branch>>(request).await;
let response = result.map_err(|e| { let response = result.map_err(|e| {
error!(?e, "Failed to list branches"); error!(?e, "Failed to list branches");
ForgeBranchError::NoneFound // BranchListNotAvailable crate::branch::Error::NoneFound // BranchListNotAvailable
})?; })?;
let branches = response let branches = response
.response_body() .response_body()

View file

@ -3,14 +3,12 @@ use git_next_git::RepoDetails;
use kxio::network::{self, Network}; use kxio::network::{self, Network};
use tracing::{error, warn}; use tracing::{error, warn};
use crate::ForgeFileError;
pub(super) async fn contents_get( pub(super) async fn contents_get(
repo_details: &RepoDetails, repo_details: &RepoDetails,
net: &Network, net: &Network,
branch: &BranchName, branch: &BranchName,
file_path: &str, file_path: &str,
) -> Result<String, ForgeFileError> { ) -> Result<String, crate::file::Error> {
let hostname = &repo_details.forge.hostname(); let hostname = &repo_details.forge.hostname();
let repo_path = &repo_details.repo_path; let repo_path = &repo_details.repo_path;
let api_token = &repo_details.forge.token(); let api_token = &repo_details.forge.token();
@ -33,7 +31,7 @@ pub(super) async fn contents_get(
let result = net.get::<ForgeContentsResponse>(request).await; let result = net.get::<ForgeContentsResponse>(request).await;
let response = result.map_err(|e| { let response = result.map_err(|e| {
warn!(?e, ""); warn!(?e, "");
ForgeFileError::NotFound(file_path.to_string()) crate::file::Error::NotFound(file_path.to_string())
})?; })?;
let status = response.status_code(); let status = response.status_code();
let contents = match response.response_body() { let contents = match response.response_body() {
@ -41,29 +39,30 @@ pub(super) async fn contents_get(
// we need to decode (see encoding field) the value of 'content' from the response // we need to decode (see encoding field) the value of 'content' from the response
match body.content_type { match body.content_type {
ForgeContentsType::File => decode_config(body), ForgeContentsType::File => decode_config(body),
_ => Err(ForgeFileError::NotFile(file_path.to_string())), _ => Err(crate::file::Error::NotFile(file_path.to_string())),
} }
} }
None => { None => {
error!(%status, "Failed to fetch repo config file"); error!(%status, "Failed to fetch repo config file");
Err(ForgeFileError::Unknown(status.to_string())) Err(crate::file::Error::Unknown(status.to_string()))
} }
}?; }?;
Ok(contents) Ok(contents)
} }
fn decode_config(body: ForgeContentsResponse) -> Result<String, ForgeFileError> { fn decode_config(body: ForgeContentsResponse) -> Result<String, crate::file::Error> {
use base64::Engine; use base64::Engine;
match body.encoding.as_str() { match body.encoding.as_str() {
"base64" => { "base64" => {
let decoded = base64::engine::general_purpose::STANDARD let decoded = base64::engine::general_purpose::STANDARD
.decode(body.content) .decode(body.content)
.map_err(|_| ForgeFileError::DecodeFromBase64)?; .map_err(|_| crate::file::Error::DecodeFromBase64)?;
let decoded = String::from_utf8(decoded).map_err(|_| ForgeFileError::DecodeFromUtf8)?; let decoded =
String::from_utf8(decoded).map_err(|_| crate::file::Error::DecodeFromUtf8)?;
Ok(decoded) Ok(decoded)
} }
encoding => Err(ForgeFileError::UnknownEncoding(encoding.to_string())), encoding => Err(crate::file::Error::UnknownEncoding(encoding.to_string())),
} }
} }

View file

@ -7,7 +7,7 @@ use git_next_git::{self as git, GitRef, RepoDetails, Repository};
use kxio::network::{self, Network}; use kxio::network::{self, Network};
use tracing::{error, info, warn}; use tracing::{error, info, warn};
use crate::{validation, CommitStatus, ForgeBranchError, ForgeFileError}; use crate::{validation, CommitStatus};
struct ForgeJo; struct ForgeJo;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -31,7 +31,7 @@ impl super::ForgeLike for ForgeJoEnv {
"forgejo".to_string() "forgejo".to_string()
} }
async fn branches_get_all(&self) -> Result<Vec<BranchName>, ForgeBranchError> { async fn branches_get_all(&self) -> Result<Vec<BranchName>, crate::branch::Error> {
branch::get_all(&self.repo_details, &self.net).await branch::get_all(&self.repo_details, &self.net).await
} }
@ -39,7 +39,7 @@ impl super::ForgeLike for ForgeJoEnv {
&self, &self,
branch: &BranchName, branch: &BranchName,
file_path: &str, file_path: &str,
) -> Result<String, ForgeFileError> { ) -> Result<String, crate::file::Error> {
file::contents_get(&self.repo_details, &self.net, branch, file_path).await file::contents_get(&self.repo_details, &self.net, branch, file_path).await
} }

View file

@ -16,22 +16,19 @@ mod mock_forge;
mod types; mod types;
pub use types::*; pub use types::*;
mod errors;
pub use errors::*;
#[async_trait::async_trait] #[async_trait::async_trait]
pub trait ForgeLike { pub trait ForgeLike {
fn name(&self) -> String; fn name(&self) -> String;
/// Returns a list of all branches in the repo. /// Returns a list of all branches in the repo.
async fn branches_get_all(&self) -> Result<Vec<BranchName>, ForgeBranchError>; async fn branches_get_all(&self) -> Result<Vec<BranchName>, branch::Error>;
/// Returns the contents of the file. /// Returns the contents of the file.
async fn file_contents_get( async fn file_contents_get(
&self, &self,
branch: &BranchName, branch: &BranchName,
file_path: &str, file_path: &str,
) -> Result<String, ForgeFileError>; ) -> Result<String, file::Error>;
/// Assesses the relative positions of the main, next and dev branch and updates their /// Assesses the relative positions of the main, next and dev branch and updates their
/// positions as needed. /// positions as needed.
@ -96,6 +93,38 @@ impl std::ops::Deref for Forge {
} }
} }
pub mod branch {
#[derive(Debug, derive_more::Display)]
pub enum Error {
#[display("Branch not found: {}", 0)]
NotFound(git_next_config::BranchName),
#[display("Unable to find any branches")]
NoneFound,
}
impl std::error::Error for Error {}
}
pub mod file {
#[derive(Debug, derive_more::Display)]
pub enum Error {
#[display("File not found: {}", 0)]
NotFound(String),
#[display("Unable to parse file contents")]
ParseContent,
#[display("Unable to decode from base64")]
DecodeFromBase64,
#[display("Unable to decoce from UTF-8")]
DecodeFromUtf8,
#[display("Unknown file encoding: {}", 0)]
UnknownEncoding(String),
#[display("Not a file: {}", 0)]
NotFile(String),
#[display("Unknown error (status: {})", 0)]
Unknown(String),
}
impl std::error::Error for Error {}
}
pub mod validation { pub mod validation {
use git_next_config::BranchName; use git_next_config::BranchName;
use git_next_git as git; use git_next_git as git;

View file

@ -2,7 +2,7 @@ use git::OpenRepository;
use git_next_config::{BranchName, GitDir, RepoConfig}; use git_next_config::{BranchName, GitDir, RepoConfig};
use git_next_git::{self as git, GitRef}; use git_next_git::{self as git, GitRef};
use crate::{validation, CommitStatus, ForgeBranchError, ForgeFileError}; use crate::{branch, file, validation, CommitStatus};
struct MockForge; struct MockForge;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -18,7 +18,7 @@ impl super::ForgeLike for MockForgeEnv {
"mock".to_string() "mock".to_string()
} }
async fn branches_get_all(&self) -> Result<Vec<BranchName>, ForgeBranchError> { async fn branches_get_all(&self) -> Result<Vec<BranchName>, branch::Error> {
todo!() todo!()
} }
@ -26,7 +26,7 @@ impl super::ForgeLike for MockForgeEnv {
&self, &self,
_branch: &BranchName, _branch: &BranchName,
_file_path: &str, _file_path: &str,
) -> Result<String, ForgeFileError> { ) -> Result<String, file::Error> {
todo!() todo!()
} }

View file

@ -2,7 +2,7 @@ use git_next_config::{self as config, BranchName, RepoConfig};
use git_next_git::RepoDetails; use git_next_git::RepoDetails;
use tracing::error; use tracing::error;
use crate::gitforge::{self, ForgeFileError}; use crate::gitforge;
pub async fn load(details: &RepoDetails, forge: &gitforge::Forge) -> Result<RepoConfig, Error> { pub async fn load(details: &RepoDetails, forge: &gitforge::Forge) -> Result<RepoConfig, Error> {
let contents = forge let contents = forge
@ -15,10 +15,10 @@ pub async fn load(details: &RepoDetails, forge: &gitforge::Forge) -> Result<Repo
#[derive(Debug, derive_more::From, derive_more::Display)] #[derive(Debug, derive_more::From, derive_more::Display)]
pub enum Error { pub enum Error {
File(ForgeFileError), File(gitforge::file::Error),
Config(config::server::Error), Config(config::server::Error),
Toml(toml::de::Error), Toml(toml::de::Error),
Forge(gitforge::ForgeBranchError), Forge(gitforge::branch::Error),
BranchNotFound(BranchName), BranchNotFound(BranchName),
} }