Compare commits
3 commits
0124b8d8c0
...
7aea70f5ee
Author | SHA1 | Date | |
---|---|---|---|
7aea70f5ee | |||
f10dc25aeb | |||
dd5532d3a3 |
30 changed files with 302 additions and 255 deletions
|
@ -7,6 +7,7 @@ members = [
|
|||
"crates/git",
|
||||
"crates/forge",
|
||||
"crates/forge-forgejo",
|
||||
"crates/forge-github",
|
||||
"crates/repo-actor",
|
||||
]
|
||||
|
||||
|
@ -26,6 +27,7 @@ git-next-config = { path = "crates/config" }
|
|||
git-next-git = { path = "crates/git" }
|
||||
git-next-forge = { path = "crates/forge" }
|
||||
git-next-forge-forgejo = { path = "crates/forge-forgejo" }
|
||||
git-next-forge-github = { path = "crates/forge-github" }
|
||||
git-next-repo-actor = { path = "crates/repo-actor" }
|
||||
|
||||
# CLI parsing
|
||||
|
|
|
@ -4,7 +4,7 @@ version = { workspace = true }
|
|||
edition = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = ["forgejo"]
|
||||
default = ["forgejo", "github"]
|
||||
forgejo = []
|
||||
github = []
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use kxio::network::{self, Network};
|
|||
pub async fn get_all(
|
||||
repo_details: &git::RepoDetails,
|
||||
net: &Network,
|
||||
) -> Result<Vec<config::BranchName>, git::branch::Error> {
|
||||
) -> git::branch::Result<Vec<config::BranchName>> {
|
||||
let hostname = &repo_details.forge.hostname();
|
||||
let repo_path = &repo_details.repo_path;
|
||||
use secrecy::ExposeSecret;
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
mod get_all;
|
||||
mod validate_positions;
|
||||
|
||||
pub use get_all::get_all;
|
||||
|
||||
pub use validate_positions::validate_positions;
|
||||
|
|
|
@ -4,6 +4,7 @@ mod file;
|
|||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use git::validation::repo::validate_repo;
|
||||
use git_next_config as config;
|
||||
use git_next_git as git;
|
||||
|
||||
|
@ -43,25 +44,6 @@ impl git::ForgeLike for ForgeJo {
|
|||
file::contents_get(&self.repo_details, &self.net, branch, file_path).await
|
||||
}
|
||||
|
||||
async fn branches_validate_positions(
|
||||
&self,
|
||||
repository: git::OpenRepository,
|
||||
repo_config: config::RepoConfig,
|
||||
) -> git::validation::Result {
|
||||
branch::validate_positions(self, &repository, repo_config)
|
||||
}
|
||||
|
||||
fn branch_reset(
|
||||
&self,
|
||||
repository: &git::OpenRepository,
|
||||
branch_name: config::BranchName,
|
||||
to_commit: git::GitRef,
|
||||
force: git::push::Force,
|
||||
) -> git::push::Result {
|
||||
repository.fetch()?;
|
||||
repository.push(&self.repo_details, branch_name, to_commit, force)
|
||||
}
|
||||
|
||||
async fn commit_status(&self, commit: &git::Commit) -> git::commit::Status {
|
||||
let repo_details = &self.repo_details;
|
||||
let hostname = &repo_details.forge.hostname();
|
||||
|
@ -117,7 +99,7 @@ impl git::ForgeLike for ForgeJo {
|
|||
self.repo.open(&gitdir)?
|
||||
};
|
||||
info!("Validating...");
|
||||
git::validate(&repository, &self.repo_details)
|
||||
validate_repo(&repository, &self.repo_details)
|
||||
.map_err(|e| git::repository::Error::Validation(e.to_string()))?;
|
||||
Ok(repository)
|
||||
}
|
||||
|
|
59
crates/forge-github/Cargo.toml
Normal file
59
crates/forge-github/Cargo.toml
Normal file
|
@ -0,0 +1,59 @@
|
|||
[package]
|
||||
name = "git-next-forge-github"
|
||||
version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
git-next-config = { workspace = true }
|
||||
git-next-git = { workspace = true }
|
||||
|
||||
# logging
|
||||
console-subscriber = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
|
||||
# base64 decoding
|
||||
base64 = { workspace = true }
|
||||
|
||||
# git
|
||||
async-trait = { workspace = true }
|
||||
|
||||
# fs/network
|
||||
kxio = { workspace = true }
|
||||
|
||||
# TOML parsing
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
toml = { workspace = true }
|
||||
|
||||
# Secrets and Password
|
||||
secrecy = { workspace = true }
|
||||
|
||||
# Conventional Commit check
|
||||
git-conventional = { workspace = true }
|
||||
|
||||
# Webhooks
|
||||
bytes = { workspace = true }
|
||||
ulid = { workspace = true }
|
||||
warp = { workspace = true }
|
||||
|
||||
# boilerplate
|
||||
derive_more = { workspace = true }
|
||||
|
||||
# file watcher
|
||||
inotify = { workspace = true }
|
||||
|
||||
# # Actors
|
||||
# actix = { workspace = true }
|
||||
# actix-rt = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
# Testing
|
||||
assert2 = { workspace = true }
|
||||
|
||||
[lints.clippy]
|
||||
nursery = { level = "warn", priority = -1 }
|
||||
# pedantic = "warn"
|
||||
unwrap_used = "warn"
|
||||
expect_used = "warn"
|
47
crates/forge-github/src/lib.rs
Normal file
47
crates/forge-github/src/lib.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
#![allow(dead_code)]
|
||||
|
||||
use derive_more::Constructor;
|
||||
use git_next_config as config;
|
||||
use git_next_git as git;
|
||||
|
||||
use kxio::network::Network;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[derive(Clone, Debug, Constructor)]
|
||||
pub struct Github {
|
||||
net: Network,
|
||||
}
|
||||
#[async_trait::async_trait]
|
||||
impl git_next_git::ForgeLike for Github {
|
||||
fn name(&self) -> String {
|
||||
"github".to_string()
|
||||
}
|
||||
async fn branches_get_all(&self) -> Result<Vec<config::BranchName>, git::branch::Error> {
|
||||
todo!();
|
||||
}
|
||||
|
||||
/// Returns the contents of the file.
|
||||
async fn file_contents_get(
|
||||
&self,
|
||||
_branch_name: &config::BranchName,
|
||||
_file_path: &str,
|
||||
) -> Result<String, git::file::Error> {
|
||||
todo!();
|
||||
}
|
||||
|
||||
/// Checks the results of any (e.g. CI) status checks for the commit.
|
||||
async fn commit_status(&self, _commit: &git::Commit) -> git::commit::Status {
|
||||
todo!();
|
||||
}
|
||||
|
||||
/// Clones a repo to disk.
|
||||
fn repo_clone(
|
||||
&self,
|
||||
_gitdir: config::GitDir,
|
||||
) -> Result<git::OpenRepository, git::repository::Error> {
|
||||
todo!();
|
||||
}
|
||||
}
|
8
crates/forge-github/src/tests/mod.rs
Normal file
8
crates/forge-github/src/tests/mod.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
use git_next_git::ForgeLike as _;
|
||||
|
||||
#[test]
|
||||
fn test_name() {
|
||||
let net = kxio::network::Network::new_mock();
|
||||
let forge = crate::Github::new(net);
|
||||
assert_eq!(forge.name(), "github");
|
||||
}
|
|
@ -4,14 +4,15 @@ version = { workspace = true }
|
|||
edition = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = ["forgejo"]
|
||||
default = ["forgejo", "github"]
|
||||
forgejo = ["git-next-forge-forgejo"]
|
||||
github = []
|
||||
github = ["git-next-forge-github"]
|
||||
|
||||
[dependencies]
|
||||
git-next-config = { workspace = true }
|
||||
git-next-git = { workspace = true }
|
||||
git-next-forge-forgejo = { workspace = true, optional = true }
|
||||
git-next-forge-github = { workspace = true, optional = true }
|
||||
|
||||
# logging
|
||||
console-subscriber = { workspace = true }
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
use crate::network::Network;
|
||||
|
||||
struct Github;
|
||||
pub(super) struct GithubEnv {
|
||||
net: Network,
|
||||
}
|
||||
impl GithubEnv {
|
||||
pub(crate) const fn new(net: Network) -> GithubEnv {
|
||||
Self { net }
|
||||
}
|
||||
}
|
||||
#[async_trait::async_trait]
|
||||
impl super::ForgeLike for GithubEnv {
|
||||
fn name(&self) -> String {
|
||||
"github".to_string()
|
||||
}
|
||||
|
||||
async fn branches_get_all(&self) -> Vec<super::Branch> {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -1,27 +1,26 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
//
|
||||
use git_next_forge_forgejo as forgejo;
|
||||
use git_next_forge_github as github;
|
||||
use git_next_git as git;
|
||||
use kxio::network::Network;
|
||||
|
||||
#[cfg(feature = "github")]
|
||||
mod github;
|
||||
|
||||
mod mock_forge;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Forge {
|
||||
Mock(mock_forge::MockForgeEnv),
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
Mock(mock_forge::MockForge),
|
||||
|
||||
#[cfg(feature = "forgejo")]
|
||||
ForgeJo(forgejo::ForgeJo),
|
||||
ForgeJo(git_next_forge_forgejo::ForgeJo),
|
||||
|
||||
#[cfg(feature = "github")]
|
||||
Github(github::GithubEnv),
|
||||
Github(git_next_forge_github::Github),
|
||||
}
|
||||
impl Forge {
|
||||
pub const fn new_mock() -> Self {
|
||||
Self::Mock(mock_forge::MockForgeEnv::new())
|
||||
Self::Mock(mock_forge::MockForge::new())
|
||||
}
|
||||
|
||||
#[cfg(feature = "forgejo")]
|
||||
pub const fn new_forgejo(
|
||||
repo_details: git::RepoDetails,
|
||||
|
@ -30,9 +29,10 @@ impl Forge {
|
|||
) -> Self {
|
||||
Self::ForgeJo(forgejo::ForgeJo::new(repo_details, net, repo))
|
||||
}
|
||||
|
||||
#[cfg(feature = "github")]
|
||||
pub const fn new_github(net: Network) -> Self {
|
||||
Self::Github(github::GithubEnv::new(net))
|
||||
Self::Github(github::Github::new(net))
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Forge {
|
||||
|
@ -43,7 +43,7 @@ impl std::ops::Deref for Forge {
|
|||
#[cfg(feature = "forgejo")]
|
||||
Self::ForgeJo(env) => env,
|
||||
#[cfg(feature = "github")]
|
||||
Forge::Github(env) => env,
|
||||
Self::Github(env) => env,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
//
|
||||
#![cfg(not(tarpaulin_include))]
|
||||
|
||||
use derive_more::Constructor;
|
||||
use git::OpenRepository;
|
||||
use git_next_config as config;
|
||||
use git_next_git as git;
|
||||
|
||||
struct MockForge;
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MockForgeEnv;
|
||||
impl MockForgeEnv {
|
||||
pub(crate) const fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Debug, Constructor)]
|
||||
pub struct MockForge;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl git::ForgeLike for MockForgeEnv {
|
||||
impl git::ForgeLike for MockForge {
|
||||
fn name(&self) -> String {
|
||||
"mock".to_string()
|
||||
}
|
||||
|
@ -31,24 +27,6 @@ impl git::ForgeLike for MockForgeEnv {
|
|||
todo!()
|
||||
}
|
||||
|
||||
async fn branches_validate_positions(
|
||||
&self,
|
||||
_repository: git::OpenRepository,
|
||||
_repo_config: config::RepoConfig,
|
||||
) -> git::validation::Result {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn branch_reset(
|
||||
&self,
|
||||
_repository: &git::OpenRepository,
|
||||
_branch_name: config::BranchName,
|
||||
_to_commit: git::GitRef,
|
||||
_force: git::push::Force,
|
||||
) -> git::push::Result {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn commit_status(&self, _commit: &git::Commit) -> git::commit::Status {
|
||||
todo!()
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_name() {
|
||||
let net = Network::new_mock();
|
||||
let forge = Forge::new_github(net);
|
||||
assert_eq!(forge.name(), "github");
|
||||
}
|
|
@ -4,9 +4,6 @@ use super::*;
|
|||
use git_next_config as config;
|
||||
use git_next_git as git;
|
||||
|
||||
#[cfg(feature = "github")]
|
||||
mod github;
|
||||
|
||||
#[test]
|
||||
fn test_mock_name() {
|
||||
let forge = Forge::new_mock();
|
||||
|
|
|
@ -1,6 +1,26 @@
|
|||
//
|
||||
use crate as git;
|
||||
use git_next_config as config;
|
||||
|
||||
pub type Result<T> = core::result::Result<T, Error>;
|
||||
|
||||
#[derive(Debug, derive_more::Display, derive_more::From)]
|
||||
pub enum Error {
|
||||
#[display("network: {}", 0)]
|
||||
Network(kxio::network::NetworkError),
|
||||
|
||||
Fetch(git::fetch::Error),
|
||||
|
||||
Push(git::push::Error),
|
||||
}
|
||||
impl std::error::Error for Error {}
|
||||
|
||||
pub fn reset(
|
||||
repository: &git::OpenRepository,
|
||||
repo_details: &git::RepoDetails,
|
||||
branch_name: config::BranchName,
|
||||
to_commit: git::GitRef,
|
||||
force: git::push::Force,
|
||||
) -> Result<()> {
|
||||
repository.fetch()?;
|
||||
Ok(repository.push(repo_details, branch_name, to_commit, force)?)
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ pub struct Histories {
|
|||
pub mod log {
|
||||
use derive_more::{Display, From};
|
||||
|
||||
pub type Result<T> = core::result::Result<T, Error>;
|
||||
|
||||
#[derive(Debug, Display, From)]
|
||||
pub enum Error {
|
||||
Gix(String),
|
||||
|
|
|
@ -15,23 +15,6 @@ pub trait ForgeLike {
|
|||
file_path: &str,
|
||||
) -> Result<String, git::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: git::OpenRepository,
|
||||
repo_config: config::RepoConfig,
|
||||
) -> git::validation::Result;
|
||||
|
||||
/// Moves a branch to a new commit.
|
||||
fn branch_reset(
|
||||
&self,
|
||||
repository: &git::OpenRepository,
|
||||
branch_name: config::BranchName,
|
||||
to_commit: git::GitRef,
|
||||
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;
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ mod git_remote;
|
|||
pub mod push;
|
||||
mod repo_details;
|
||||
pub mod repository;
|
||||
pub mod validate;
|
||||
pub mod validation;
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -25,4 +24,3 @@ pub use git_remote::GitRemote;
|
|||
pub use repo_details::RepoDetails;
|
||||
pub use repository::OpenRepository;
|
||||
pub use repository::Repository;
|
||||
pub use validate::validate;
|
||||
|
|
|
@ -17,7 +17,6 @@ impl std::fmt::Display for Force {
|
|||
#[derive(Debug, derive_more::From, derive_more::Display)]
|
||||
pub enum Error {
|
||||
Open(Box<gix::open::Error>),
|
||||
Fetch(super::fetch::Error),
|
||||
Push,
|
||||
Lock,
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
mod validate {
|
||||
|
||||
use assert2::let_assert;
|
||||
use git_next_config::{ForgeDetails, GitDir, Hostname, RepoPath};
|
||||
|
||||
use crate::{
|
||||
repository::{self, Direction},
|
||||
validate, GitRemote, RepoDetails,
|
||||
repository,
|
||||
validation::{self, repo::validate_repo},
|
||||
GitRemote, RepoDetails,
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
@ -27,8 +29,9 @@ mod validate {
|
|||
|open_repo| {
|
||||
let_assert!(
|
||||
Ok(_) = open_repo.lock().map(|mut open_repo| {
|
||||
open_repo.has_default_remote(Direction::Push, remote.clone());
|
||||
open_repo.has_default_remote(Direction::Fetch, remote);
|
||||
open_repo
|
||||
.has_default_remote(repository::Direction::Push, remote.clone());
|
||||
open_repo.has_default_remote(repository::Direction::Fetch, remote);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -37,7 +40,7 @@ mod validate {
|
|||
|
||||
let_assert!(Ok(open_repository) = repository.open(&gitdir));
|
||||
|
||||
let_assert!(Ok(_) = validate(&open_repository, &repo_details));
|
||||
let_assert!(Ok(_) = validation::repo::validate_repo(&open_repository, &repo_details));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -61,7 +64,7 @@ mod validate {
|
|||
let_assert!(
|
||||
Ok(_) = open_repo.lock().map(|mut open_repo| {
|
||||
// INFO: open_repo.has_default_remote(Direction::Push, remote.clone());
|
||||
open_repo.has_default_remote(Direction::Fetch, remote);
|
||||
open_repo.has_default_remote(repository::Direction::Fetch, remote);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -70,7 +73,7 @@ mod validate {
|
|||
|
||||
let_assert!(Ok(open_repository) = repository.open(&gitdir));
|
||||
|
||||
let_assert!(Err(_) = validate(&open_repository, &repo_details));
|
||||
let_assert!(Err(_) = validate_repo(&open_repository, &repo_details));
|
||||
}
|
||||
#[test]
|
||||
fn should_fail_where_no_default_fetch_remote() {
|
||||
|
@ -92,7 +95,7 @@ mod validate {
|
|||
|open_repo| {
|
||||
let_assert!(
|
||||
Ok(_) = open_repo.lock().map(|mut open_repo| {
|
||||
open_repo.has_default_remote(Direction::Push, remote);
|
||||
open_repo.has_default_remote(repository::Direction::Push, remote);
|
||||
// INFO: open_repo.has_default_remote(Direction::Fetch, remote);
|
||||
})
|
||||
);
|
||||
|
@ -102,7 +105,7 @@ mod validate {
|
|||
|
||||
let_assert!(Ok(open_repository) = repository.open(&gitdir));
|
||||
|
||||
let_assert!(Err(_) = validate(&open_repository, &repo_details));
|
||||
let_assert!(Err(_) = validate_repo(&open_repository, &repo_details));
|
||||
}
|
||||
#[test]
|
||||
fn should_fail_where_invalid_default_push_remote() {
|
||||
|
@ -128,8 +131,8 @@ mod validate {
|
|||
|open_repo| {
|
||||
let_assert!(
|
||||
Ok(_) = open_repo.lock().map(|mut open_repo| {
|
||||
open_repo.has_default_remote(Direction::Push, other_remote);
|
||||
open_repo.has_default_remote(Direction::Fetch, remote);
|
||||
open_repo.has_default_remote(repository::Direction::Push, other_remote);
|
||||
open_repo.has_default_remote(repository::Direction::Fetch, remote);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -138,7 +141,7 @@ mod validate {
|
|||
|
||||
let_assert!(Ok(open_repository) = repository.open(&gitdir));
|
||||
|
||||
let_assert!(Err(_) = validate(&open_repository, &repo_details));
|
||||
let_assert!(Err(_) = validate_repo(&open_repository, &repo_details));
|
||||
}
|
||||
#[test]
|
||||
fn should_fail_where_invalid_default_fetch_remote() {
|
||||
|
@ -164,8 +167,9 @@ mod validate {
|
|||
|open_repo| {
|
||||
let_assert!(
|
||||
Ok(_) = open_repo.lock().map(|mut open_repo| {
|
||||
open_repo.has_default_remote(Direction::Push, remote);
|
||||
open_repo.has_default_remote(Direction::Fetch, other_remote);
|
||||
open_repo.has_default_remote(repository::Direction::Push, remote);
|
||||
open_repo
|
||||
.has_default_remote(repository::Direction::Fetch, other_remote);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -174,7 +178,7 @@ mod validate {
|
|||
|
||||
let_assert!(Ok(open_repository) = repository.open(&gitdir));
|
||||
|
||||
let_assert!(Err(_) = validate(&open_repository, &repo_details));
|
||||
let_assert!(Err(_) = validate_repo(&open_repository, &repo_details));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,7 +186,7 @@ mod git_clone {
|
|||
use assert2::let_assert;
|
||||
use git_next_config::{ForgeDetails, GitDir, Hostname, RepoPath};
|
||||
|
||||
use crate::{repository::Direction, GitRemote, RepoDetails};
|
||||
use crate::{repository, GitRemote, RepoDetails};
|
||||
|
||||
#[test]
|
||||
fn should_clone_repo() {
|
||||
|
@ -195,7 +199,7 @@ mod git_clone {
|
|||
.with_gitdir(GitDir::new(fs.base()))
|
||||
.with_repo_path(RepoPath::new("kemitix/git-next".to_string()));
|
||||
let_assert!(Ok(open_repo) = r.git_clone(&repo_details));
|
||||
let_assert!(Some(remote) = open_repo.find_default_remote(Direction::Fetch));
|
||||
let_assert!(Some(remote) = open_repo.find_default_remote(repository::Direction::Fetch));
|
||||
assert_eq!(
|
||||
remote,
|
||||
GitRemote::new(
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
use crate as git;
|
||||
use git_next_config::BranchName;
|
||||
|
||||
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 {
|
||||
Fetch(git::fetch::Error),
|
||||
|
||||
CommitLog(git::commit::log::Error),
|
||||
|
||||
#[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 {}
|
||||
|
||||
impl From<git::fetch::Error> for Error {
|
||||
fn from(value: git::fetch::Error) -> Self {
|
||||
Self::Fetch(value)
|
||||
}
|
||||
}
|
2
crates/git/src/validation/mod.rs
Normal file
2
crates/git/src/validation/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
pub mod positions;
|
||||
pub mod repo;
|
|
@ -1,17 +1,24 @@
|
|||
//
|
||||
use crate as forgejo;
|
||||
use git::ForgeLike as _;
|
||||
use crate as git;
|
||||
use git_next_config as config;
|
||||
use git_next_git as git;
|
||||
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
||||
pub type Result<T> = core::result::Result<T, Error>;
|
||||
|
||||
pub struct Positions {
|
||||
pub main: git::Commit,
|
||||
pub next: git::Commit,
|
||||
pub dev: git::Commit,
|
||||
pub dev_commit_history: Vec<git::Commit>,
|
||||
}
|
||||
|
||||
#[allow(clippy::cognitive_complexity)] // TODO: (#83) reduce complexity
|
||||
pub fn validate_positions(
|
||||
forge: &forgejo::ForgeJo,
|
||||
repository: &git::OpenRepository,
|
||||
repo_details: &git::RepoDetails,
|
||||
repo_config: config::RepoConfig,
|
||||
) -> git::validation::Result {
|
||||
) -> Result<Positions> {
|
||||
// Collect Commit Histories for `main`, `next` and `dev` branches
|
||||
repository.fetch()?;
|
||||
let commit_histories = get_commit_histories(repository, &repo_config);
|
||||
|
@ -19,7 +26,7 @@ pub fn validate_positions(
|
|||
Ok(commit_histories) => commit_histories,
|
||||
Err(err) => {
|
||||
error!(?err, "Failed to get commit histories");
|
||||
return Err(git::validation::Error::CommitLog(err));
|
||||
return Err(git::validation::positions::Error::CommitLog(err));
|
||||
}
|
||||
};
|
||||
// Validations
|
||||
|
@ -28,7 +35,7 @@ pub fn validate_positions(
|
|||
"No commits on main branch '{}'",
|
||||
repo_config.branches().main()
|
||||
);
|
||||
return Err(git::validation::Error::BranchHasNoCommits(
|
||||
return Err(git::validation::positions::Error::BranchHasNoCommits(
|
||||
repo_config.branches().main(),
|
||||
));
|
||||
};
|
||||
|
@ -41,7 +48,7 @@ pub fn validate_positions(
|
|||
repo_config.branches().main(),
|
||||
repo_config.branches().main(),
|
||||
);
|
||||
return Err(git::validation::Error::DevBranchNotBasedOn(
|
||||
return Err(git::validation::positions::Error::DevBranchNotBasedOn(
|
||||
repo_config.branches().main(),
|
||||
));
|
||||
}
|
||||
|
@ -51,26 +58,27 @@ pub fn validate_positions(
|
|||
"No commits on next branch '{}",
|
||||
repo_config.branches().next()
|
||||
);
|
||||
return Err(git::validation::Error::BranchHasNoCommits(
|
||||
return Err(git::validation::positions::Error::BranchHasNoCommits(
|
||||
repo_config.branches().next(),
|
||||
));
|
||||
};
|
||||
let next_is_ancestor_of_dev = commit_histories.dev.iter().any(|dev| dev == &next);
|
||||
if !next_is_ancestor_of_dev {
|
||||
info!("Next is not an ancestor of dev - resetting next to main");
|
||||
if let Err(err) = forge.branch_reset(
|
||||
if let Err(err) = git::branch::reset(
|
||||
repository,
|
||||
repo_details,
|
||||
repo_config.branches().next(),
|
||||
main.into(),
|
||||
git::push::Force::From(next.clone().into()),
|
||||
) {
|
||||
warn!(?err, "Failed to reset next to main");
|
||||
return Err(git::validation::Error::FailedToResetBranch {
|
||||
return Err(git::validation::positions::Error::FailedToResetBranch {
|
||||
branch: repo_config.branches().next(),
|
||||
commit: next,
|
||||
});
|
||||
}
|
||||
return Err(git::validation::Error::BranchReset(
|
||||
return Err(git::validation::positions::Error::BranchReset(
|
||||
repo_config.branches().next(),
|
||||
));
|
||||
}
|
||||
|
@ -87,19 +95,20 @@ pub fn validate_positions(
|
|||
repo_config.branches().main(),
|
||||
repo_config.branches().next()
|
||||
);
|
||||
if let Err(err) = forge.branch_reset(
|
||||
if let Err(err) = git::branch::reset(
|
||||
repository,
|
||||
repo_details,
|
||||
repo_config.branches().next(),
|
||||
main.into(),
|
||||
git::push::Force::From(next.clone().into()),
|
||||
) {
|
||||
warn!(?err, "Failed to reset next to main");
|
||||
return Err(git::validation::Error::FailedToResetBranch {
|
||||
return Err(git::validation::positions::Error::FailedToResetBranch {
|
||||
branch: repo_config.branches().next(),
|
||||
commit: next,
|
||||
});
|
||||
}
|
||||
return Err(git::validation::Error::BranchReset(
|
||||
return Err(git::validation::positions::Error::BranchReset(
|
||||
repo_config.branches().next(),
|
||||
));
|
||||
}
|
||||
|
@ -108,7 +117,7 @@ pub fn validate_positions(
|
|||
"No commits on next branch '{}'",
|
||||
repo_config.branches().next()
|
||||
);
|
||||
return Err(git::validation::Error::BranchHasNoCommits(
|
||||
return Err(git::validation::positions::Error::BranchHasNoCommits(
|
||||
repo_config.branches().next(),
|
||||
));
|
||||
};
|
||||
|
@ -122,7 +131,7 @@ pub fn validate_positions(
|
|||
repo_config.branches().dev(),
|
||||
repo_config.branches().next()
|
||||
);
|
||||
return Err(git::validation::Error::DevBranchNotBasedOn(
|
||||
return Err(git::validation::positions::Error::DevBranchNotBasedOn(
|
||||
repo_config.branches().next(),
|
||||
)); // dev is not based on next
|
||||
}
|
||||
|
@ -131,11 +140,11 @@ pub fn validate_positions(
|
|||
"No commits on dev branch '{}'",
|
||||
repo_config.branches().dev()
|
||||
);
|
||||
return Err(git::validation::Error::BranchHasNoCommits(
|
||||
return Err(git::validation::positions::Error::BranchHasNoCommits(
|
||||
repo_config.branches().dev(),
|
||||
));
|
||||
};
|
||||
Ok(git::validation::Positions {
|
||||
Ok(git::validation::positions::Positions {
|
||||
main,
|
||||
next,
|
||||
dev,
|
||||
|
@ -146,7 +155,7 @@ pub fn validate_positions(
|
|||
fn get_commit_histories(
|
||||
repository: &git::repository::OpenRepository,
|
||||
repo_config: &config::RepoConfig,
|
||||
) -> Result<git::commit::Histories, git::commit::log::Error> {
|
||||
) -> git::commit::log::Result<git::commit::Histories> {
|
||||
let main = (repository.commit_log(&repo_config.branches().main(), &[]))?;
|
||||
let main_head = [main[0].clone()];
|
||||
let next = repository.commit_log(&repo_config.branches().next(), &main_head)?;
|
||||
|
@ -160,3 +169,28 @@ fn get_commit_histories(
|
|||
let histories = git::commit::Histories { main, next, dev };
|
||||
Ok(histories)
|
||||
}
|
||||
#[derive(Debug, derive_more::Display)]
|
||||
pub enum Error {
|
||||
Fetch(git::fetch::Error),
|
||||
|
||||
CommitLog(git::commit::log::Error),
|
||||
|
||||
#[display("Failed to Reset Branch {branch} to {commit}")]
|
||||
FailedToResetBranch {
|
||||
branch: config::BranchName,
|
||||
commit: git::Commit,
|
||||
},
|
||||
|
||||
BranchReset(config::BranchName),
|
||||
|
||||
BranchHasNoCommits(config::BranchName),
|
||||
|
||||
DevBranchNotBasedOn(config::BranchName),
|
||||
}
|
||||
impl std::error::Error for Error {}
|
||||
|
||||
impl From<git::fetch::Error> for Error {
|
||||
fn from(value: git::fetch::Error) -> Self {
|
||||
Self::Fetch(value)
|
||||
}
|
||||
}
|
|
@ -1,15 +1,17 @@
|
|||
use tracing::info;
|
||||
|
||||
use crate::repository::{Direction, OpenRepository};
|
||||
|
||||
use super::{GitRemote, RepoDetails};
|
||||
use crate as git;
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn validate(repository: &OpenRepository, repo_details: &RepoDetails) -> Result<()> {
|
||||
let Some(push_remote) = repository.find_default_remote(Direction::Push) else {
|
||||
pub fn validate_repo(
|
||||
repository: &git::OpenRepository,
|
||||
repo_details: &git::RepoDetails,
|
||||
) -> Result<()> {
|
||||
let Some(push_remote) = repository.find_default_remote(git::repository::Direction::Push) else {
|
||||
return Err(Error::NoDefaultPushRemote);
|
||||
};
|
||||
let Some(fetch_remote) = repository.find_default_remote(Direction::Fetch) else {
|
||||
let Some(fetch_remote) = repository.find_default_remote(git::repository::Direction::Fetch)
|
||||
else {
|
||||
return Err(Error::NoDefaultFetchRemote);
|
||||
};
|
||||
let git_remote = repo_details.git_remote();
|
||||
|
@ -40,13 +42,13 @@ pub enum Error {
|
|||
Io(std::io::Error),
|
||||
#[display("MismatchDefaultPushRemote(found: {found}, expected: {expected})")]
|
||||
MismatchDefaultPushRemote {
|
||||
found: GitRemote,
|
||||
expected: GitRemote,
|
||||
found: git::GitRemote,
|
||||
expected: git::GitRemote,
|
||||
},
|
||||
#[display("MismatchDefaultFetchRemote(found: {found}, expected: {expected})")]
|
||||
MismatchDefaultFetchRemote {
|
||||
found: GitRemote,
|
||||
expected: GitRemote,
|
||||
found: git::GitRemote,
|
||||
expected: git::GitRemote,
|
||||
},
|
||||
}
|
||||
impl std::error::Error for Error {}
|
|
@ -4,7 +4,7 @@ version = { workspace = true }
|
|||
edition = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = ["forgejo"]
|
||||
default = ["forgejo", "github"]
|
||||
forgejo = []
|
||||
github = []
|
||||
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
use std::time::Duration;
|
||||
|
||||
//
|
||||
use actix::prelude::*;
|
||||
|
||||
use git_next_config as config;
|
||||
use git_next_forge as forge;
|
||||
use git_next_git as git;
|
||||
use tracing::{info, warn};
|
||||
|
||||
use crate::{MessageToken, ValidateRepo};
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
// advance next to the next commit towards the head of the dev branch
|
||||
#[tracing::instrument(fields(next), skip_all)]
|
||||
pub async fn advance_next(
|
||||
next: git::Commit,
|
||||
dev_commit_history: Vec<git::Commit>,
|
||||
repo_details: git::RepoDetails,
|
||||
repo_config: config::RepoConfig,
|
||||
forge: forge::Forge,
|
||||
repository: git::OpenRepository,
|
||||
addr: Addr<super::RepoActor>,
|
||||
message_token: MessageToken,
|
||||
|
@ -30,8 +30,9 @@ pub async fn advance_next(
|
|||
return;
|
||||
}
|
||||
info!("Advancing next to commit '{}'", commit);
|
||||
if let Err(err) = forge.branch_reset(
|
||||
if let Err(err) = git::branch::reset(
|
||||
&repository,
|
||||
&repo_details,
|
||||
repo_config.branches().next(),
|
||||
commit.into(),
|
||||
git::push::Force::No,
|
||||
|
@ -78,13 +79,14 @@ pub fn find_next_commit_on_dev(
|
|||
#[tracing::instrument(fields(next), skip_all)]
|
||||
pub async fn advance_main(
|
||||
next: git::Commit,
|
||||
repo_details: &git::RepoDetails,
|
||||
repo_config: &config::RepoConfig,
|
||||
forge: &forge::Forge,
|
||||
repository: &git::OpenRepository,
|
||||
) {
|
||||
info!("Advancing main to next");
|
||||
if let Err(err) = forge.branch_reset(
|
||||
if let Err(err) = git::branch::reset(
|
||||
repository,
|
||||
repo_details,
|
||||
repo_config.branches().main(),
|
||||
next.into(),
|
||||
git::push::Force::No,
|
||||
|
|
|
@ -9,6 +9,7 @@ mod tests;
|
|||
use std::time::Duration;
|
||||
|
||||
use actix::prelude::*;
|
||||
use git::validation::positions::{validate_positions, Positions};
|
||||
|
||||
use crate as repo_actor;
|
||||
use git_next_config as config;
|
||||
|
@ -19,11 +20,11 @@ use kxio::network::Network;
|
|||
use tracing::{debug, info, warn, Instrument};
|
||||
|
||||
#[derive(Debug, derive_more::Display)]
|
||||
#[display("{}:{}:{}", generation, details.forge.forge_name(), details.repo_alias)]
|
||||
#[display("{}:{}:{}", generation, repo_details.forge.forge_name(), repo_details.repo_alias)]
|
||||
pub struct RepoActor {
|
||||
generation: git::Generation,
|
||||
message_token: MessageToken,
|
||||
details: git::RepoDetails,
|
||||
repo_details: git::RepoDetails,
|
||||
webhook: config::server::Webhook,
|
||||
webhook_id: Option<webhook::WebhookId>, // INFO: if [None] then no webhook is configured
|
||||
webhook_auth: Option<webhook::WebhookAuth>, // INFO: if [None] then no webhook is configured
|
||||
|
@ -53,7 +54,7 @@ impl RepoActor {
|
|||
Self {
|
||||
generation,
|
||||
message_token: MessageToken::new(),
|
||||
details,
|
||||
repo_details: details,
|
||||
webhook,
|
||||
webhook_id: None,
|
||||
webhook_auth: None,
|
||||
|
@ -68,12 +69,12 @@ impl RepoActor {
|
|||
}
|
||||
impl Actor for RepoActor {
|
||||
type Context = Context<Self>;
|
||||
#[tracing::instrument(name = "RepoActor::stopping", skip_all, fields(repo = %self.details))]
|
||||
#[tracing::instrument(name = "RepoActor::stopping", skip_all, fields(repo = %self.repo_details))]
|
||||
fn stopping(&mut self, ctx: &mut Self::Context) -> Running {
|
||||
info!("Checking webhook");
|
||||
match self.webhook_id.take() {
|
||||
Some(webhook_id) => {
|
||||
let repo_details = self.details.clone();
|
||||
let repo_details = self.repo_details.clone();
|
||||
let net = self.net.clone();
|
||||
info!(%webhook_id, "Unregistring webhook");
|
||||
webhook::unregister(webhook_id, repo_details, net)
|
||||
|
@ -92,13 +93,13 @@ impl Actor for RepoActor {
|
|||
pub struct CloneRepo;
|
||||
impl Handler<CloneRepo> for RepoActor {
|
||||
type Result = ();
|
||||
#[tracing::instrument(name = "RepoActor::CloneRepo", skip_all, fields(repo = %self.details, gitdir = %self.details.gitdir))]
|
||||
#[tracing::instrument(name = "RepoActor::CloneRepo", skip_all, fields(repo = %self.repo_details, gitdir = %self.repo_details.gitdir))]
|
||||
fn handle(&mut self, _msg: CloneRepo, ctx: &mut Self::Context) -> Self::Result {
|
||||
let gitdir = self.details.gitdir.clone();
|
||||
let gitdir = self.repo_details.gitdir.clone();
|
||||
match self.forge.repo_clone(gitdir) {
|
||||
Ok(repository) => {
|
||||
self.repository.replace(repository);
|
||||
if self.details.repo_config.is_none() {
|
||||
if self.repo_details.repo_config.is_none() {
|
||||
ctx.address().do_send(LoadConfigFromRepo);
|
||||
} else {
|
||||
ctx.address().do_send(ValidateRepo {
|
||||
|
@ -116,9 +117,9 @@ impl Handler<CloneRepo> for RepoActor {
|
|||
pub struct LoadConfigFromRepo;
|
||||
impl Handler<LoadConfigFromRepo> for RepoActor {
|
||||
type Result = ();
|
||||
#[tracing::instrument(name = "RepoActor::LoadConfigFromRepo", skip_all, fields(repo = %self.details))]
|
||||
#[tracing::instrument(name = "RepoActor::LoadConfigFromRepo", skip_all, fields(repo = %self.repo_details))]
|
||||
fn handle(&mut self, _msg: LoadConfigFromRepo, ctx: &mut Self::Context) -> Self::Result {
|
||||
let details = self.details.clone();
|
||||
let details = self.repo_details.clone();
|
||||
let addr = ctx.address();
|
||||
let forge = self.forge.clone();
|
||||
repo_actor::load::load_file(details, addr, forge)
|
||||
|
@ -133,10 +134,10 @@ impl Handler<LoadConfigFromRepo> for RepoActor {
|
|||
struct LoadedConfig(git_next_config::RepoConfig);
|
||||
impl Handler<LoadedConfig> for RepoActor {
|
||||
type Result = ();
|
||||
#[tracing::instrument(name = "RepoActor::LoadedConfig", skip_all, fields(repo = %self.details, branches = %msg.0))]
|
||||
#[tracing::instrument(name = "RepoActor::LoadedConfig", skip_all, fields(repo = %self.repo_details, branches = %msg.0))]
|
||||
fn handle(&mut self, msg: LoadedConfig, ctx: &mut Self::Context) -> Self::Result {
|
||||
let repo_config = msg.0;
|
||||
self.details.repo_config.replace(repo_config);
|
||||
self.repo_details.repo_config.replace(repo_config);
|
||||
|
||||
ctx.address().do_send(ValidateRepo {
|
||||
message_token: self.message_token,
|
||||
|
@ -151,7 +152,7 @@ pub struct ValidateRepo {
|
|||
}
|
||||
impl Handler<ValidateRepo> for RepoActor {
|
||||
type Result = ();
|
||||
#[tracing::instrument(name = "RepoActor::ValidateRepo", skip_all, fields(repo = %self.details, token = %msg.message_token))]
|
||||
#[tracing::instrument(name = "RepoActor::ValidateRepo", skip_all, fields(repo = %self.repo_details, token = %msg.message_token))]
|
||||
fn handle(&mut self, msg: ValidateRepo, ctx: &mut Self::Context) -> Self::Result {
|
||||
match msg.message_token {
|
||||
message_token if self.message_token < message_token => {
|
||||
|
@ -168,7 +169,7 @@ impl Handler<ValidateRepo> for RepoActor {
|
|||
}
|
||||
if self.webhook_id.is_none() {
|
||||
webhook::register(
|
||||
self.details.clone(),
|
||||
self.repo_details.clone(),
|
||||
self.webhook.clone(),
|
||||
ctx.address(),
|
||||
self.net.clone(),
|
||||
|
@ -177,18 +178,16 @@ impl Handler<ValidateRepo> for RepoActor {
|
|||
.into_actor(self)
|
||||
.wait(ctx);
|
||||
}
|
||||
if let (Some(repository), Some(repo_config)) =
|
||||
(self.repository.clone(), self.details.repo_config.clone())
|
||||
{
|
||||
let forge = self.forge.clone();
|
||||
if let (Some(repository), Some(repo_config)) = (
|
||||
self.repository.clone(),
|
||||
self.repo_details.repo_config.clone(),
|
||||
) {
|
||||
let repo_details = self.repo_details.clone();
|
||||
let addr = ctx.address();
|
||||
let message_token = self.message_token;
|
||||
async move {
|
||||
match forge
|
||||
.branches_validate_positions(repository, repo_config)
|
||||
.await
|
||||
{
|
||||
Ok(git::validation::Positions {
|
||||
match validate_positions(&repository, &repo_details, repo_config) {
|
||||
Ok(Positions {
|
||||
main,
|
||||
next,
|
||||
dev,
|
||||
|
@ -221,10 +220,10 @@ pub struct StartMonitoring {
|
|||
impl Handler<StartMonitoring> for RepoActor {
|
||||
type Result = ();
|
||||
#[tracing::instrument(name = "RepoActor::StartMonitoring", skip_all,
|
||||
fields(token = %self.message_token, repo = %self.details, main = %msg.main, next= %msg.next, dev = %msg.dev))
|
||||
fields(token = %self.message_token, repo = %self.repo_details, main = %msg.main, next= %msg.next, dev = %msg.dev))
|
||||
]
|
||||
fn handle(&mut self, msg: StartMonitoring, ctx: &mut Self::Context) -> Self::Result {
|
||||
let Some(repo_config) = self.details.repo_config.clone() else {
|
||||
let Some(repo_config) = self.repo_details.repo_config.clone() else {
|
||||
warn!("No config loaded");
|
||||
return;
|
||||
};
|
||||
|
@ -246,8 +245,8 @@ impl Handler<StartMonitoring> for RepoActor {
|
|||
branch::advance_next(
|
||||
msg.next,
|
||||
msg.dev_commit_history,
|
||||
self.repo_details.clone(),
|
||||
repo_config,
|
||||
forge,
|
||||
repository,
|
||||
addr,
|
||||
self.message_token,
|
||||
|
@ -265,7 +264,7 @@ impl Handler<StartMonitoring> for RepoActor {
|
|||
pub struct WebhookRegistered(webhook::WebhookId, webhook::WebhookAuth);
|
||||
impl Handler<WebhookRegistered> for RepoActor {
|
||||
type Result = ();
|
||||
#[tracing::instrument(name = "RepoActor::WebhookRegistered", skip_all, fields(repo = %self.details, webhook_id = %msg.0))]
|
||||
#[tracing::instrument(name = "RepoActor::WebhookRegistered", skip_all, fields(repo = %self.repo_details, webhook_id = %msg.0))]
|
||||
fn handle(&mut self, msg: WebhookRegistered, _ctx: &mut Self::Context) -> Self::Result {
|
||||
self.webhook_id.replace(msg.0);
|
||||
self.webhook_auth.replace(msg.1);
|
||||
|
@ -277,9 +276,9 @@ impl Handler<WebhookRegistered> for RepoActor {
|
|||
pub struct AdvanceMainTo(git::Commit);
|
||||
impl Handler<AdvanceMainTo> for RepoActor {
|
||||
type Result = ();
|
||||
#[tracing::instrument(name = "RepoActor::AdvanceMainTo", skip_all, fields(repo = %self.details, commit = %msg.0))]
|
||||
#[tracing::instrument(name = "RepoActor::AdvanceMainTo", skip_all, fields(repo = %self.repo_details, commit = %msg.0))]
|
||||
fn handle(&mut self, msg: AdvanceMainTo, ctx: &mut Self::Context) -> Self::Result {
|
||||
let Some(repo_config) = self.details.repo_config.clone() else {
|
||||
let Some(repo_config) = self.repo_details.repo_config.clone() else {
|
||||
warn!("No config loaded");
|
||||
return;
|
||||
};
|
||||
|
@ -287,11 +286,11 @@ impl Handler<AdvanceMainTo> for RepoActor {
|
|||
warn!("No repository opened");
|
||||
return;
|
||||
};
|
||||
let forge = self.forge.clone();
|
||||
let repo_details = self.repo_details.clone();
|
||||
let addr = ctx.address();
|
||||
let message_token = self.message_token;
|
||||
async move {
|
||||
branch::advance_main(msg.0, &repo_config, &forge, &repository).await;
|
||||
branch::advance_main(msg.0, &repo_details, &repo_config, &repository).await;
|
||||
match repo_config.source() {
|
||||
git_next_config::RepoConfigSource::Repo => addr.do_send(LoadConfigFromRepo),
|
||||
git_next_config::RepoConfigSource::Server => {
|
||||
|
|
|
@ -182,7 +182,7 @@ impl Handler<WebhookMessage> for RepoActor {
|
|||
type Result = ();
|
||||
|
||||
#[allow(clippy::cognitive_complexity)] // TODO: (#49) reduce complexity
|
||||
#[tracing::instrument(name = "RepoActor::WebhookMessage", skip_all, fields(token = %self.message_token, repo = %self.details))]
|
||||
#[tracing::instrument(name = "RepoActor::WebhookMessage", skip_all, fields(token = %self.message_token, repo = %self.repo_details))]
|
||||
fn handle(&mut self, msg: WebhookMessage, ctx: &mut Self::Context) -> Self::Result {
|
||||
let Some(expected_authorization) = &self.webhook_auth else {
|
||||
warn!("Don't know what authorization to expect");
|
||||
|
@ -199,7 +199,7 @@ impl Handler<WebhookMessage> for RepoActor {
|
|||
match serde_json::from_str::<Push>(body.as_str()) {
|
||||
Err(err) => warn!(?err, ?body, "Not a 'push'"),
|
||||
Ok(push) => {
|
||||
if let Some(config) = &self.details.repo_config {
|
||||
if let Some(config) = &self.repo_details.repo_config {
|
||||
match push.branch(config.branches()) {
|
||||
None => warn!(
|
||||
?push,
|
||||
|
|
|
@ -3,11 +3,6 @@ name = "git-next-server"
|
|||
version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = ["forgejo"]
|
||||
forgejo = []
|
||||
github = []
|
||||
|
||||
[dependencies]
|
||||
git-next-config = { workspace = true }
|
||||
git-next-git = { workspace = true }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
use assert2::let_assert;
|
||||
use git::repository::Direction;
|
||||
use git::{repository::Direction, validation::repo::validate_repo};
|
||||
use git_next_config::{
|
||||
self as config, ForgeType, GitDir, Hostname, RepoBranches, RepoConfig, RepoConfigSource,
|
||||
RepoPath,
|
||||
|
@ -46,7 +46,7 @@ fn gitdir_should_display_as_pathbuf() {
|
|||
// git.kemitix.net:kemitix/git-next
|
||||
// If the default push remote is something else, then this test will fail
|
||||
fn repo_details_find_default_push_remote_finds_correct_remote() -> Result<()> {
|
||||
let cli_crate_dir = std::env::current_dir().map_err(git::validate::Error::Io)?;
|
||||
let cli_crate_dir = std::env::current_dir().map_err(git::validation::repo::Error::Io)?;
|
||||
let_assert!(Some(Some(root)) = cli_crate_dir.parent().map(|p| p.parent()));
|
||||
let mut repo_details = git::common::repo_details(
|
||||
1,
|
||||
|
@ -77,7 +77,7 @@ fn repo_details_find_default_push_remote_finds_correct_remote() -> Result<()> {
|
|||
|
||||
#[test]
|
||||
fn gitdir_validate_should_pass_a_valid_git_repo() -> Result<()> {
|
||||
let cli_crate_dir = std::env::current_dir().map_err(git::validate::Error::Io)?;
|
||||
let cli_crate_dir = std::env::current_dir().map_err(git::validation::repo::Error::Io)?;
|
||||
let_assert!(Some(Some(root)) = cli_crate_dir.parent().map(|p| p.parent()));
|
||||
let mut repo_details = git::common::repo_details(
|
||||
1,
|
||||
|
@ -92,14 +92,16 @@ fn gitdir_validate_should_pass_a_valid_git_repo() -> Result<()> {
|
|||
repo_details.repo_path = RepoPath::new("kemitix/git-next".to_string());
|
||||
let gitdir = &repo_details.gitdir;
|
||||
let repository = git::repository::new().open(gitdir)?;
|
||||
git::validate(&repository, &repo_details)?;
|
||||
validate_repo(&repository, &repo_details)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gitdir_validate_should_fail_a_git_repo_with_wrong_remote() -> Result<()> {
|
||||
let_assert!(Ok(cli_crate_dir) = std::env::current_dir().map_err(git::validate::Error::Io));
|
||||
let_assert!(
|
||||
Ok(cli_crate_dir) = std::env::current_dir().map_err(git::validation::repo::Error::Io)
|
||||
);
|
||||
let_assert!(Some(Some(root)) = cli_crate_dir.parent().map(|p| p.parent()));
|
||||
let mut repo_details = git::common::repo_details(
|
||||
1,
|
||||
|
@ -111,7 +113,7 @@ fn gitdir_validate_should_fail_a_git_repo_with_wrong_remote() -> Result<()> {
|
|||
repo_details.repo_path = RepoPath::new("hello/world".to_string());
|
||||
let gitdir = &repo_details.gitdir;
|
||||
let repository = git::repository::new().open(gitdir)?;
|
||||
let_assert!(Err(_) = git::validate(&repository, &repo_details));
|
||||
let_assert!(Err(_) = validate_repo(&repository, &repo_details));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue