summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-08-02 15:51:47 +0200
committerrabite <rabite@posteo.de>2019-08-02 15:51:47 +0200
commitd42f7d328c53e010cf28153a25168368b8b0376c (patch)
tree806d338bcd6f3cfdba07a93a31bf6754e09d00c0
parentefde265f3a3db049eefe9db08174ba8f7665f717 (diff)
config updater (auto and manual)
-rw-r--r--src/config_installer.rs80
-rw-r--r--src/file_browser.rs8
-rw-r--r--src/main.rs31
3 files changed, 98 insertions, 21 deletions
diff --git a/src/config_installer.rs b/src/config_installer.rs
index 5ca9282..4a2ca76 100644
--- a/src/config_installer.rs
+++ b/src/config_installer.rs
@@ -4,7 +4,7 @@ use std::process::Command;
use std::ffi::OsStr;
use std::path::Path;
-use crate::fail::{HError, HResult};
+use crate::fail::{HError, HResult, ErrorLog};
use crate::widget::WidgetCore;
@@ -77,16 +77,18 @@ fn install_config_all() -> HResult<()> {
Ok(())
}
-fn move_dir(from: &str, to: &Path) -> HResult<()> {
- let success = Command::new("mv")
+fn copy(from: &Path, to: &Path) -> HResult<()> {
+ // Uses -a flag to preserve symlinks
+ let success = Command::new("cp")
+ .arg("-a")
.arg(from)
.arg(to.as_os_str())
.status()
.map(|s| s.success());
if success.is_err() || !success.unwrap() {
- HError::log(&format!("Couldn't move {} to {} !",
- from,
+ HError::log(&format!("Couldn't copy {} to {} !",
+ from.to_string_lossy(),
to.to_string_lossy()))
} else {
Ok(())
@@ -97,7 +99,7 @@ fn install_config_previewers() -> HResult<()> {
let hunter_dir = crate::paths::hunter_path()?;
let archive_path = create_archive()?;
extract_archive(Path::new("/tmp"), &archive_path)?;
- move_dir("/tmp/hunter/previewers", &hunter_dir)?;
+ copy(Path::new("/tmp/hunter/previewers"), &hunter_dir)?;
delete_archive(&archive_path)
}
@@ -105,10 +107,74 @@ fn install_config_actions() -> HResult<()> {
let hunter_dir = crate::paths::hunter_path()?;
let archive_path = create_archive()?;
extract_archive(Path::new("/tmp"), &archive_path)?;
- move_dir("/tmp/hunter/actions", &hunter_dir)?;
+ copy(Path::new("/tmp/hunter/actions"), &hunter_dir)?;
delete_archive(&archive_path)
}
+fn update_previewer() -> HResult<()> {
+ let previewer_dir = crate::paths::previewers_path()?;
+ let archive_path = create_archive()?;
+
+ extract_archive(Path::new("/tmp"), &archive_path)?;
+
+ update_dir(Path::new("/tmp/hunter/previewers"), &previewer_dir).log();
+
+ delete_archive(&archive_path)?;
+
+ Ok(())
+}
+
+fn update_actions() -> HResult<()> {
+ let actions_dir = crate::paths::actions_path()?;
+ let archive_path = create_archive()?;
+
+ extract_archive(Path::new("/tmp"), &archive_path)?;
+
+ update_dir(Path::new("/tmp/hunter/actions"), &actions_dir).log();
+
+ delete_archive(&archive_path)?;
+
+ Ok(())
+}
+
+pub fn update_config(core: WidgetCore, force: bool) -> HResult<()> {
+ // First install whatever might be missing, makes sure all dirs are there
+ ensure_config(core).log();
+
+ // Just overwrite everything except core config/keys with the latest version
+ if force {
+ install_config_previewers().log();
+ install_config_actions().log();
+ return Ok(())
+ }
+
+ let archive_path = create_archive()?;
+ extract_archive(Path::new("/tmp"), &archive_path)?;
+ Ok(())
+}
+
+fn update_dir<P: AsRef<Path>>(source: P, target: P) -> HResult<()> {
+ for file in std::fs::read_dir(source)? {
+ let file_path = file?.path();
+ let file_name = file_path.file_name()?;
+ let target_path = target.as_ref().join(file_name);
+
+ if file_path.is_dir() {
+ // Check subdirectories recursively
+ update_dir(&file_path, &target_path).log();
+ } else {
+ if !target_path.exists() {
+ HError::log::<()>(&format!("Installing additional config file: {}",
+ file_path.to_string_lossy())).ok();
+ copy(&file_path, &target_path).log();
+ }
+ }
+ }
+
+ Ok(())
+}
+
+
fn create_archive() -> HResult<&'static str> {
let archive_path = "/tmp/hunter-config.tar.gz";
let def_config = default_config_archive();
diff --git a/src/file_browser.rs b/src/file_browser.rs
index 73e8e1f..1a57c8a 100644
--- a/src/file_browser.rs
+++ b/src/file_browser.rs
@@ -87,14 +87,6 @@ pub struct FileBrowser {
}
impl Tabbable for TabView<FileBrowser> {
- fn on_new(&mut self) -> HResult<()> {
- let core = self.core.clone();
- std::thread::spawn(move || {
- crate::config_installer::ensure_config(core).log();
- });
- Ok(())
- }
-
fn new_tab(&mut self) -> HResult<()> {
let cur_tab = self.active_tab_();
diff --git a/src/main.rs b/src/main.rs
index a89fe4c..1304c49 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -72,7 +72,7 @@ mod keybind;
use widget::{Widget, WidgetCore};
use term::ScreenExt;
-use fail::{HResult, HError, MimeError};
+use fail::{HResult, HError, MimeError, ErrorLog};
use file_browser::FileBrowser;
use tabview::TabView;
use trait_ext::PathBufMime;
@@ -97,10 +97,10 @@ fn main() -> HResult<()> {
// do this early so it might be ready when needed
crate::files::load_tags().ok();
- parse_args().ok();
-
let mut core = WidgetCore::new().expect("Can't create WidgetCore!");
+ parse_args(core.clone()).log();
+
// Resets terminal when hunter crashes :(
die_gracefully(&core);
@@ -117,6 +117,13 @@ fn main() -> HResult<()> {
fn run(mut core: WidgetCore) -> HResult<()> {
core.screen.clear()?;
+ let core2 = core.clone();
+
+ // I hate waiting!!!
+ std::thread::spawn(move || {
+ crate::config_installer::ensure_config(core2).log();
+ });
+
let filebrowser = FileBrowser::new(&core, None)?;
let mut tabview = TabView::new(&core);
tabview.push_widget(filebrowser)?;
@@ -130,12 +137,18 @@ fn run(mut core: WidgetCore) -> HResult<()> {
}
-fn parse_args() -> HResult<()> {
+fn parse_args(core: WidgetCore) -> HResult<()> {
let args = App::new("Lag-free terminal file browser")
.version(clap::crate_version!())
.author(clap::crate_authors!("\n"))
.about("Hunt your files at light-speed, armed with full $SHELL integration")
.arg(
+ Arg::with_name("update")
+ .short("u")
+ .long("update-conf")
+ .help("Update configuration (WARNING: Overwrites modified previewers/actions with default names! Main config/keys are safe!)")
+ .takes_value(false))
+ .arg(
Arg::with_name("animation-off")
.short("a")
.long("animation-off")
@@ -185,11 +198,17 @@ fn parse_args() -> HResult<()> {
std::process::exit(1)
}
+ if args.is_present("update") {
+ crate::config_installer::update_config(core, true).log();
+ }
+
if let Some(path) = path {
- std::env::set_current_dir(&path).ok();
+ std::env::set_current_dir(&path)
+ .map_err(HError::from)
+ .log();
}
- crate::config::set_argv_config(args).ok();
+ crate::config::set_argv_config(args).log();
Ok(())
}