From 344bb8aa34183be2ee56ef42763582840ef7d598 Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Thu, 18 Dec 2025 17:24:11 +0100 Subject: [PATCH] bin/patch: Reorganize cob-specific and common code --- bin/cob.rs | 15 ++++++++++++++- bin/cob/patch.rs | 31 ------------------------------ bin/commands/patch.rs | 26 ++++++++++++------------- bin/commands/patch/common.rs | 12 ------------ bin/commands/patch/list.rs | 37 ++++++++++++++++++++++-------------- bin/commands/patch/review.rs | 4 ++-- 6 files changed, 52 insertions(+), 73 deletions(-) delete mode 100644 bin/cob/patch.rs delete mode 100644 bin/commands/patch/common.rs diff --git a/bin/cob.rs b/bin/cob.rs index a5dfc54b..8f2dde19 100644 --- a/bin/cob.rs +++ b/bin/cob.rs @@ -1,2 +1,15 @@ +use radicle::node::device::Device; +use radicle::patch::{Patch, Review, ReviewId, Revision}; + pub mod issue; -pub mod patch; + +pub fn find_review<'a, G>( + patch: &'a Patch, + revision: &Revision, + signer: &Device, +) -> Option<(ReviewId, &'a Review)> { + patch + .reviews_of(revision.id()) + .find(|(_, review)| review.author().public_key() == signer.public_key()) + .map(|(id, review)| (*id, review)) +} diff --git a/bin/cob/patch.rs b/bin/cob/patch.rs deleted file mode 100644 index 58a46813..00000000 --- a/bin/cob/patch.rs +++ /dev/null @@ -1,31 +0,0 @@ -use anyhow::Result; - -use radicle::cob::patch::{Patch, PatchId}; -use radicle::node::device::Device; -use radicle::patch::cache::Patches; -use radicle::patch::{Review, ReviewId, Revision}; -use radicle::storage::git::Repository; -use radicle::Profile; - -pub fn all(profile: &Profile, repository: &Repository) -> Result> { - let cache = profile.patches(repository)?; - let patches = cache.list()?; - - Ok(patches.flatten().collect()) -} - -pub fn find(profile: &Profile, repository: &Repository, id: &PatchId) -> Result> { - let cache = profile.patches(repository)?; - Ok(cache.get(id)?) -} - -pub fn find_review<'a, G>( - patch: &'a Patch, - revision: &Revision, - signer: &Device, -) -> Option<(ReviewId, &'a Review)> { - patch - .reviews_of(revision.id()) - .find(|(_, review)| review.author().public_key() == signer.public_key()) - .map(|(id, review)| (*id, review)) -} diff --git a/bin/commands/patch.rs b/bin/commands/patch.rs index 34b5699d..c5aebdbb 100644 --- a/bin/commands/patch.rs +++ b/bin/commands/patch.rs @@ -1,5 +1,3 @@ -#[path = "patch/common.rs"] -mod common; #[path = "patch/list.rs"] mod list; #[path = "patch/review.rs"] @@ -11,6 +9,7 @@ use anyhow::anyhow; use radicle::cob::ObjectId; use radicle::identity::RepoId; +use radicle::prelude::Did; use radicle::patch::{Patch, Revision, RevisionId, Status}; use radicle::storage::git::Repository; @@ -18,7 +17,6 @@ use radicle_cli::git::Rev; use radicle_cli::terminal::args; use radicle_cli::terminal::args::{string, Args, Error, Help}; -use crate::commands::tui_patch::common::PatchOperation; use crate::terminal; use crate::terminal::Quiet; use crate::ui::items::patch::filter::PatchFilter; @@ -236,6 +234,7 @@ impl Args for Options { #[tokio::main] pub async fn run(options: Options, ctx: impl radicle_cli::terminal::Context) -> anyhow::Result<()> { + use crate::tui_patch::list::PatchOperation; use radicle::storage::ReadStorage; let (_, rid) = radicle::rad::cwd() @@ -324,10 +323,10 @@ pub async fn run(options: Options, ctx: impl radicle_cli::terminal::Context) -> mod interface { use anyhow::anyhow; - use radicle::cob; + use radicle::cob::patch::cache::Patches; use radicle::identity::RepoId; - use radicle::patch::PatchId; - use radicle::patch::Verdict; + use radicle::patch; + use radicle::patch::{PatchId, Verdict}; use radicle::storage::git::cob::DraftStore; use radicle::storage::ReadStorage; use radicle::Profile; @@ -336,8 +335,7 @@ mod interface { use radicle_tui::Selection; - use crate::cob::patch; - use crate::commands::tui_patch::common::PatchOperation; + use crate::cob; use crate::tui_patch::list; use crate::tui_patch::review::builder::CommentBuilder; use crate::tui_patch::review::ReviewAction; @@ -351,7 +349,7 @@ mod interface { opts: ListOptions, profile: Profile, rid: RepoId, - ) -> anyhow::Result>> { + ) -> anyhow::Result>> { let repository = profile.storage.repository(rid).unwrap(); log::info!("Starting patch selection interface in project {rid}.."); @@ -373,14 +371,16 @@ mod interface { ) -> anyhow::Result<()> { let repo = profile.storage.repository(rid)?; let signer = terminal::signer(&profile)?; + let cache = profile.patches(&repo)?; - let patch = patch::find(&profile, &repo, &patch_id)? + let patch = cache + .get(&patch_id)? .ok_or_else(|| anyhow!("Patch `{patch_id}` not found"))?; let (_, revision) = opts.revision_or_latest(&patch, &repo)?; let hunks = ReviewBuilder::new(&repo).hunks(revision)?; let drafts = DraftStore::new(&repo, *signer.public_key()); - let mut patches = cob::patch::Cache::no_cache(&drafts)?; + let mut patches = patch::Cache::no_cache(&drafts)?; let mut patch = patches.get_mut(&patch_id)?; if let Some(review) = revision.review_by(signer.public_key()) { @@ -394,7 +394,7 @@ mod interface { }; let mode = if opts.edit { - if let Some((id, _)) = patch::find_review(&patch, revision, &signer) { + if let Some((id, _)) = cob::find_review(&patch, revision, &signer) { // Review already started, resume. log::info!("Resuming review {id}.."); @@ -422,7 +422,7 @@ mod interface { loop { // Reload review let signer = profile.signer()?; - let (review_id, review) = patch::find_review(&patch, revision, &signer) + let (review_id, review) = cob::find_review(&patch, revision, &signer) .ok_or_else(|| anyhow!("Could not find review."))?; let response = review::Tui::new( diff --git a/bin/commands/patch/common.rs b/bin/commands/patch/common.rs deleted file mode 100644 index 96185b5f..00000000 --- a/bin/commands/patch/common.rs +++ /dev/null @@ -1,12 +0,0 @@ -use radicle::patch::PatchId; -use serde::Serialize; - -/// The selected patch operation returned by the operation -/// selection widget. -#[derive(Clone, Debug, Eq, PartialEq, Serialize)] -pub enum PatchOperation { - Checkout { id: PatchId }, - Diff { id: PatchId }, - Show { id: PatchId }, - _Review { id: PatchId }, -} diff --git a/bin/commands/patch/list.rs b/bin/commands/patch/list.rs index 7b76ca23..c04978ba 100644 --- a/bin/commands/patch/list.rs +++ b/bin/commands/patch/list.rs @@ -3,6 +3,8 @@ use std::sync::{Arc, Mutex}; use anyhow::Result; +use radicle::patch::cache::Patches; +use radicle::patch::PatchId; use radicle::storage::git::Repository; use radicle::Profile; @@ -13,6 +15,7 @@ use ratatui::{Frame, Viewport}; use radicle_tui as tui; +use serde::Serialize; use tui::event::Key; use tui::store; use tui::task::EmptyProcessors; @@ -23,9 +26,6 @@ use tui::ui::im::Show; use tui::ui::{BufferedValue, Column, Spacing}; use tui::{Channel, Exit}; -use super::common::PatchOperation; - -use crate::cob::patch; use crate::ui::items::filter::Filter; use crate::ui::items::patch::filter::PatchFilter; use crate::ui::items::patch::Patch; @@ -54,6 +54,16 @@ const HELP: &str = r#"# Generic keybindings Pattern: is: | is:authored | authors:[, ] | Example: is:open is:authored improve"#; +/// The selected patch operation returned by the operation +/// selection widget. +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub enum PatchOperation { + Checkout { id: PatchId }, + Diff { id: PatchId }, + Show { id: PatchId }, + _Review { id: PatchId }, +} + type Selection = tui::Selection; pub struct Context { @@ -135,22 +145,21 @@ impl TryFrom<&Context> for App { type Error = anyhow::Error; fn try_from(context: &Context) -> Result { - let patches = patch::all(&context.profile, &context.repository)?; + let cache = &context.profile.patches(&context.repository)?; + let mut patches = cache + .list()? + .filter_map(|patch| patch.ok()) + .flat_map(|patch| Patch::new(&context.profile, &context.repository, patch.clone()).ok()) + .collect::>(); + patches.sort_by(|a, b| b.timestamp.cmp(&a.timestamp)); + let search = { let raw = context.filter.to_string(); raw.trim().to_string() }; - let filter = PatchFilter::from_str(&context.filter.to_string()).unwrap_or_default(); - - let mut items = patches - .into_iter() - .flat_map(|patch| Patch::new(&context.profile, &context.repository, patch.clone()).ok()) - .collect::>(); - - items.sort_by(|a, b| b.timestamp.cmp(&a.timestamp)); Ok(App { - patches: Arc::new(Mutex::new(items.clone())), + patches: Arc::new(Mutex::new(patches.clone())), state: AppState { page: Page::Main, main_group: ContainerState::new(3, Some(0)), @@ -161,7 +170,7 @@ impl TryFrom<&Context> for App { }), show_search: false, help: TextViewState::new(Position::default()), - filter, + filter: PatchFilter::from_str(&context.filter.to_string()).unwrap_or_default(), }, }) } diff --git a/bin/commands/patch/review.rs b/bin/commands/patch/review.rs index c1702322..215e3007 100644 --- a/bin/commands/patch/review.rs +++ b/bin/commands/patch/review.rs @@ -717,7 +717,7 @@ mod test { use radicle::storage::git::cob::DraftStore; use radicle::storage::git::Repository; - use crate::cob::patch; + use crate::cob; use crate::test::setup::NodeWithRepo; use super::builder::ReviewBuilder; @@ -762,7 +762,7 @@ mod test { &node.node.signer, )?; - let (_, review) = patch::find_review(draft, revision, &node.node.signer) + let (_, review) = cob::find_review(draft, revision, &node.node.signer) .ok_or_else(|| anyhow!("Could not find review."))?; Ok((id, review))