diff options
Diffstat (limited to '')
-rw-r--r-- | pkgs/by-name/ba/back/src/config/mod.rs | 132 |
1 files changed, 98 insertions, 34 deletions
diff --git a/pkgs/by-name/ba/back/src/config/mod.rs b/pkgs/by-name/ba/back/src/config/mod.rs index 7351ad8..832d060 100644 --- a/pkgs/by-name/ba/back/src/config/mod.rs +++ b/pkgs/by-name/ba/back/src/config/mod.rs @@ -18,55 +18,119 @@ use gix::ThreadSafeRepository; use serde::Deserialize; use url::Url; -use crate::error::{self, Error}; +use crate::{ + error::{self, Error}, + git_bug::dag::is_git_bug, +}; +#[derive(Deserialize)] pub struct BackConfig { - // NOTE(@bpeetz): We do not need to html escape this, as the value must be a valid url. As such - // `<tags>` of all kinds _should_ be invalid. <2024-12-26> + /// The url to the source code of back. This is needed, because back is licensed under the + /// AGPL. pub source_code_repository_url: Url, - pub repository: ThreadSafeRepository, - pub root: Url, + + /// The root url this instance of back is hosted on. + /// For example: + /// `issues.foss-syndicate.org` + pub root_url: Url, + + project_list: PathBuf, + + /// The path that is the common parent of all the repositories. + pub scan_path: PathBuf, } -#[derive(Deserialize)] -struct RawBackConfig { - source_code_repository_url: Url, - repository_path: PathBuf, - root_url: Url, +pub struct BackRepositories { + repositories: Vec<BackRepository>, } -impl BackConfig { - pub fn from_config_file(path: &Path) -> error::Result<Self> { - let value = fs::read_to_string(path).map_err(|err| Error::ConfigRead { - file: path.to_owned(), - error: err, - })?; +impl BackRepositories { + pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter { + self.into_iter() + } +} - let raw: RawBackConfig = - serde_json::from_str(&value).map_err(|err| Error::ConfigParse { - file: path.to_owned(), - error: err, - })?; +impl<'a> IntoIterator for &'a BackRepositories { + type Item = <&'a Vec<BackRepository> as IntoIterator>::Item; + + type IntoIter = <&'a Vec<BackRepository> as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.repositories.iter() + } +} - Self::try_from(raw) +impl BackRepositories { + /// Try to get the repository at path `path`. + /// If no repository was registered/found at `path`, returns an error. + pub fn get(&self, path: &Path) -> Result<&BackRepository, error::Error> { + self.repositories + .iter() + .find(|p| p.repo_path == path) + .ok_or(error::Error::RepoFind { + repository_path: path.to_owned(), + }) } } -impl TryFrom<RawBackConfig> for BackConfig { - type Error = error::Error; +pub struct BackRepository { + repo_path: PathBuf, +} - fn try_from(value: RawBackConfig) -> Result<Self, Self::Error> { - let repository = { - ThreadSafeRepository::open(&value.repository_path).map_err(|err| Error::RepoOpen { - repository_path: value.repository_path, - error: Box::new(err), +impl BackRepository { + pub fn open(&self, scan_path: &Path) -> Result<ThreadSafeRepository, error::Error> { + let path = { + let base = scan_path.join(&self.repo_path); + if base.is_dir() { + base + } else { + PathBuf::from(base.display().to_string() + ".git") + } + }; + let repo = ThreadSafeRepository::open(path).map_err(|err| Error::RepoOpen { + repository_path: self.repo_path.to_owned(), + error: Box::new(err), + })?; + if is_git_bug(&repo.to_thread_local())? { + Ok(repo) + } else { + Err(error::Error::NotGitBug { + path: self.repo_path.clone(), }) - }?; + } + } + pub fn path(&self) -> &Path { + &self.repo_path + } +} + +impl BackConfig { + pub fn repositories(&self) -> error::Result<BackRepositories> { + let repositories = fs::read_to_string(&self.project_list) + .map_err(|err| error::Error::ProjectListRead { + error: err, + file: self.project_list.to_owned(), + })? + .lines() + .try_fold(vec![], |mut acc, path| { + acc.push(BackRepository { + repo_path: PathBuf::from(path), + }); + + Ok::<_, error::Error>(acc) + })?; + Ok(BackRepositories { repositories }) + } + + pub fn from_config_file(path: &Path) -> error::Result<Self> { + let value = fs::read_to_string(path).map_err(|err| Error::ConfigRead { + file: path.to_owned(), + error: err, + })?; - Ok(Self { - repository, - source_code_repository_url: value.source_code_repository_url, - root: value.root_url, + serde_json::from_str(&value).map_err(|err| Error::ConfigParse { + file: path.to_owned(), + error: err, }) } } |