2024-04-16 22:21:55 +01:00
|
|
|
#![allow(dead_code)]
|
|
|
|
|
2024-05-18 11:41:18 +01:00
|
|
|
use git::OpenRepository;
|
2024-05-11 19:46:20 +01:00
|
|
|
use git_next_config::{BranchName, GitDir, RepoConfig};
|
2024-05-18 11:41:18 +01:00
|
|
|
use git_next_git::{self as git, GitRef, RepoDetails};
|
2024-04-16 22:21:55 +01:00
|
|
|
use kxio::network::Network;
|
|
|
|
|
|
|
|
#[cfg(feature = "forgejo")]
|
|
|
|
mod forgejo;
|
|
|
|
|
|
|
|
#[cfg(feature = "github")]
|
|
|
|
mod github;
|
|
|
|
|
|
|
|
mod mock_forge;
|
|
|
|
|
|
|
|
mod types;
|
|
|
|
pub use types::*;
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
|
pub trait ForgeLike {
|
|
|
|
fn name(&self) -> String;
|
2024-04-19 18:56:42 +01:00
|
|
|
|
|
|
|
/// Returns a list of all branches in the repo.
|
2024-05-23 08:01:16 +01:00
|
|
|
async fn branches_get_all(&self) -> Result<Vec<BranchName>, branch::Error>;
|
2024-04-19 18:56:42 +01:00
|
|
|
|
|
|
|
/// Returns the contents of the file.
|
2024-04-16 22:21:55 +01:00
|
|
|
async fn file_contents_get(
|
|
|
|
&self,
|
2024-05-11 19:46:20 +01:00
|
|
|
branch: &BranchName,
|
2024-04-16 22:21:55 +01:00
|
|
|
file_path: &str,
|
2024-05-23 08:01:16 +01:00
|
|
|
) -> Result<String, file::Error>;
|
2024-04-19 18:56:42 +01:00
|
|
|
|
|
|
|
/// Assesses the relative positions of the main, next and dev branch and updates their
|
|
|
|
/// positions as needed.
|
2024-04-16 22:21:55 +01:00
|
|
|
async fn branches_validate_positions(
|
|
|
|
&self,
|
2024-05-18 11:41:18 +01:00
|
|
|
repository: OpenRepository,
|
2024-04-16 22:21:55 +01:00
|
|
|
repo_config: RepoConfig,
|
2024-05-22 08:41:30 +01:00
|
|
|
) -> validation::Result;
|
2024-04-19 18:56:42 +01:00
|
|
|
|
|
|
|
/// Moves a branch to a new commit.
|
2024-04-16 22:21:55 +01:00
|
|
|
fn branch_reset(
|
|
|
|
&self,
|
2024-05-18 11:41:18 +01:00
|
|
|
repository: &OpenRepository,
|
2024-04-16 22:21:55 +01:00
|
|
|
branch_name: BranchName,
|
|
|
|
to_commit: GitRef,
|
2024-05-16 14:45:25 +01:00
|
|
|
force: git::push::Force,
|
|
|
|
) -> git::push::Result;
|
2024-04-16 22:21:55 +01:00
|
|
|
|
2024-04-19 18:56:42 +01:00
|
|
|
/// Checks the results of any (e.g. CI) status checks for the commit.
|
2024-05-11 19:46:20 +01:00
|
|
|
async fn commit_status(&self, commit: &git::Commit) -> CommitStatus;
|
2024-04-19 18:56:42 +01:00
|
|
|
|
|
|
|
/// Clones a repo to disk.
|
2024-05-18 11:41:18 +01:00
|
|
|
fn repo_clone(&self, gitdir: GitDir) -> Result<OpenRepository, git::repository::Error>;
|
2024-04-16 22:21:55 +01:00
|
|
|
}
|
|
|
|
|
2024-05-04 12:37:35 +01:00
|
|
|
#[derive(Clone, Debug)]
|
2024-04-16 22:21:55 +01:00
|
|
|
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")]
|
2024-05-18 11:41:18 +01:00
|
|
|
pub const fn new_forgejo(
|
|
|
|
repo_details: RepoDetails,
|
|
|
|
net: Network,
|
|
|
|
repo: git::Repository,
|
|
|
|
) -> Self {
|
|
|
|
Self::ForgeJo(forgejo::ForgeJoEnv::new(repo_details, net, repo))
|
2024-04-16 22:21:55 +01:00
|
|
|
}
|
|
|
|
#[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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-23 08:01:16 +01:00
|
|
|
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 {}
|
|
|
|
}
|
|
|
|
|
2024-05-22 08:41:30 +01:00
|
|
|
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 {}
|
|
|
|
}
|
|
|
|
|
2024-04-16 22:21:55 +01:00
|
|
|
#[cfg(test)]
|
2024-04-24 07:08:03 +01:00
|
|
|
pub mod tests;
|