feat(config): User can specify git directory to use for a repo
Closes kemitix/git-next#53 Does not include using this information.
This commit is contained in:
parent
50a969ede6
commit
704853017b
4 changed files with 43 additions and 31 deletions
|
@ -62,6 +62,7 @@ tokio = { version = "1.37", features = ["full"] }
|
|||
[dev-dependencies]
|
||||
# Testing
|
||||
assert2 = "0.3"
|
||||
pretty_assertions = "1.4"
|
||||
test-log = "0.2"
|
||||
anyhow = "1.0"
|
||||
|
||||
|
|
|
@ -9,5 +9,5 @@ token = "API-Token"
|
|||
# path to private SSH key for user?
|
||||
|
||||
[forge.default.repos]
|
||||
hello = { repo = "user/hello", branch = "main" } # maps to https://git.example.net/user/hello on the branch 'main'
|
||||
world = { repo = "user/world", branch = "master" } # maps to the 'master' branch
|
||||
hello = { repo = "user/hello", branch = "main", gitdir = "/opt/git/projects/user/hello.git" } # maps to https://git.example.net/user/hello on the branch 'main'
|
||||
world = { repo = "user/world", branch = "master", main = "master", next = "upcoming", "dev" = "develop" } # maps to the 'master' branch
|
||||
|
|
|
@ -4,6 +4,7 @@ use std::{
|
|||
collections::HashMap,
|
||||
fmt::{Display, Formatter},
|
||||
ops::Deref,
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use secrecy::ExposeSecret;
|
||||
|
@ -16,7 +17,7 @@ use crate::filesystem::FileSystem;
|
|||
#[derive(Debug, PartialEq, Eq, Deserialize)]
|
||||
pub struct ServerConfig {
|
||||
webhook: Webhook,
|
||||
forge: HashMap<String, Forge>,
|
||||
forge: HashMap<String, ForgeConfig>,
|
||||
}
|
||||
impl ServerConfig {
|
||||
pub(crate) fn load(fs: &FileSystem) -> Result<Self, OneOf<(std::io::Error, toml::de::Error)>> {
|
||||
|
@ -24,7 +25,7 @@ impl ServerConfig {
|
|||
toml::from_str(&str).map_err(OneOf::new)
|
||||
}
|
||||
|
||||
pub(crate) fn forges(&self) -> impl Iterator<Item = (ForgeName, &Forge)> {
|
||||
pub(crate) fn forges(&self) -> impl Iterator<Item = (ForgeName, &ForgeConfig)> {
|
||||
self.forge
|
||||
.iter()
|
||||
.map(|(name, forge)| (ForgeName(name.clone()), forge))
|
||||
|
@ -119,16 +120,16 @@ impl Display for RepoBranches {
|
|||
/// Defines a Forge to connect to
|
||||
/// Maps from `git-next-server.toml` at `forge.{forge}`
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
|
||||
pub struct Forge {
|
||||
pub struct ForgeConfig {
|
||||
forge_type: ForgeType,
|
||||
hostname: String,
|
||||
user: String,
|
||||
token: String,
|
||||
// API Token
|
||||
// Private SSH Key Path
|
||||
repos: HashMap<String, Repo>,
|
||||
repos: HashMap<String, ServerRepoConfig>,
|
||||
}
|
||||
impl Forge {
|
||||
impl ForgeConfig {
|
||||
#[allow(dead_code)]
|
||||
pub const fn forge_type(&self) -> &ForgeType {
|
||||
&self.forge_type
|
||||
|
@ -146,29 +147,30 @@ impl Forge {
|
|||
ApiToken(self.token.clone().into())
|
||||
}
|
||||
|
||||
pub fn repos(&self) -> impl Iterator<Item = (RepoAlias, &Repo)> {
|
||||
pub fn repos(&self) -> impl Iterator<Item = (RepoAlias, &ServerRepoConfig)> {
|
||||
self.repos
|
||||
.iter()
|
||||
.map(|(name, repo)| (RepoAlias(name.clone()), repo))
|
||||
}
|
||||
}
|
||||
impl Display for Forge {
|
||||
impl Display for ForgeConfig {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{} - {}@{}", self.forge_type, self.user, self.hostname)
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines a Repo within a Forge to be monitored by the server
|
||||
/// Defines a Repo within a ForgeConfig to be monitored by the server
|
||||
/// Maps from `git-next-server.toml` at `forge.{forge}.repos.{name}`
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
|
||||
pub struct Repo {
|
||||
pub struct ServerRepoConfig {
|
||||
repo: String,
|
||||
branch: String,
|
||||
gitdir: Option<PathBuf>,
|
||||
main: Option<String>,
|
||||
next: Option<String>,
|
||||
dev: Option<String>,
|
||||
}
|
||||
impl Repo {
|
||||
impl ServerRepoConfig {
|
||||
#[allow(dead_code)]
|
||||
pub fn repo(&self) -> RepoPath {
|
||||
RepoPath(self.repo.clone())
|
||||
|
@ -193,12 +195,12 @@ impl Repo {
|
|||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
impl AsRef<Self> for Repo {
|
||||
impl AsRef<Self> for ServerRepoConfig {
|
||||
fn as_ref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
impl Display for Repo {
|
||||
impl Display for ServerRepoConfig {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{} - {}", self.repo, self.branch)
|
||||
}
|
||||
|
@ -259,8 +261,8 @@ pub struct ForgeDetails {
|
|||
// API Token
|
||||
// Private SSH Key Path
|
||||
}
|
||||
impl From<(&ForgeName, &Forge)> for ForgeDetails {
|
||||
fn from(forge: (&ForgeName, &Forge)) -> Self {
|
||||
impl From<(&ForgeName, &ForgeConfig)> for ForgeDetails {
|
||||
fn from(forge: (&ForgeName, &ForgeConfig)) -> Self {
|
||||
Self {
|
||||
name: forge.0.clone(),
|
||||
forge_type: forge.1.forge_type.clone(),
|
||||
|
@ -318,7 +320,12 @@ pub struct RepoDetails {
|
|||
pub config: Option<RepoConfig>,
|
||||
}
|
||||
impl RepoDetails {
|
||||
pub fn new(name: &RepoAlias, repo: &Repo, forge_name: &ForgeName, forge: &Forge) -> Self {
|
||||
pub fn new(
|
||||
name: &RepoAlias,
|
||||
repo: &ServerRepoConfig,
|
||||
forge_name: &ForgeName,
|
||||
forge: &ForgeConfig,
|
||||
) -> Self {
|
||||
Self {
|
||||
name: name.clone(),
|
||||
repo: RepoPath(repo.repo.clone()),
|
||||
|
@ -372,13 +379,14 @@ impl Display for ForgeType {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use crate::filesystem::FileSystem;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "forgejo")]
|
||||
fn test_server_config_load() -> Result<(), OneOf<(std::io::Error, toml::de::Error)>> {
|
||||
fn load_should_parse_server_config() -> Result<(), OneOf<(std::io::Error, toml::de::Error)>> {
|
||||
let fs = FileSystem::new_temp().map_err(OneOf::new)?;
|
||||
fs.write_file(
|
||||
"git-next-server.toml",
|
||||
|
@ -387,13 +395,13 @@ mod tests {
|
|||
url = "http://localhost:9909/webhook"
|
||||
|
||||
[forge.default]
|
||||
forge_type = "ForgeJo"
|
||||
forge_type = "MockForge"
|
||||
hostname = "git.example.net"
|
||||
user = "Bob"
|
||||
token = "API-Token"
|
||||
|
||||
[forge.default.repos]
|
||||
hello = { repo = "user/hello", branch = "main" }
|
||||
hello = { repo = "user/hello", branch = "main", gitdir = "/opt/git/user/hello.git" }
|
||||
world = { repo = "user/world", branch = "master", main = "main", next = "next", dev = "dev" }
|
||||
|
||||
[forge.default.repos.sam]
|
||||
|
@ -412,17 +420,18 @@ mod tests {
|
|||
},
|
||||
forge: HashMap::from([(
|
||||
"default".to_string(),
|
||||
Forge {
|
||||
forge_type: ForgeType::ForgeJo,
|
||||
ForgeConfig {
|
||||
forge_type: ForgeType::MockForge,
|
||||
hostname: "git.example.net".to_string(),
|
||||
user: "Bob".to_string(),
|
||||
token: "API-Token".to_string(),
|
||||
repos: HashMap::from([
|
||||
(
|
||||
"hello".to_string(),
|
||||
Repo {
|
||||
ServerRepoConfig {
|
||||
repo: "user/hello".to_string(),
|
||||
branch: "main".to_string(),
|
||||
gitdir: Some("/opt/git/user/hello.git".into()),
|
||||
main: None,
|
||||
next: None,
|
||||
dev: None,
|
||||
|
@ -430,9 +439,10 @@ mod tests {
|
|||
),
|
||||
(
|
||||
"world".to_string(),
|
||||
Repo {
|
||||
ServerRepoConfig {
|
||||
repo: "user/world".to_string(),
|
||||
branch: "master".to_string(),
|
||||
gitdir: None,
|
||||
main: Some("main".to_string()),
|
||||
next: Some("next".to_string()),
|
||||
dev: Some("dev".to_string()),
|
||||
|
@ -440,9 +450,10 @@ mod tests {
|
|||
),
|
||||
(
|
||||
"sam".to_string(),
|
||||
Repo {
|
||||
ServerRepoConfig {
|
||||
repo: "user/sam".to_string(),
|
||||
branch: "main".to_string(),
|
||||
gitdir: None,
|
||||
main: Some("master".to_string()),
|
||||
next: Some("upcoming".to_string()),
|
||||
dev: Some("sam-dev".to_string()),
|
||||
|
|
|
@ -15,11 +15,11 @@ use crate::{
|
|||
filesystem::FileSystem,
|
||||
server::{
|
||||
actors::webhook,
|
||||
config::{Forge, ForgeName, RepoAlias, Webhook},
|
||||
config::{ForgeConfig, ForgeName, RepoAlias, Webhook},
|
||||
},
|
||||
};
|
||||
|
||||
use self::{actors::repo::RepoActor, config::Repo};
|
||||
use self::{actors::repo::RepoActor, config::ServerRepoConfig};
|
||||
|
||||
pub fn init(fs: FileSystem) {
|
||||
let file_name = "git-next-server.toml";
|
||||
|
@ -68,7 +68,7 @@ pub async fn start(fs: FileSystem, net: Network) {
|
|||
}
|
||||
|
||||
fn create_forge_repos(
|
||||
forge: &Forge,
|
||||
forge: &ForgeConfig,
|
||||
forge_name: ForgeName,
|
||||
webhook: &Webhook,
|
||||
net: &Network,
|
||||
|
@ -85,10 +85,10 @@ fn create_forge_repos(
|
|||
|
||||
fn create_actor(
|
||||
forge_name: ForgeName,
|
||||
forge: config::Forge,
|
||||
forge: config::ForgeConfig,
|
||||
webhook: &Webhook,
|
||||
net: &Network,
|
||||
) -> impl Fn((RepoAlias, &Repo)) -> (ForgeName, RepoAlias, RepoActor) {
|
||||
) -> impl Fn((RepoAlias, &ServerRepoConfig)) -> (ForgeName, RepoAlias, RepoActor) {
|
||||
let webhook = webhook.clone();
|
||||
let net = net.clone();
|
||||
move |(repo_name, repo)| {
|
||||
|
|
Loading…
Reference in a new issue