git-next/crates/forge/src/lib.rs

155 lines
4.2 KiB
Rust
Raw Normal View History

#![allow(dead_code)]
use git::OpenRepository;
use git_next_config::{BranchName, GitDir, RepoConfig};
use git_next_git::{self as git, GitRef, RepoDetails};
use kxio::network::Network;
#[cfg(feature = "forgejo")]
mod forgejo;
#[cfg(feature = "github")]
mod github;
mod mock_forge;
#[async_trait::async_trait]
pub trait ForgeLike {
fn name(&self) -> String;
/// Returns a list of all branches in the repo.
async fn branches_get_all(&self) -> Result<Vec<BranchName>, branch::Error>;
/// Returns the contents of the file.
async fn file_contents_get(
&self,
branch: &BranchName,
file_path: &str,
) -> Result<String, file::Error>;
/// Assesses the relative positions of the main, next and dev branch and updates their
/// positions as needed.
async fn branches_validate_positions(
&self,
repository: OpenRepository,
repo_config: RepoConfig,
) -> validation::Result;
/// Moves a branch to a new commit.
fn branch_reset(
&self,
repository: &OpenRepository,
branch_name: BranchName,
to_commit: GitRef,
2024-05-16 14:45:25 +01:00
force: git::push::Force,
) -> git::push::Result;
/// Checks the results of any (e.g. CI) status checks for the commit.
async fn commit_status(&self, commit: &git::Commit) -> git::commit::Status;
/// Clones a repo to disk.
fn repo_clone(&self, gitdir: GitDir) -> Result<OpenRepository, git::repository::Error>;
}
#[derive(Clone, Debug)]
pub enum Forge {
Mock(mock_forge::MockForgeEnv),
#[allow(clippy::enum_variant_names)]
#[cfg(feature = "forgejo")]
ForgeJo(forgejo::ForgeJoEnv),
#[cfg(feature = "github")]
Github(github::GithubEnv),
}
impl Forge {
pub const fn new_mock() -> Self {
Self::Mock(mock_forge::MockForgeEnv::new())
}
#[cfg(feature = "forgejo")]
pub const fn new_forgejo(
repo_details: RepoDetails,
net: Network,
repo: git::Repository,
) -> Self {
Self::ForgeJo(forgejo::ForgeJoEnv::new(repo_details, net, repo))
}
#[cfg(feature = "github")]
pub const fn new_github(net: Network) -> Self {
Self::Github(github::GithubEnv::new(net))
}
}
impl std::ops::Deref for Forge {
type Target = dyn ForgeLike;
fn deref(&self) -> &Self::Target {
match self {
Self::Mock(env) => env,
#[cfg(feature = "forgejo")]
Self::ForgeJo(env) => env,
#[cfg(feature = "github")]
Forge::Github(env) => env,
}
}
}
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 {
use git_next_config::BranchName;
use git_next_git as git;
pub type Result = core::result::Result<Positions, Error>;
pub struct Positions {
pub main: git::Commit,
pub next: git::Commit,
pub dev: git::Commit,
pub dev_commit_history: Vec<git::Commit>,
}
#[derive(Debug, derive_more::Display)]
pub enum Error {
Network(Box<kxio::network::NetworkError>),
#[display("Failed to Reset Branch {branch} to {commit}")]
FailedToResetBranch {
branch: BranchName,
commit: git::Commit,
},
BranchReset(BranchName),
BranchHasNoCommits(BranchName),
DevBranchNotBasedOn(BranchName),
}
impl std::error::Error for Error {}
}
#[cfg(test)]
pub mod tests;