aboutsummaryrefslogtreecommitdiffstats
path: root/pkgs/by-name/ba/back/src/config
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/by-name/ba/back/src/config')
-rw-r--r--pkgs/by-name/ba/back/src/config/mod.rs110
1 files changed, 98 insertions, 12 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..1161ce3 100644
--- a/pkgs/by-name/ba/back/src/config/mod.rs
+++ b/pkgs/by-name/ba/back/src/config/mod.rs
@@ -18,21 +18,97 @@ 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,
+};
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,
+
+ /// A list of the repositories known to back.
+ /// This list is constructed from the `scan_path` and the `project_list` file.
+ pub repositories: BackRepositories,
+
+ /// The root url this instance of back is hosted on.
+ /// For example:
+ /// `issues.foss-syndicate.org`
pub root: Url,
}
+pub struct BackRepositories {
+ repositories: Vec<BackRepository>,
+
+ /// The path that is the common parent of all the repositories.
+ scan_path: PathBuf,
+}
+
+impl BackRepositories {
+ pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter {
+ self.into_iter()
+ }
+}
+
+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()
+ }
+}
+
+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(),
+ })
+ }
+
+ pub fn scan_path(&self) -> &Path {
+ &self.scan_path
+ }
+}
+
+pub struct BackRepository {
+ repo_path: PathBuf,
+}
+
+impl BackRepository {
+ pub fn open(&self, scan_path: &Path) -> Result<ThreadSafeRepository, error::Error> {
+ let repo = ThreadSafeRepository::open(scan_path.join(&self.repo_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
+ }
+}
+
#[derive(Deserialize)]
struct RawBackConfig {
source_code_repository_url: Url,
- repository_path: PathBuf,
root_url: Url,
+ project_list: PathBuf,
+ scan_path: PathBuf,
}
impl BackConfig {
@@ -56,16 +132,26 @@ impl TryFrom<RawBackConfig> for BackConfig {
type Error = error::Error;
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),
- })
- }?;
+ let repositories = fs::read_to_string(&value.project_list)
+ .map_err(|err| error::Error::ProjectListRead {
+ error: err,
+ file: value.project_list,
+ })?
+ .lines()
+ .try_fold(vec![], |mut acc, path| {
+ acc.push(BackRepository {
+ repo_path: PathBuf::from(path),
+ });
+
+ Ok::<_, Self::Error>(acc)
+ })?;
Ok(Self {
- repository,
source_code_repository_url: value.source_code_repository_url,
+ repositories: BackRepositories {
+ repositories,
+ scan_path: value.scan_path,
+ },
root: value.root_url,
})
}