diff options
author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-06-06 22:08:26 +0200 |
---|---|---|
committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-06-06 22:08:26 +0200 |
commit | 21b9a461dafeab63893d82a82d7b84ffe3a59c40 (patch) | |
tree | dfb8e657e2f36b426d9fba1b1a703431836d92e5 /pkgs/by-name/ba/back/src/git_bug/issue | |
parent | flake.nix: Use the packaged version of `ragenix` (diff) | |
download | nixos-server-21b9a461dafeab63893d82a82d7b84ffe3a59c40.zip |
pkgs/back: Remove
Back has been moved out-of-tree.
Diffstat (limited to 'pkgs/by-name/ba/back/src/git_bug/issue')
6 files changed, 0 insertions, 602 deletions
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 <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::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<Value> 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<gix::Id<'_>> 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<Operation>, -} - -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<Operation>, -} 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 <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::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 <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::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 <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::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<Comment>, - pub status: Status, - pub last_status_change: TimeStamp, - pub labels: Vec<Label>, -} -impl From<RawCollapsedIssue> for CollapsedIssue { - fn from(r: RawCollapsedIssue) -> Self { - macro_rules! get { - ($name:ident) => { - r.$name.expect(concat!( - "'", - stringify!($name), - "' is unset, when trying to collapes an issue! (This is likely a bug)" - )) - }; - } - - Self { - id: get! {id}, - author: get! {author}, - timestamp: get! {timestamp}, - title: get! {title}, - message: get! {message}, - comments: r.comments, - status: get! {status}, - last_status_change: get! {last_status_change}, - labels: r.labels, - } - } -} - -#[derive(Debug)] -pub struct Comment { - pub id: Id, - pub author: Author, - pub timestamp: TimeStamp, - pub message: MarkDown, -} - -#[derive(Debug, Default)] -pub struct RawCollapsedIssue { - pub id: Option<Id>, - pub author: Option<Author>, - pub timestamp: Option<TimeStamp>, - pub title: Option<MarkDown>, - pub message: Option<MarkDown>, - pub status: Option<Status>, - pub last_status_change: Option<TimeStamp>, - - // NOTE(@bpeetz): These values set here already, because an issue without these - // would be perfectly valid. <2024-12-26> - pub labels: Vec<Label>, - pub comments: Vec<Comment>, -} - -impl RawCollapsedIssue { - pub fn append_entity(&mut self, entity: Entity) { - for op in entity.operations { - match op { - Operation::AddComment { timestamp, message } => { - self.comments.push(Comment { - id: entity.id.clone(), - author: entity.author.clone(), - timestamp, - message, - }); - } - Operation::Create { - timestamp, - title, - message, - } => { - self.id = Some(entity.id.clone()); - self.author = Some(entity.author.clone()); - self.timestamp = Some(timestamp); - self.title = Some(title); - self.message = Some(message); - self.status = Some(Status::Open); // This is the default in git_bug - self.last_status_change = Some(timestamp); - } - Operation::EditComment { - timestamp, - target, - message, - } => { - let comments = &mut self.comments; - - let target_comment = comments - .iter_mut() - .find(|comment| comment.id == target) - .expect("The target must be a valid comment"); - - // TODO(@bpeetz): We should probably set a `edited = true` flag here. <2024-12-26> - // TODO(@bpeetz): Should we also change the author? <2024-12-26> - - target_comment.timestamp = timestamp; - target_comment.message = message; - } - Operation::LabelChange { - timestamp: _, - added, - removed, - } => { - let labels = self.labels.clone(); - - self.labels = labels - .into_iter() - .filter(|val| !removed.contains(val)) - .chain(added.into_iter()) - .collect(); - } - Operation::SetStatus { timestamp, status } => { - self.status = Some(status); - self.last_status_change = Some(timestamp); - } - Operation::SetTitle { - timestamp: _, - title, - was: _, - } => { - self.title = Some(title); - } - - Operation::NoOp {} => unimplemented!(), - Operation::SetMetadata {} => unimplemented!(), - } - } - } -} diff --git a/pkgs/by-name/ba/back/src/git_bug/issue/operation/mod.rs b/pkgs/by-name/ba/back/src/git_bug/issue/operation/mod.rs deleted file mode 100644 index 7f861a7..0000000 --- a/pkgs/by-name/ba/back/src/git_bug/issue/operation/mod.rs +++ /dev/null @@ -1,124 +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::convert::Infallible; - -use operation_type::OperationType; -use serde::Deserialize; -use serde_json::Value; - -use crate::{ - get, - git_bug::format::{MarkDown, TimeStamp}, -}; - -use super::{entity, label::Label, Status}; - -pub mod operation_type; - -#[derive(Deserialize, Debug)] -#[serde(try_from = "Value")] -pub enum Operation { - AddComment { - timestamp: TimeStamp, - message: MarkDown, - }, - Create { - timestamp: TimeStamp, - title: MarkDown, - message: MarkDown, - }, - EditComment { - timestamp: TimeStamp, - target: entity::Id, - message: MarkDown, - }, - LabelChange { - timestamp: TimeStamp, - added: Vec<Label>, - removed: Vec<Label>, - }, - SetStatus { - timestamp: TimeStamp, - status: Status, - }, - SetTitle { - timestamp: TimeStamp, - title: MarkDown, - was: MarkDown, - }, - - // These seem to be just weird non-operation, operations. - // defined in: git-bug/entities/bug/operation.go - NoOp {}, - SetMetadata {}, -} - -impl TryFrom<Value> for Operation { - type Error = Infallible; - - fn try_from(value: Value) -> Result<Self, Self::Error> { - let operation_type = OperationType::from_json_int( - value - .get("type") - .expect("Should exist") - .as_u64() - .expect("This should work"), - ); - - let op = match operation_type { - OperationType::AddComment => Self::AddComment { - timestamp: get! {value, "timestamp" }, - message: get! {value, "message"}, - }, - OperationType::Create => Self::Create { - timestamp: get! {value, "timestamp"}, - title: get! {value, "title"}, - message: get! {value, "message"}, - }, - OperationType::EditComment => Self::EditComment { - timestamp: get! {value, "timestamp"}, - target: get! {value, "target"}, - message: get! {value, "message"}, - }, - OperationType::LabelChange => Self::LabelChange { - timestamp: get! {value, "timestamp"}, - added: serde_json::from_value( - value - .get("added") - .expect("This should be available") - .to_owned(), - ) - .expect("This should be parsable"), - removed: serde_json::from_value( - value - .get("removed") - .expect("This should be available") - .to_owned(), - ) - .expect("This should be parsable"), - }, - OperationType::SetStatus => Self::SetStatus { - timestamp: get! {value, "timestamp"}, - status: get! {value, "status"}, - }, - OperationType::SetTitle => Self::SetTitle { - timestamp: get! {value, "timestamp"}, - title: get! {value, "title"}, - was: get! {value, "was"}, - }, - OperationType::NoOp => Self::NoOp {}, - OperationType::SetMetadata => Self::SetMetadata {}, - }; - - Ok(op) - } -} diff --git a/pkgs/by-name/ba/back/src/git_bug/issue/operation/operation_type.rs b/pkgs/by-name/ba/back/src/git_bug/issue/operation/operation_type.rs deleted file mode 100644 index 69d272f..0000000 --- a/pkgs/by-name/ba/back/src/git_bug/issue/operation/operation_type.rs +++ /dev/null @@ -1,51 +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>. - -pub enum OperationType { - AddComment, - Create, - EditComment, - LabelChange, - NoOp, - SetMetadata, - SetStatus, - SetTitle, -} - -impl OperationType { - // NOTE(@bpeetz): This mapping should always be the same as `git_bug`'s. - // The mapping is defined in `git-bug/entities/bug/operation.go`. <2024-12-26> - pub fn to_json_int(self) -> u64 { - match self { - OperationType::Create => 1, - OperationType::SetTitle => 2, - OperationType::AddComment => 3, - OperationType::SetStatus => 4, - OperationType::LabelChange => 5, - OperationType::EditComment => 6, - OperationType::NoOp => 7, - OperationType::SetMetadata => 8, - } - } - pub fn from_json_int(value: u64) -> Self { - match value { - 1 => OperationType::Create, - 2 => OperationType::SetTitle, - 3 => OperationType::AddComment, - 4 => OperationType::SetStatus, - 5 => OperationType::LabelChange, - 6 => OperationType::EditComment, - 7 => OperationType::NoOp, - 8 => OperationType::SetMetadata, - other => unimplemented!("The operation type {other} is not recognized."), - } - } -} |