diff options
Diffstat (limited to 'pkgs/by-name/ba/back/src/git_bug/dag/mod.rs')
-rw-r--r-- | pkgs/by-name/ba/back/src/git_bug/dag/mod.rs | 155 |
1 files changed, 0 insertions, 155 deletions
diff --git a/pkgs/by-name/ba/back/src/git_bug/dag/mod.rs b/pkgs/by-name/ba/back/src/git_bug/dag/mod.rs deleted file mode 100644 index 3d22b04..0000000 --- a/pkgs/by-name/ba/back/src/git_bug/dag/mod.rs +++ /dev/null @@ -1,155 +0,0 @@ -// Back - An extremely simple git issue tracking system. Inspired by tvix's -// panettone -// -// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -// SPDX-License-Identifier: AGPL-3.0-or-later -// -// This file is part of Back. -// -// You should have received a copy of the License along with this program. -// If not, see <https://www.gnu.org/licenses/agpl.txt>. - -use std::path::Path; - -use gix::{bstr::ByteSlice, refs::Target, Commit, Id, ObjectId, Repository}; - -use crate::error; - -use super::issue::{ - entity::{Entity, RawEntity}, - CollapsedIssue, RawCollapsedIssue, -}; - -#[derive(Debug)] -pub struct Dag { - entities: Vec<Entity>, -} - -impl Dag { - pub fn collapse(self) -> CollapsedIssue { - let raw_collapsed_issue = self.entities.into_iter().rev().fold( - RawCollapsedIssue::default(), - |mut collapsed_issue, entity| { - collapsed_issue.append_entity(entity); - collapsed_issue - }, - ); - - CollapsedIssue::from(raw_collapsed_issue) - } - - /// Construct a DAG from the root child upwards. - pub fn construct(repo: &Repository, id: ObjectId) -> Self { - let mut entities = vec![]; - - let base_commit = repo - .find_object(id) - .expect("The object with this id should exist.") - .try_into_commit() - .expect("The git-bug's data model enforces this."); - - entities.push(Self::commit_to_operations(repo, &base_commit)); - - let mut current_commit = base_commit; - while let Some(parent_id) = Self::try_get_parent(repo, ¤t_commit) { - entities.push(Self::commit_to_operations(repo, &parent_id)); - current_commit = parent_id; - } - - Self { - entities: { - entities - .into_iter() - .map(|(raw_entity, id)| Entity::from_raw(repo, raw_entity, id)) - .collect() - }, - } - } - - fn commit_to_operations<'b>(repo: &Repository, id: &Commit<'b>) -> (RawEntity, Id<'b>) { - let tree_obj = repo - .find_object( - id.tree_id() - .expect("All of git-bug's commits should have trees attached to them'"), - ) - .expect("The object with this id should exist.") - .try_into_tree() - .expect("git-bug's data model enforces this."); - - let ops_ref = tree_obj - .find_entry("ops") - .expect("All of git-bug's trees should contain a 'ops' json file"); - - let issue_data = repo - .find_object(ops_ref.object_id()) - .expect("The object with this id should exist.") - .try_into_blob() - .expect("The git-bug's data model enforces this.") - .data - .clone(); - - let operations = serde_json::from_str( - issue_data - .to_str() - .expect("git-bug's ensures, that this is valid json."), - ) - .expect("The returned json should be valid"); - - (operations, id.id()) - } - - fn try_get_parent<'a>(repo: &'a Repository, base_commit: &Commit<'a>) -> Option<Commit<'a>> { - let count = base_commit.parent_ids().count(); - - match count { - 0 => None, - 1 => { - let parent = base_commit.parent_ids().last().expect("One does exist"); - - let parent_id = parent.object().expect("The object exists").id; - Some( - repo.find_object(parent_id) - .expect("This is a valid id") - .try_into_commit() - .expect("This should be a commit"), - ) - } - other => { - unreachable!( - "Each commit, used by git-bug should only have one parent, but found: {other}" - ); - } - } - } -} - -/// Check whether `git-bug` has been initialized in this repository -pub fn is_git_bug(repo: &Repository) -> error::Result<bool> { - Ok(repo - .refs - .iter()? - .prefixed(Path::new("refs/bugs/")) - .map_err(|err| error::Error::RepoRefsPrefixed { error: err })? - .count() - > 0) -} - -pub fn issues_from_repository(repo: &Repository) -> error::Result<Vec<Dag>> { - let dags = repo - .refs - .iter()? - .prefixed(Path::new("refs/bugs/")) - .map_err(|err| error::Error::RepoRefsPrefixed { error: err })? - .map(|val| { - let reference = val.expect("All `git-bug` references in 'refs/bugs' should be objects"); - - if let Target::Object(id) = reference.target { - Dag::construct(repo, id) - } else { - unreachable!("All 'refs/bugs/' should contain a clear target."); - } - }) - .collect::<Vec<Dag>>(); - - Ok(dags) -} |