forked from kemitix/git-next
feat(config): Repos specify which branch to read config from
This commit is contained in:
parent
b66b70c08b
commit
e9685abf5f
4 changed files with 112 additions and 36 deletions
|
@ -6,4 +6,5 @@ user = "git-next" # the user to perform actions as
|
||||||
# path to private SSH key for user?
|
# path to private SSH key for user?
|
||||||
|
|
||||||
[forge.default.repos]
|
[forge.default.repos]
|
||||||
hello = "user/hello" # maps to https://git.example.net/user/hello and git@git.example.net:user/hello.git
|
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
|
||||||
|
|
|
@ -17,7 +17,7 @@ impl Handler<StartRepo> for RepoActor {
|
||||||
fn handle(&mut self, _msg: StartRepo, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, _msg: StartRepo, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
info!(
|
info!(
|
||||||
"Starting Repo: {} - {}",
|
"Starting Repo: {} - {}",
|
||||||
self.details.name.0, self.details.path.0
|
self.details.name.0, self.details.repo.0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,18 @@ use crate::filesystem::FileSystem;
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
forge: HashMap<String, Forge>,
|
forge: HashMap<String, Forge>,
|
||||||
}
|
}
|
||||||
|
impl Config {
|
||||||
|
pub(crate) fn load(fs: &FileSystem) -> Result<Self, OneOf<(std::io::Error, toml::de::Error)>> {
|
||||||
|
let str = fs.read_file("git-next-server.toml").map_err(OneOf::new)?;
|
||||||
|
toml::from_str(&str).map_err(OneOf::new)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn forges(&self) -> impl Iterator<Item = (ForgeName, &Forge)> {
|
||||||
|
self.forge
|
||||||
|
.iter()
|
||||||
|
.map(|(name, forge)| (ForgeName(name.clone()), forge))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Deserialize)]
|
#[derive(Debug, PartialEq, Eq, Deserialize)]
|
||||||
pub struct Forge {
|
pub struct Forge {
|
||||||
|
@ -19,26 +31,62 @@ pub struct Forge {
|
||||||
user: String,
|
user: String,
|
||||||
// API Token
|
// API Token
|
||||||
// Private SSH Key Path
|
// Private SSH Key Path
|
||||||
repos: HashMap<String, String>,
|
repos: HashMap<String, Repo>,
|
||||||
}
|
}
|
||||||
impl Forge {
|
impl Forge {
|
||||||
pub const fn forge_type(&self) -> &ForgeType {
|
pub const fn forge_type(&self) -> &ForgeType {
|
||||||
&self.forge_type
|
&self.forge_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hostname(&self) -> &str {
|
pub fn hostname(&self) -> Hostname {
|
||||||
&self.hostname
|
Hostname(self.hostname.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn user(&self) -> &str {
|
pub fn user(&self) -> User {
|
||||||
&self.user
|
User(self.user.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn repos(&self) -> impl Iterator<Item = (&String, &String)> {
|
pub fn repos(&self) -> impl Iterator<Item = (RepoName, &Repo)> {
|
||||||
self.repos.iter()
|
self.repos
|
||||||
|
.iter()
|
||||||
|
.map(|(name, repo)| (RepoName(name.clone()), repo))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Deserialize)]
|
||||||
|
pub struct Repo {
|
||||||
|
repo: String,
|
||||||
|
branch: String,
|
||||||
|
}
|
||||||
|
impl Repo {
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn new(repo: &str, branch: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
repo: repo.to_string(),
|
||||||
|
branch: branch.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn repo(&self) -> RepoPath {
|
||||||
|
RepoPath(self.repo.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn branch(&self) -> BranchName {
|
||||||
|
BranchName(self.branch.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(test)]
|
||||||
|
impl AsRef<Repo> for Repo {
|
||||||
|
fn as_ref(&self) -> &Repo {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Display for Repo {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{} - {}", self.repo, self.branch)
|
||||||
|
}
|
||||||
|
}
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ForgeName(pub String);
|
pub struct ForgeName(pub String);
|
||||||
impl Display for ForgeName {
|
impl Display for ForgeName {
|
||||||
|
@ -47,7 +95,17 @@ impl Display for ForgeName {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub struct Hostname(pub String);
|
pub struct Hostname(pub String);
|
||||||
|
impl Display for Hostname {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
pub struct User(pub String);
|
pub struct User(pub String);
|
||||||
|
impl Display for User {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
pub struct ForgeDetails {
|
pub struct ForgeDetails {
|
||||||
pub name: ForgeName,
|
pub name: ForgeName,
|
||||||
pub forge_type: ForgeType,
|
pub forge_type: ForgeType,
|
||||||
|
@ -74,11 +132,38 @@ impl Display for RepoName {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub struct RepoPath(pub String);
|
pub struct RepoPath(pub String);
|
||||||
|
impl Display for RepoPath {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub struct BranchName(pub String);
|
||||||
|
impl Display for BranchName {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
pub struct RepoDetails {
|
pub struct RepoDetails {
|
||||||
pub name: RepoName,
|
pub name: RepoName,
|
||||||
pub path: RepoPath,
|
pub repo: RepoPath,
|
||||||
|
pub branch: BranchName,
|
||||||
pub forge: ForgeDetails,
|
pub forge: ForgeDetails,
|
||||||
}
|
}
|
||||||
|
impl RepoDetails {
|
||||||
|
pub fn new(name: &RepoName, repo: &Repo, forge_name: &ForgeName, forge: &Forge) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.clone(),
|
||||||
|
repo: RepoPath(repo.repo.clone()),
|
||||||
|
branch: BranchName(repo.branch.clone()),
|
||||||
|
forge: ForgeDetails {
|
||||||
|
name: forge_name.clone(),
|
||||||
|
forge_type: forge.forge_type.clone(),
|
||||||
|
hostname: Hostname(forge.hostname.clone()),
|
||||||
|
user: User(forge.user.clone()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
|
||||||
pub enum ForgeType {
|
pub enum ForgeType {
|
||||||
|
@ -94,18 +179,6 @@ impl Display for ForgeType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
impl Config {
|
|
||||||
pub(crate) fn load(fs: &FileSystem) -> Result<Self, OneOf<(std::io::Error, toml::de::Error)>> {
|
|
||||||
let str = fs.read_file("git-next-server.toml").map_err(OneOf::new)?;
|
|
||||||
toml::from_str(&str).map_err(OneOf::new)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn forges(&self) -> impl Iterator<Item = (&String, &Forge)> {
|
|
||||||
self.forge.iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use assert2::let_assert;
|
use assert2::let_assert;
|
||||||
|
@ -126,7 +199,8 @@ mod tests {
|
||||||
user = "Bob"
|
user = "Bob"
|
||||||
|
|
||||||
[forge.default.repos]
|
[forge.default.repos]
|
||||||
hello = "user/world"
|
hello = { repo = "user/hello", branch = "main" }
|
||||||
|
world = { repo = "user/world", branch = "master" }
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.map_err(OneOf::new)?;
|
.map_err(OneOf::new)?;
|
||||||
|
@ -135,7 +209,14 @@ mod tests {
|
||||||
assert_eq!(default.forge_type, ForgeType::ForgeJo);
|
assert_eq!(default.forge_type, ForgeType::ForgeJo);
|
||||||
assert_eq!(default.hostname, "git.example.net".to_string());
|
assert_eq!(default.hostname, "git.example.net".to_string());
|
||||||
assert_eq!(default.user, "Bob".to_string());
|
assert_eq!(default.user, "Bob".to_string());
|
||||||
assert_eq!(default.repos.get("hello"), Some(&"user/world".to_string()));
|
assert_eq!(
|
||||||
|
default.repos.get("hello"),
|
||||||
|
Some(Repo::new("user/hello", "main").as_ref())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
default.repos.get("world"),
|
||||||
|
Some(Repo::new("user/world", "master").as_ref())
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,27 +47,21 @@ pub fn start(fs: FileSystem) {
|
||||||
info!("Loaded config");
|
info!("Loaded config");
|
||||||
let mut actors: Vec<(ForgeName, RepoName, actors::repo::RepoActor)> = vec![];
|
let mut actors: Vec<(ForgeName, RepoName, actors::repo::RepoActor)> = vec![];
|
||||||
config.forges().for_each(|(forge_name, forge)| {
|
config.forges().for_each(|(forge_name, forge)| {
|
||||||
let forge_name = ForgeName(forge_name.clone());
|
|
||||||
let span = tracing::info_span!("Forge", %forge_name);
|
let span = tracing::info_span!("Forge", %forge_name);
|
||||||
let _guard = span.enter();
|
let _guard = span.enter();
|
||||||
info!("Forge: {}", forge_name);
|
info!("Forge: {}", forge_name);
|
||||||
info!("Forge Type: {}", forge.forge_type());
|
info!("Forge Type: {}", forge.forge_type());
|
||||||
info!("Hostname: {}", forge.hostname());
|
info!("Hostname: {}", forge.hostname());
|
||||||
info!("User: {}", forge.user());
|
info!("User: {}", forge.user());
|
||||||
forge.repos().for_each(|(repo_name, path)| {
|
forge.repos().for_each(|(repo_name, repo)| {
|
||||||
let repo_name = RepoName(repo_name.clone());
|
let span = tracing::info_span!("Repo", %repo_name, %repo);
|
||||||
let span = tracing::info_span!("Repo", %repo_name);
|
|
||||||
let _guard = span.enter();
|
let _guard = span.enter();
|
||||||
info!("Repo: {} - {}", repo_name, path);
|
info!("Creating Repo");
|
||||||
let actor = actors::repo::RepoActor {
|
let actor = actors::repo::RepoActor {
|
||||||
details: config::RepoDetails {
|
details: config::RepoDetails::new(&repo_name, repo, &forge_name, forge),
|
||||||
name: repo_name.clone(),
|
|
||||||
path: config::RepoPath(path.clone()),
|
|
||||||
forge: (&forge_name, forge).into(),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
actors.push((forge_name.clone(), repo_name.clone(), actor));
|
actors.push((forge_name.clone(), repo_name, actor));
|
||||||
info!("Created actor for repo: {} - {}", repo_name, path);
|
info!("Created Repo");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
info!("Sending StartRepo to all actors...");
|
info!("Sending StartRepo to all actors...");
|
||||||
|
|
Loading…
Reference in a new issue