From 21b9a461dafeab63893d82a82d7b84ffe3a59c40 Mon Sep 17 00:00:00 2001 From: Benedikt Peetz Date: Fri, 6 Jun 2025 22:08:26 +0200 Subject: pkgs/back: Remove Back has been moved out-of-tree. --- pkgs/by-name/ba/back/src/git_bug/dag/mod.rs | 155 ----------------- pkgs/by-name/ba/back/src/git_bug/format/mod.rs | 157 ----------------- .../ba/back/src/git_bug/issue/entity/mod.rs | 78 --------- .../ba/back/src/git_bug/issue/identity/mod.rs | 79 --------- .../by-name/ba/back/src/git_bug/issue/label/mod.rs | 85 ---------- pkgs/by-name/ba/back/src/git_bug/issue/mod.rs | 185 --------------------- .../ba/back/src/git_bug/issue/operation/mod.rs | 124 -------------- .../src/git_bug/issue/operation/operation_type.rs | 51 ------ pkgs/by-name/ba/back/src/git_bug/mod.rs | 28 ---- 9 files changed, 942 deletions(-) delete mode 100644 pkgs/by-name/ba/back/src/git_bug/dag/mod.rs delete mode 100644 pkgs/by-name/ba/back/src/git_bug/format/mod.rs delete mode 100644 pkgs/by-name/ba/back/src/git_bug/issue/entity/mod.rs delete mode 100644 pkgs/by-name/ba/back/src/git_bug/issue/identity/mod.rs delete mode 100644 pkgs/by-name/ba/back/src/git_bug/issue/label/mod.rs delete mode 100644 pkgs/by-name/ba/back/src/git_bug/issue/mod.rs delete mode 100644 pkgs/by-name/ba/back/src/git_bug/issue/operation/mod.rs delete mode 100644 pkgs/by-name/ba/back/src/git_bug/issue/operation/operation_type.rs delete mode 100644 pkgs/by-name/ba/back/src/git_bug/mod.rs (limited to 'pkgs/by-name/ba/back/src/git_bug') 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 -// 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 . - -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, -} - -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> { - 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 { - 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> { - 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::>(); - - Ok(dags) -} diff --git a/pkgs/by-name/ba/back/src/git_bug/format/mod.rs b/pkgs/by-name/ba/back/src/git_bug/format/mod.rs deleted file mode 100644 index ffe44fd..0000000 --- a/pkgs/by-name/ba/back/src/git_bug/format/mod.rs +++ /dev/null @@ -1,157 +0,0 @@ -// Back - An extremely simple git issue tracking system. Inspired by tvix's -// panettone -// -// Copyright (C) 2024 Benedikt Peetz -// 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 . - -use std::fmt::Display; - -use chrono::DateTime; -use markdown::to_html; -use serde::Deserialize; -use serde_json::Value; - -/// Markdown content. -#[derive(Debug, Default, Clone)] -pub struct MarkDown { - value: String, -} - -impl Display for MarkDown { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(to_html(&self.value).as_str()) - } -} -impl From<&Value> for MarkDown { - fn from(value: &Value) -> Self { - Self { - value: value.as_str().expect("This will exist").to_owned(), - } - } -} - -/// An UNIX time stamp. -/// -/// These should only ever be used for human-display, because timestamps are unreliably in a -/// distributed system. -/// Because of this reason, there is no `value()` function. -#[derive(Debug, Default, Clone, Copy)] -pub struct TimeStamp { - value: u64, -} -impl From<&Value> for TimeStamp { - fn from(value: &Value) -> Self { - Self { - value: value.as_u64().expect("This must exist"), - } - } -} -impl Display for TimeStamp { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let date = - DateTime::from_timestamp(self.value as i64, 0).expect("This timestamp should be vaild"); - - let newdate = date.format("%Y-%m-%d %H:%M:%S"); - f.write_str(newdate.to_string().as_str()) - } -} - -/// An UNIX time stamp. -/// -/// These should only ever be used for human-display, because timestamps are unreliably in a -/// distributed system. -/// -/// This one allows underlying access to it's value and is only obtainable via `unsafe` code. -/// The reason behind this is, that you might need to access this to improve the display for humans -/// (i.e., sorting by date). -#[derive(Debug, Default, Clone, Copy, Ord, PartialOrd, Eq, PartialEq)] -pub struct UnsafeTimeStamp { - value: u64, -} -impl TimeStamp { - /// # Safety - /// This is not really unsafe, but there is just no way your can trust a time stamp in a - /// distributed system. As such access to the raw value could lead to bugs. - pub unsafe fn to_unsafe(self) -> UnsafeTimeStamp { - UnsafeTimeStamp { value: self.value } - } -} - -#[derive(Debug, Default, Deserialize, Clone, PartialEq, Eq)] -/// A string that should be escaped when injected into html content. -pub struct HtmlString { - value: String, -} - -impl From for HtmlString { - fn from(value: String) -> Self { - Self { value } - } -} -impl From<&str> for HtmlString { - fn from(value: &str) -> Self { - Self { - value: value.to_owned(), - } - } -} - -impl From for HtmlString { - fn from(value: MarkDown) -> Self { - Self { value: value.value } - } -} - -impl From<&Value> for HtmlString { - fn from(value: &Value) -> Self { - Self { - value: value.as_str().expect("This will exist").to_owned(), - } - } -} -impl Display for HtmlString { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(escape_html(&self.value).as_str()) - } -} - -// From `tera::escape_html` -/// Escape HTML following [OWASP](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet) -/// -/// Escape the following characters with HTML entity encoding to prevent switching -/// into any execution context, such as script, style, or event handlers. Using -/// hex entities is recommended in the spec. In addition to the 5 characters -/// significant in XML (&, <, >, ", '), the forward slash is included as it helps -/// to end an HTML entity. -/// -/// ```text -/// & --> & -/// < --> < -/// > --> > -/// " --> " -/// ' --> ' ' is not recommended -/// / --> / forward slash is included as it helps end an HTML entity -/// ``` -#[inline] -pub fn escape_html(input: &str) -> String { - let mut output = String::with_capacity(input.len() * 2); - for c in input.chars() { - match c { - '&' => output.push_str("&"), - '<' => output.push_str("<"), - '>' => output.push_str(">"), - '"' => output.push_str("""), - '\'' => output.push_str("'"), - '/' => output.push_str("/"), - _ => output.push(c), - } - } - - // Not using shrink_to_fit() on purpose - output -} diff --git a/pkgs/by-name/ba/back/src/git_bug/issue/entity/mod.rs b/pkgs/by-name/ba/back/src/git_bug/issue/entity/mod.rs deleted file mode 100644 index f2e9af0..0000000 --- a/pkgs/by-name/ba/back/src/git_bug/issue/entity/mod.rs +++ /dev/null @@ -1,78 +0,0 @@ -// Back - An extremely simple git issue tracking system. Inspired by tvix's -// panettone -// -// Copyright (C) 2024 Benedikt Peetz -// 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 . - -use std::fmt::Display; - -use gix::Repository; -use serde::Deserialize; -use serde_json::Value; - -use super::{ - identity::{Author, RawAuthor}, - operation::Operation, -}; - -#[derive(Deserialize, Debug, PartialEq, Eq, Clone)] -#[serde(from = "Value")] -pub struct Id { - value: String, -} -impl From for Id { - fn from(value: Value) -> Self { - Self::from(&value) - } -} -impl From<&Value> for Id { - fn from(value: &Value) -> Self { - Self { - value: value.as_str().expect("This should be a string").to_owned(), - } - } -} -impl From> for Id { - fn from(value: gix::Id<'_>) -> Self { - Self { - value: value.shorten().expect("This should work?").to_string(), - } - } -} -impl Display for Id { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.value.fmt(f) - // let shortend = self.value.shorten().expect("This should work."); - // f.write_str(shortend.to_string().as_str()) - } -} - -#[derive(Debug)] -pub struct Entity { - pub id: Id, - pub author: Author, - pub operations: Vec, -} - -impl Entity { - pub fn from_raw<'a>(repo: &'a Repository, raw: RawEntity, id: gix::Id<'a>) -> Self { - Self { - id: Id::from(id), - author: Author::construct(repo, raw.author), - operations: raw.operations, - } - } -} - -#[derive(Deserialize)] -pub struct RawEntity { - pub author: RawAuthor, - - #[serde(alias = "ops")] - pub operations: Vec, -} diff --git a/pkgs/by-name/ba/back/src/git_bug/issue/identity/mod.rs b/pkgs/by-name/ba/back/src/git_bug/issue/identity/mod.rs deleted file mode 100644 index bbf483c..0000000 --- a/pkgs/by-name/ba/back/src/git_bug/issue/identity/mod.rs +++ /dev/null @@ -1,79 +0,0 @@ -// Back - An extremely simple git issue tracking system. Inspired by tvix's -// panettone -// -// Copyright (C) 2024 Benedikt Peetz -// 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 . - -use std::fmt::Display; - -use gix::{bstr::ByteSlice, Repository}; -use serde::Deserialize; -use serde_json::Value; - -use crate::{get, git_bug::format::HtmlString}; - -use super::entity::Id; - -#[derive(Debug, Clone)] -pub struct Author { - pub name: HtmlString, - pub email: HtmlString, - pub id: Id, -} - -impl Display for Author { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "({}, {})", self.name, self.email) - } -} - -impl Author { - pub fn construct(repo: &Repository, raw: RawAuthor) -> Self { - let commit_obj = repo - .find_reference(&format!("refs/identities/{}", raw.id)) - .expect("All authors should also have identities") - .peel_to_commit() - .expect("All identities should be commits"); - - let tree_obj = repo - .find_tree( - commit_obj - .tree() - .expect("The commit should have an tree associated with it") - .id, - ) - .expect("This should be a tree"); - - let data = repo - .find_blob( - tree_obj - .find_entry("version") - .expect("This entry should exist") - .object() - .expect("This should point to a blob entry") - .id, - ) - .expect("This blob should exist") - .data - .clone(); - - let json: Value = serde_json::from_str(data.to_str().expect("This is encoded json")) - .expect("This is valid json"); - - Author { - name: get! {json, "name"}, - email: get! {json, "email"}, - id: raw.id, - } - } -} - -#[derive(Deserialize)] -pub struct RawAuthor { - id: Id, -} diff --git a/pkgs/by-name/ba/back/src/git_bug/issue/label/mod.rs b/pkgs/by-name/ba/back/src/git_bug/issue/label/mod.rs deleted file mode 100644 index a971234..0000000 --- a/pkgs/by-name/ba/back/src/git_bug/issue/label/mod.rs +++ /dev/null @@ -1,85 +0,0 @@ -// Back - An extremely simple git issue tracking system. Inspired by tvix's -// panettone -// -// Copyright (C) 2024 Benedikt Peetz -// 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 . - -use std::fmt::Display; - -use serde::Deserialize; -use sha2::{Digest, Sha256}; - -use crate::git_bug::format::HtmlString; - -#[derive(Debug, Deserialize, PartialEq, Eq, Clone)] -pub struct Label { - value: HtmlString, -} - -impl Display for Label { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.value.fmt(f) - } -} - -impl Label { - /// RGBA from a Label computed in a deterministic way - /// This is taken completely from `git_bug` - pub fn associate_color(&self) -> Color { - // colors from: https://material-ui.com/style/color/ - let colors = vec![ - Color::from_rgba(244, 67, 54, 255), // red - Color::from_rgba(233, 30, 99, 255), // pink - Color::from_rgba(156, 39, 176, 255), // purple - Color::from_rgba(103, 58, 183, 255), // deepPurple - Color::from_rgba(63, 81, 181, 255), // indigo - Color::from_rgba(33, 150, 243, 255), // blue - Color::from_rgba(3, 169, 244, 255), // lightBlue - Color::from_rgba(0, 188, 212, 255), // cyan - Color::from_rgba(0, 150, 136, 255), // teal - Color::from_rgba(76, 175, 80, 255), // green - Color::from_rgba(139, 195, 74, 255), // lightGreen - Color::from_rgba(205, 220, 57, 255), // lime - Color::from_rgba(255, 235, 59, 255), // yellow - Color::from_rgba(255, 193, 7, 255), // amber - Color::from_rgba(255, 152, 0, 255), // orange - Color::from_rgba(255, 87, 34, 255), // deepOrange - Color::from_rgba(121, 85, 72, 255), // brown - Color::from_rgba(158, 158, 158, 255), // grey - Color::from_rgba(96, 125, 139, 255), // blueGrey - ]; - - let hash = Sha256::digest(self.to_string().as_bytes()); - - let id: usize = hash - .into_iter() - .map(|val| val as usize) - .fold(0, |acc, val| (acc + val) % colors.len()); - - colors[id] - } -} - -#[derive(Default, Clone, Copy, Debug)] -pub struct Color { - pub red: u32, - pub green: u32, - pub blue: u32, - pub alpha: u32, -} - -impl Color { - pub fn from_rgba(red: u32, green: u32, blue: u32, alpha: u32) -> Self { - Self { - red, - green, - blue, - alpha, - } - } -} diff --git a/pkgs/by-name/ba/back/src/git_bug/issue/mod.rs b/pkgs/by-name/ba/back/src/git_bug/issue/mod.rs deleted file mode 100644 index d382b54..0000000 --- a/pkgs/by-name/ba/back/src/git_bug/issue/mod.rs +++ /dev/null @@ -1,185 +0,0 @@ -// Back - An extremely simple git issue tracking system. Inspired by tvix's -// panettone -// -// Copyright (C) 2024 Benedikt Peetz -// 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 . - -use std::fmt::Display; - -use entity::{Entity, Id}; -use identity::Author; -use label::Label; -use operation::Operation; -use serde_json::Value; - -use super::format::{MarkDown, TimeStamp}; - -pub mod entity; -pub mod identity; -pub mod label; -pub mod operation; - -#[derive(Debug, Eq, PartialEq, Copy, Clone)] -pub enum Status { - Open, - Closed, -} -impl From<&Value> for Status { - fn from(value: &Value) -> Self { - match value.as_u64().expect("This should be a integer") { - 1 => Self::Open, - 2 => Self::Closed, - other => unimplemented!("Invalid status string: '{other}'"), - } - } -} -impl Display for Status { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Status::Open => f.write_str("Open"), - Status::Closed => f.write_str("Closed"), - } - } -} - -#[derive(Debug)] -pub struct CollapsedIssue { - pub id: Id, - pub author: Author, - pub timestamp: TimeStamp, - pub title: MarkDown, - pub message: MarkDown, - pub comments: Vec, - pub status: Status, - pub last_status_change: TimeStamp, - pub labels: Vec