Skip to content

Commit

Permalink
add progress message to interactive mode (#1120)
Browse files Browse the repository at this point in the history
  • Loading branch information
aawsome authored Apr 16, 2024
1 parent 5cbf088 commit b6e9c1b
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 46 deletions.
47 changes: 37 additions & 10 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ use convert_case::{Case, Casing};
use dialoguer::Password;
use human_panic::setup_panic;
use log::{log, warn, Level};
use rustic_core::{IndexedFull, OpenStatus, Repository};
use rustic_core::{IndexedFull, OpenStatus, ProgressBars, Repository};
use simplelog::{CombinedLogger, LevelFilter, TermLogger, TerminalMode, WriteLogger};

pub(super) mod constants {
Expand Down Expand Up @@ -277,20 +277,32 @@ impl Configurable<RusticConfig> for EntryPoint {
}
}
}

/// Get the repository with the given options
///
/// # Arguments
///
/// * `repo_opts` - The repository options
///
fn get_repository(repo_opts: &AllRepositoryOptions) -> Result<Repository<ProgressOptions, ()>> {
let po = RUSTIC_APP.config().global.progress_options;
fn get_repository_with_progress<P>(
repo_opts: &AllRepositoryOptions,
po: P,
) -> Result<Repository<P, ()>> {
let backends = repo_opts.be.to_backends()?;
let repo = Repository::new_with_progress(&repo_opts.repo, &backends, po)?;
Ok(repo)
}

/// Get the repository with the given options
///
/// # Arguments
///
/// * `repo_opts` - The repository options
///
fn get_repository(repo_opts: &AllRepositoryOptions) -> Result<Repository<ProgressOptions, ()>> {
let po = RUSTIC_APP.config().global.progress_options;
get_repository_with_progress(repo_opts, po)
}

/// Open the repository with the given options
///
/// # Arguments
Expand All @@ -310,13 +322,14 @@ fn get_repository(repo_opts: &AllRepositoryOptions) -> Result<Repository<Progres
/// [`RepositoryErrorKind::PasswordCommandParsingFailed`]: crate::error::RepositoryErrorKind::PasswordCommandParsingFailed
/// [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`]: crate::error::RepositoryErrorKind::ReadingPasswordFromCommandFailed
/// [`RepositoryErrorKind::FromSplitError`]: crate::error::RepositoryErrorKind::FromSplitError
fn open_repository(
fn open_repository_with_progress<P: Clone>(
repo_opts: &AllRepositoryOptions,
) -> Result<Repository<ProgressOptions, OpenStatus>> {
po: P,
) -> Result<Repository<P, OpenStatus>> {
if RUSTIC_APP.config().global.check_index {
warn!("Option check-index is not supported and will be ignored!");
}
let repo = get_repository(repo_opts)?;
let repo = get_repository_with_progress(repo_opts, po)?;
match repo.password()? {
// if password is given, directly return the result of find_key_in_backend and don't retry
Some(pass) => {
Expand All @@ -339,11 +352,18 @@ fn open_repository(
Err(anyhow!("incorrect password"))
}

fn open_repository(
repo_opts: &AllRepositoryOptions,
) -> Result<Repository<ProgressOptions, OpenStatus>> {
let po = RUSTIC_APP.config().global.progress_options;
open_repository_with_progress(repo_opts, po)
}
/// helper function to get an opened and inedexed repo
fn open_repository_indexed(
fn open_repository_indexed_with_progress<P: Clone + ProgressBars>(
repo_opts: &AllRepositoryOptions,
) -> Result<Repository<ProgressOptions, impl IndexedFull + Debug>> {
let open = open_repository(repo_opts)?;
po: P,
) -> Result<Repository<P, impl IndexedFull + Debug>> {
let open = open_repository_with_progress(repo_opts, po)?;
let check_index = RUSTIC_APP.config().global.check_index;
let repo = if check_index {
open.to_indexed_checked()
Expand All @@ -353,6 +373,13 @@ fn open_repository_indexed(
Ok(repo)
}

fn open_repository_indexed(
repo_opts: &AllRepositoryOptions,
) -> Result<Repository<ProgressOptions, impl IndexedFull + Debug>> {
let po = RUSTIC_APP.config().global.progress_options;
open_repository_indexed_with_progress(repo_opts, po)
}

#[cfg(test)]
mod tests {
use crate::commands::EntryPoint;
Expand Down
32 changes: 20 additions & 12 deletions src/commands/tui.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
//! `tui` subcommand
mod ls;
mod progress;
mod snapshots;
mod widgets;

use progress::TuiProgressBars;
use snapshots::Snapshots;

use std::io;
use std::sync::{Arc, RwLock};

use crate::commands::open_repository_indexed;
use crate::commands::open_repository_indexed_with_progress;
use crate::{Application, RUSTIC_APP};

use abscissa_core::{status_err, Command, Runnable, Shutdown};
Expand All @@ -18,7 +21,7 @@ use crossterm::{
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::prelude::*;
use rustic_core::IndexedFull;
use rustic_core::{IndexedFull, ProgressBars};

/// `tui` subcommand
#[derive(clap::Parser, Command, Debug)]
Expand All @@ -33,35 +36,40 @@ impl Runnable for TuiCmd {
}
}

struct App<'a, S> {
snapshots: Snapshots<'a, S>,
struct App<'a, P, S> {
snapshots: Snapshots<'a, P, S>,
}

impl TuiCmd {
fn inner_run(&self) -> Result<()> {
let config = RUSTIC_APP.config();
let repo = open_repository_indexed(&config.repository)?;

// setup terminal
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
let terminal = Arc::new(RwLock::new(Terminal::new(backend)?));

let progress = TuiProgressBars {
terminal: terminal.clone(),
};
let repo = open_repository_indexed_with_progress(&config.repository, progress)?;
// create app and run it
let snapshots = Snapshots::new(&repo, config.snapshot_filter.clone())?;
let app = App { snapshots };
let res = run_app(&mut terminal, app);
let res = run_app(terminal.clone(), app);

// restore terminal
disable_raw_mode()?;
let mut terminal = terminal.write().unwrap();
execute!(
terminal.backend_mut(),
LeaveAlternateScreen,
DisableMouseCapture
)?;
terminal.show_cursor()?;
drop(terminal);

if let Err(err) = res {
println!("{err:?}");
Expand All @@ -71,12 +79,12 @@ impl TuiCmd {
}
}

fn run_app<B: Backend, S: IndexedFull>(
terminal: &mut Terminal<B>,
mut app: App<'_, S>,
fn run_app<B: Backend, P: ProgressBars, S: IndexedFull>(
terminal: Arc<RwLock<Terminal<B>>>,
mut app: App<'_, P, S>,
) -> Result<()> {
loop {
_ = terminal.draw(|f| ui(f, &mut app))?;
_ = terminal.write().unwrap().draw(|f| ui(f, &mut app))?;
let event = event::read()?;
use KeyCode::*;

Expand All @@ -91,7 +99,7 @@ fn run_app<B: Backend, S: IndexedFull>(
}
}

fn ui<S: IndexedFull>(f: &mut Frame<'_>, app: &mut App<'_, S>) {
fn ui<P: ProgressBars, S: IndexedFull>(f: &mut Frame<'_>, app: &mut App<'_, P, S>) {
let area = f.size();
app.snapshots.draw(area, f);
}
29 changes: 16 additions & 13 deletions src/commands/tui/ls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@ use crossterm::event::{Event, KeyCode, KeyEventKind};
use ratatui::{prelude::*, widgets::*};
use rustic_core::{
repofile::{Node, SnapshotFile, Tree},
IndexedFull, Repository,
IndexedFull, ProgressBars, Repository,
};
use style::palette::tailwind;

use crate::{
commands::{
ls::{NodeLs, Summary},
tui::widgets::{popup_text, Draw, PopUpText, ProcessEvent, SelectTable, WithBlock},
},
config::progress_options::ProgressOptions,
use crate::commands::{
ls::{NodeLs, Summary},
tui::widgets::{popup_text, Draw, PopUpText, ProcessEvent, SelectTable, WithBlock},
};

// the states this screen can be in
Expand All @@ -37,18 +34,18 @@ General Commands:
"#;

pub(crate) struct Snapshot<'a, S> {
pub(crate) struct Snapshot<'a, P, S> {
current_screen: CurrentScreen,
numeric: bool,
table: WithBlock<SelectTable>,
repo: &'a Repository<ProgressOptions, S>,
repo: &'a Repository<P, S>,
snapshot: SnapshotFile,
path: PathBuf,
trees: Vec<Tree>,
}

impl<'a, S: IndexedFull> Snapshot<'a, S> {
pub fn new(repo: &'a Repository<ProgressOptions, S>, snapshot: SnapshotFile) -> Result<Self> {
impl<'a, P: ProgressBars, S: IndexedFull> Snapshot<'a, P, S> {
pub fn new(repo: &'a Repository<P, S>, snapshot: SnapshotFile) -> Result<Self> {
let header = ["Name", "Size", "Mode", "User", "Group", "Time"]
.into_iter()
.map(Text::from)
Expand Down Expand Up @@ -98,8 +95,12 @@ impl<'a, S: IndexedFull> Snapshot<'a, S> {
}

pub fn update_table(&mut self) {
let old_selection = self.table.widget.selected();
let tree = self.trees.last().unwrap();
let old_selection = if tree.nodes.is_empty() {
None
} else {
Some(self.table.widget.selected().unwrap_or_default())
};
let mut rows = Vec::new();
let mut summary = Summary::default();
for node in &tree.nodes {
Expand All @@ -126,7 +127,7 @@ impl<'a, S: IndexedFull> Snapshot<'a, S> {
}
))
.title_alignment(Alignment::Center);
self.table.widget.set_to(old_selection.unwrap_or_default());
self.table.widget.select(old_selection);
}

pub fn enter(&mut self) -> Result<()> {
Expand All @@ -137,6 +138,7 @@ impl<'a, S: IndexedFull> Snapshot<'a, S> {
self.trees.push(self.repo.get_tree(&node.subtree.unwrap())?);
}
}
self.table.widget.set_to(0);
self.update_table();
Ok(())
}
Expand All @@ -145,6 +147,7 @@ impl<'a, S: IndexedFull> Snapshot<'a, S> {
_ = self.path.pop();
_ = self.trees.pop();
if !self.trees.is_empty() {
self.table.widget.set_to(0);
self.update_table();
}
self.trees.is_empty()
Expand Down
Loading

0 comments on commit b6e9c1b

Please sign in to comment.