Radish alpha
r
Radicle terminal user interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
bin: Pass review instance to `patch review`
Erik Kundt committed 1 year ago
commit d983b7ccd6d58324922a9757404077014e6a7044
parent 1cff69d7ea910bd0c0f437f3270d2a1423f41d27
5 files changed +82 -62
modified bin/cob.rs
@@ -21,7 +21,7 @@ pub mod inbox;
pub mod issue;
pub mod patch;

-
pub type IndexedReviewItem = (usize, crate::cob::ReviewItem);
+
pub type IndexedHunkItem = (usize, crate::cob::HunkItem);

#[allow(dead_code)]
pub fn parse_labels(input: String) -> Result<Vec<Label>> {
@@ -93,7 +93,7 @@ impl From<&Hunk<Modification>> for HunkStats {
/// A single review item. Can be a hunk or eg. a file move.
/// Files are usually split into multiple review items.
#[derive(Clone, Debug)]
-
pub enum ReviewItem {
+
pub enum HunkItem {
    FileAdded {
        path: PathBuf,
        new: DiffFile,
@@ -132,7 +132,7 @@ pub enum ReviewItem {
    },
}

-
impl ReviewItem {
+
impl HunkItem {
    pub fn hunk(&self) -> Option<&Hunk<Modification>> {
        match self {
            Self::FileAdded { hunk, .. } => hunk.as_ref(),
modified bin/commands/patch.rs
@@ -381,7 +381,7 @@ mod interface {
                review.comments().collect::<Vec<_>>()
            );

-
            let selection = review::Tui::new(profile.clone(), rid, queue.clone())
+
            let selection = review::Tui::new(profile.clone(), rid, review.clone(), queue.clone())
                .run()
                .await?;
            log::info!("Received selection from TUI: {:?}", selection);
modified bin/commands/patch/review.rs
@@ -8,6 +8,7 @@ use std::sync::Mutex;

use anyhow::Result;

+
use radicle::patch::Review;
use ratatui::layout::Position;
use ratatui::style::Stylize;
use ratatui::text::Text;
@@ -31,7 +32,7 @@ use tui::ui::im::{Borders, Context, Show};
use tui::ui::Column;
use tui::{Channel, Exit};

-
use crate::ui::items::ReviewItem;
+
use crate::ui::items::HunkItem;

use self::builder::ReviewQueue;

@@ -79,14 +80,16 @@ pub struct Selection {
pub struct Tui {
    pub profile: Profile,
    pub rid: RepoId,
+
    pub review: Review,
    pub queue: ReviewQueue,
}

impl Tui {
-
    pub fn new(profile: Profile, rid: RepoId, queue: ReviewQueue) -> Self {
+
    pub fn new(profile: Profile, rid: RepoId, review: Review, queue: ReviewQueue) -> Self {
        Self {
            rid,
            profile,
+
            review,
            queue,
        }
    }
@@ -95,7 +98,12 @@ impl Tui {
        let viewport = Viewport::Fullscreen;

        let channel = Channel::default();
-
        let state = App::new(self.profile.clone(), self.rid, self.queue.clone())?;
+
        let state = App::new(
+
            self.profile.clone(),
+
            self.rid,
+
            self.review.clone(),
+
            self.queue.clone(),
+
        )?;

        tui::im(state, viewport, channel).await
    }
@@ -132,7 +140,8 @@ pub struct ReviewItemState {
#[derive(Clone)]
pub struct App<'a> {
    repository: Arc<Mutex<Repository>>,
-
    queue: Arc<Mutex<(Vec<ReviewItem<'a>>, TableState)>>,
+
    review: Arc<Mutex<Review>>,
+
    queue: Arc<Mutex<(Vec<HunkItem<'a>>, TableState)>>,
    items: HashMap<usize, ReviewItemState>,
    page: AppPage,
    windows: GroupState,
@@ -143,17 +152,27 @@ impl<'a> TryFrom<&Tui> for App<'a> {
    type Error = anyhow::Error;

    fn try_from(tui: &Tui) -> Result<Self, Self::Error> {
-
        App::new(tui.profile.clone(), tui.rid, tui.queue.clone())
+
        App::new(
+
            tui.profile.clone(),
+
            tui.rid,
+
            tui.review.clone(),
+
            tui.queue.clone(),
+
        )
    }
}

impl<'a> App<'a> {
-
    pub fn new(profile: Profile, rid: RepoId, queue: ReviewQueue) -> Result<Self, anyhow::Error> {
+
    pub fn new(
+
        profile: Profile,
+
        rid: RepoId,
+
        review: Review,
+
        queue: ReviewQueue,
+
    ) -> Result<Self, anyhow::Error> {
        let repository = profile.storage.repository(rid)?;

        let queue = queue
            .iter()
-
            .map(|item| ReviewItem::from((&repository, item)))
+
            .map(|item| HunkItem::from((&repository, item)))
            .collect::<Vec<_>>();

        let mut items = HashMap::new();
@@ -173,6 +192,7 @@ impl<'a> App<'a> {
            help: HelpState {
                text: TextViewState::new(help_text(), Position::default()),
            },
+
            review: Arc::new(Mutex::new(review)),
            queue: Arc::new(Mutex::new((queue, TableState::new(Some(0))))),
            items,
        })
modified bin/commands/patch/review/builder.rs
@@ -37,7 +37,7 @@ use radicle_cli::git::unified_diff::{Encode, HunkHeader};
use radicle_cli::terminal as term;
use radicle_cli::terminal::highlight::Highlighter;

-
use crate::cob::ReviewItem;
+
use crate::cob::HunkItem;

/// Help message shown to user.
const HELP: &str = "\
@@ -142,7 +142,7 @@ impl FromStr for ReviewAction {
#[derive(Clone, Default)]
pub struct ReviewQueue {
    /// Hunks left to review.
-
    queue: VecDeque<(usize, ReviewItem)>,
+
    queue: VecDeque<(usize, HunkItem)>,
}

impl ReviewQueue {
@@ -151,13 +151,13 @@ impl ReviewQueue {
    fn add_file(&mut self, file: FileDiff) {
        match file {
            FileDiff::Moved(moved) => {
-
                self.add_item(ReviewItem::FileMoved { moved });
+
                self.add_item(HunkItem::FileMoved { moved });
            }
            FileDiff::Copied(copied) => {
-
                self.add_item(ReviewItem::FileCopied { copied });
+
                self.add_item(HunkItem::FileCopied { copied });
            }
            FileDiff::Added(a) => {
-
                self.add_item(ReviewItem::FileAdded {
+
                self.add_item(HunkItem::FileAdded {
                    path: a.path,
                    new: a.new,
                    hunk: if let DiffContent::Plain {
@@ -173,7 +173,7 @@ impl ReviewQueue {
                });
            }
            FileDiff::Deleted(d) => {
-
                self.add_item(ReviewItem::FileDeleted {
+
                self.add_item(HunkItem::FileDeleted {
                    path: d.path,
                    old: d.old,
                    hunk: if let DiffContent::Plain {
@@ -190,7 +190,7 @@ impl ReviewQueue {
            }
            FileDiff::Modified(m) => {
                if m.old.mode != m.new.mode {
-
                    self.add_item(ReviewItem::FileModeChanged {
+
                    self.add_item(HunkItem::FileModeChanged {
                        path: m.path.clone(),
                        old: m.old.clone(),
                        new: m.new.clone(),
@@ -201,7 +201,7 @@ impl ReviewQueue {
                        // Likely a file mode change, which is handled above.
                    }
                    DiffContent::Binary => {
-
                        self.add_item(ReviewItem::FileModified {
+
                        self.add_item(HunkItem::FileModified {
                            path: m.path.clone(),
                            old: m.old.clone(),
                            new: m.new.clone(),
@@ -215,7 +215,7 @@ impl ReviewQueue {
                        stats,
                    } => {
                        for hunk in hunks {
-
                            self.add_item(ReviewItem::FileModified {
+
                            self.add_item(HunkItem::FileModified {
                                path: m.path.clone(),
                                old: m.old.clone(),
                                new: m.new.clone(),
@@ -224,7 +224,7 @@ impl ReviewQueue {
                            });
                        }
                        if let EofNewLine::OldMissing | EofNewLine::NewMissing = eof {
-
                            self.add_item(ReviewItem::FileEofChanged {
+
                            self.add_item(HunkItem::FileEofChanged {
                                path: m.path.clone(),
                                old: m.old.clone(),
                                new: m.new.clone(),
@@ -237,7 +237,7 @@ impl ReviewQueue {
        }
    }

-
    fn add_item(&mut self, item: ReviewItem) {
+
    fn add_item(&mut self, item: HunkItem) {
        self.queue.push_back((self.queue.len(), item));
    }
}
@@ -253,7 +253,7 @@ impl From<Diff> for ReviewQueue {
}

impl std::ops::Deref for ReviewQueue {
-
    type Target = VecDeque<(usize, ReviewItem)>;
+
    type Target = VecDeque<(usize, HunkItem)>;

    fn deref(&self) -> &Self::Target {
        &self.queue
@@ -267,7 +267,7 @@ impl std::ops::DerefMut for ReviewQueue {
}

impl Iterator for ReviewQueue {
-
    type Item = (usize, ReviewItem);
+
    type Item = (usize, HunkItem);

    fn next(&mut self) -> Option<Self::Item> {
        self.queue.pop_front()
@@ -281,16 +281,16 @@ pub struct FileReviewBuilder {
}

impl FileReviewBuilder {
-
    fn new(item: &ReviewItem) -> Self {
+
    fn new(item: &HunkItem) -> Self {
        Self { delta: 0 }
    }

-
    fn set_item(&mut self, item: &ReviewItem) -> &mut Self {
+
    fn set_item(&mut self, item: &HunkItem) -> &mut Self {
        self.delta = 0;
        self
    }

-
    fn ignore_item(&mut self, item: &ReviewItem) {
+
    fn ignore_item(&mut self, item: &HunkItem) {
        if let Some(h) = item.hunk_header() {
            self.delta += h.new_size as i32 - h.old_size as i32;
        }
modified bin/ui/items.rs
@@ -41,7 +41,7 @@ use tui::ui::theme::style;
use tui::ui::{span, Column};
use tui::ui::{ToRow, ToTree};

-
use crate::cob::{DiffStats, HunkStats, IndexedReviewItem};
+
use crate::cob::{DiffStats, HunkStats, IndexedHunkItem};
use crate::git::{Blob, Repo};

use super::super::git;
@@ -1040,13 +1040,13 @@ impl<'a> Into<Line<'a>> for TermLine {
}

#[derive(Clone, Debug)]
-
pub struct ReviewItem<'a> {
-
    pub inner: IndexedReviewItem,
+
pub struct HunkItem<'a> {
+
    pub inner: IndexedHunkItem,
    pub highlighted: Blobs<Vec<Line<'a>>>,
}

-
impl<'a> From<(&Repository, &IndexedReviewItem)> for ReviewItem<'a> {
-
    fn from(value: (&Repository, &IndexedReviewItem)) -> Self {
+
impl<'a> From<(&Repository, &IndexedHunkItem)> for HunkItem<'a> {
+
    fn from(value: (&Repository, &IndexedHunkItem)) -> Self {
        let (repo, item) = value;
        let hi = Highlighter::default();

@@ -1059,9 +1059,9 @@ impl<'a> From<(&Repository, &IndexedReviewItem)> for ReviewItem<'a> {
    }
}

-
impl<'a> ToRow<3> for ReviewItem<'a> {
+
impl<'a> ToRow<3> for HunkItem<'a> {
    fn to_row(&self) -> [Cell; 3] {
-
        use crate::cob::ReviewItem as Item;
+
        use crate::cob::HunkItem as Item;

        let build_stats_spans = |stats: &DiffStats| -> Vec<Span<'_>> {
            let mut cell = vec![];
@@ -1108,7 +1108,7 @@ impl<'a> ToRow<3> for ReviewItem<'a> {

                [
                    span::secondary("?").into(),
-
                    ReviewItem::pretty_path(path, false).into(),
+
                    HunkItem::pretty_path(path, false).into(),
                    Line::from(stats_cell).right_aligned().into(),
                ]
            }
@@ -1134,7 +1134,7 @@ impl<'a> ToRow<3> for ReviewItem<'a> {

                [
                    span::secondary("?").into(),
-
                    ReviewItem::pretty_path(path, false).into(),
+
                    HunkItem::pretty_path(path, false).into(),
                    Line::from(stats_cell).right_aligned().into(),
                ]
            }
@@ -1159,7 +1159,7 @@ impl<'a> ToRow<3> for ReviewItem<'a> {

                [
                    span::secondary("?").into(),
-
                    ReviewItem::pretty_path(path, true).into(),
+
                    HunkItem::pretty_path(path, true).into(),
                    Line::from(stats_cell).right_aligned().into(),
                ]
            }
@@ -1177,7 +1177,7 @@ impl<'a> ToRow<3> for ReviewItem<'a> {

                [
                    span::secondary("?").into(),
-
                    ReviewItem::pretty_path(&copied.new_path, false).into(),
+
                    HunkItem::pretty_path(&copied.new_path, false).into(),
                    Line::from(stats_cell).right_aligned().into(),
                ]
            }
@@ -1195,7 +1195,7 @@ impl<'a> ToRow<3> for ReviewItem<'a> {

                [
                    span::secondary("?").into(),
-
                    ReviewItem::pretty_path(&moved.new_path, false).into(),
+
                    HunkItem::pretty_path(&moved.new_path, false).into(),
                    Line::from(stats_cell).right_aligned().into(),
                ]
            }
@@ -1209,7 +1209,7 @@ impl<'a> ToRow<3> for ReviewItem<'a> {
                },
            ) => [
                span::secondary("?").into(),
-
                ReviewItem::pretty_path(path, false).into(),
+
                HunkItem::pretty_path(path, false).into(),
                span::default("EOF ")
                    .light_blue()
                    .into_right_aligned_line()
@@ -1224,7 +1224,7 @@ impl<'a> ToRow<3> for ReviewItem<'a> {
                },
            ) => [
                span::secondary("?").into(),
-
                ReviewItem::pretty_path(path, false).into(),
+
                HunkItem::pretty_path(path, false).into(),
                span::default("FM ")
                    .light_blue()
                    .into_right_aligned_line()
@@ -1234,7 +1234,7 @@ impl<'a> ToRow<3> for ReviewItem<'a> {
    }
}

-
impl<'a> ReviewItem<'a> {
+
impl<'a> HunkItem<'a> {
    pub fn pretty_path(path: &Path, crossed_out: bool) -> Line<'a> {
        let file = path.file_name().unwrap_or_default();
        let path = if path.iter().count() > 1 {
@@ -1264,19 +1264,19 @@ impl<'a> ReviewItem<'a> {
    }
}

-
impl<'a> ReviewItem<'a> {
+
impl<'a> HunkItem<'a> {
    pub fn header(&self) -> Vec<Column<'a>> {
        match &self.inner {
            (
                _,
-
                crate::cob::ReviewItem::FileAdded {
+
                crate::cob::HunkItem::FileAdded {
                    path,
                    new: _,
                    hunk: _,
                    _stats: _,
                },
            ) => {
-
                let path = ReviewItem::pretty_path(path, false);
+
                let path = HunkItem::pretty_path(path, false);
                let header = [
                    Column::new("", Constraint::Length(0)),
                    Column::new(path.clone(), Constraint::Length(path.width() as u16)),
@@ -1294,7 +1294,7 @@ impl<'a> ReviewItem<'a> {
            }
            (
                _,
-
                crate::cob::ReviewItem::FileModified {
+
                crate::cob::HunkItem::FileModified {
                    path,
                    old: _,
                    new: _,
@@ -1302,7 +1302,7 @@ impl<'a> ReviewItem<'a> {
                    _stats: _,
                },
            ) => {
-
                let path = ReviewItem::pretty_path(path, false);
+
                let path = HunkItem::pretty_path(path, false);
                let header = [
                    Column::new("", Constraint::Length(0)),
                    Column::new(path.clone(), Constraint::Length(path.width() as u16)),
@@ -1320,14 +1320,14 @@ impl<'a> ReviewItem<'a> {
            }
            (
                _,
-
                crate::cob::ReviewItem::FileDeleted {
+
                crate::cob::HunkItem::FileDeleted {
                    path,
                    old: _,
                    hunk: _,
                    _stats: _,
                },
            ) => {
-
                let path = ReviewItem::pretty_path(path, true);
+
                let path = HunkItem::pretty_path(path, true);
                let header = [
                    Column::new("", Constraint::Length(0)),
                    Column::new(path.clone(), Constraint::Length(path.width() as u16)),
@@ -1343,12 +1343,12 @@ impl<'a> ReviewItem<'a> {

                header.to_vec()
            }
-
            (_, crate::cob::ReviewItem::FileCopied { copied }) => {
+
            (_, crate::cob::HunkItem::FileCopied { copied }) => {
                let path = Line::from(
                    [
-
                        ReviewItem::pretty_path(&copied.old_path, false).spans,
+
                        HunkItem::pretty_path(&copied.old_path, false).spans,
                        [span::default(" -> ")].to_vec(),
-
                        ReviewItem::pretty_path(&copied.new_path, false).spans,
+
                        HunkItem::pretty_path(&copied.new_path, false).spans,
                    ]
                    .concat()
                    .to_vec(),
@@ -1368,12 +1368,12 @@ impl<'a> ReviewItem<'a> {

                header.to_vec()
            }
-
            (_, crate::cob::ReviewItem::FileMoved { moved }) => {
+
            (_, crate::cob::HunkItem::FileMoved { moved }) => {
                let path = Line::from(
                    [
-
                        ReviewItem::pretty_path(&moved.old_path, false).spans,
+
                        HunkItem::pretty_path(&moved.old_path, false).spans,
                        [span::default(" -> ")].to_vec(),
-
                        ReviewItem::pretty_path(&moved.new_path, false).spans,
+
                        HunkItem::pretty_path(&moved.new_path, false).spans,
                    ]
                    .concat()
                    .to_vec(),
@@ -1395,14 +1395,14 @@ impl<'a> ReviewItem<'a> {
            }
            (
                _,
-
                crate::cob::ReviewItem::FileEofChanged {
+
                crate::cob::HunkItem::FileEofChanged {
                    path,
                    old: _,
                    new: _,
                    _eof: _,
                },
            ) => {
-
                let path = ReviewItem::pretty_path(&path, false);
+
                let path = HunkItem::pretty_path(&path, false);
                let header = [
                    Column::new("", Constraint::Length(0)),
                    Column::new(path.clone(), Constraint::Length(path.width() as u16)),
@@ -1419,13 +1419,13 @@ impl<'a> ReviewItem<'a> {
            }
            (
                _,
-
                crate::cob::ReviewItem::FileModeChanged {
+
                crate::cob::HunkItem::FileModeChanged {
                    path,
                    old: _,
                    new: _,
                },
            ) => {
-
                let path = ReviewItem::pretty_path(&path, false);
+
                let path = HunkItem::pretty_path(&path, false);
                let header = [
                    Column::new("", Constraint::Length(0)),
                    Column::new(path.clone(), Constraint::Length(path.width() as u16)),
@@ -1447,7 +1447,7 @@ impl<'a> ReviewItem<'a> {
        match &self.inner {
            (
                _,
-
                crate::cob::ReviewItem::FileAdded {
+
                crate::cob::HunkItem::FileAdded {
                    path: _,
                    new: _,
                    hunk,
@@ -1458,7 +1458,7 @@ impl<'a> ReviewItem<'a> {
                .map(|hunk| Text::from(hunk.to_text(&self.highlighted, repo.raw()))),
            (
                _,
-
                crate::cob::ReviewItem::FileModified {
+
                crate::cob::HunkItem::FileModified {
                    path: _,
                    old: _,
                    new: _,
@@ -1470,7 +1470,7 @@ impl<'a> ReviewItem<'a> {
                .map(|hunk| Text::from(hunk.to_text(&self.highlighted, repo.raw()))),
            (
                _,
-
                crate::cob::ReviewItem::FileDeleted {
+
                crate::cob::HunkItem::FileDeleted {
                    path: _,
                    old: _,
                    hunk,