mirror of
https://github.com/nivekuil/rip
synced 2024-11-13 23:47:11 +00:00
Add resurrect option
This commit is contained in:
parent
03530ae8b9
commit
2b0694f480
2 changed files with 44 additions and 21 deletions
|
@ -1,6 +1,6 @@
|
||||||
[project]
|
[project]
|
||||||
name = "rip" # rm improved
|
name = "rip" # rm improved
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
authors = ["mail@nivekuil.com"]
|
authors = ["mail@nivekuil.com"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
63
src/main.rs
63
src/main.rs
|
@ -1,14 +1,17 @@
|
||||||
// -*- compile-command: "cargo build" -*-
|
// -*- compile-command: "cargo build" -*-
|
||||||
|
#![feature(core_str_ext)]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
|
extern crate core;
|
||||||
extern crate walkdir;
|
extern crate walkdir;
|
||||||
|
|
||||||
use clap::{Arg, App};
|
use clap::{Arg, App};
|
||||||
|
use core::str::StrExt;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Write;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
static GRAVEYARD: &'static str = "/tmp/.graveyard";
|
static GRAVEYARD: &'static str = "/tmp/.graveyard";
|
||||||
static HISTFILE: &'static str = ".rip_history";
|
static HISTFILE: &'static str = ".rip_history";
|
||||||
|
@ -20,24 +23,29 @@ fn main() {
|
||||||
.about("Rm ImProved
|
.about("Rm ImProved
|
||||||
Send files to the graveyard (/tmp/.graveyard) instead of unlinking them.")
|
Send files to the graveyard (/tmp/.graveyard) instead of unlinking them.")
|
||||||
.arg(Arg::with_name("SOURCE")
|
.arg(Arg::with_name("SOURCE")
|
||||||
.help("File or directory to remove")
|
.help("File or directory to remove")
|
||||||
.required(true)
|
.required(true)
|
||||||
.multiple(true)
|
.multiple(true)
|
||||||
.index(1)
|
.index(1)
|
||||||
.conflicts_with("decompose")
|
.conflicts_with("decompose")
|
||||||
.conflicts_with("seance"))
|
.conflicts_with("seance")
|
||||||
|
.conflicts_with("resurrect"))
|
||||||
.arg(Arg::with_name("graveyard")
|
.arg(Arg::with_name("graveyard")
|
||||||
.help("Directory where deleted files go to rest")
|
.help("Directory where deleted files go to rest")
|
||||||
.long("graveyard")
|
.long("graveyard")
|
||||||
.takes_value(true))
|
.takes_value(true))
|
||||||
.arg(Arg::with_name("decompose")
|
.arg(Arg::with_name("decompose")
|
||||||
.help("Permanently delete (unlink) the entire graveyard")
|
.help("Permanently delete (unlink) the entire graveyard")
|
||||||
.long("decompose"))
|
.long("decompose"))
|
||||||
.arg(Arg::with_name("seance")
|
.arg(Arg::with_name("seance")
|
||||||
.help("List all objects in the graveyard that were sent from the \
|
.help("List all objects in the graveyard that were sent from the \
|
||||||
current directory")
|
current directory")
|
||||||
.short("s")
|
.short("s")
|
||||||
.long("seance"))
|
.long("seance"))
|
||||||
|
.arg(Arg::with_name("resurrect")
|
||||||
|
.help("Undo the last deletion")
|
||||||
|
.short("r")
|
||||||
|
.long("resurrect"))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let graveyard: &Path = Path::new(matches.value_of("graveyard")
|
let graveyard: &Path = Path::new(matches.value_of("graveyard")
|
||||||
|
@ -48,7 +56,23 @@ Send files to the graveyard (/tmp/.graveyard) instead of unlinking them.")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if matches.is_present("resurrect") {
|
||||||
|
let histfile = graveyard.join(HISTFILE);
|
||||||
|
let mut f = fs::File::open(histfile).expect("No histfile found.");
|
||||||
|
let mut s = String::new();
|
||||||
|
f.read_to_string(&mut s).unwrap();
|
||||||
|
let mut tokens = StrExt::split(s.as_str(), "\t");
|
||||||
|
let dest = tokens.next().expect("Bad histfile format for dest");
|
||||||
|
let source = tokens.next().expect("Bad histfile format for source");
|
||||||
|
if let Err(e) = bury(Path::new(source), Path::new(dest)) {
|
||||||
|
println!("ERROR: {}: {}", e, source);
|
||||||
|
}
|
||||||
|
println!("Returned {} to {}", source, dest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let cwd: PathBuf = env::current_dir().expect("Failed to get current dir");
|
let cwd: PathBuf = env::current_dir().expect("Failed to get current dir");
|
||||||
|
|
||||||
if matches.is_present("seance") {
|
if matches.is_present("seance") {
|
||||||
let path = cwd.strip_prefix("/").unwrap();
|
let path = cwd.strip_prefix("/").unwrap();
|
||||||
for entry in WalkDir::new(graveyard.join(path)).into_iter().skip(1) {
|
for entry in WalkDir::new(graveyard.join(path)).into_iter().skip(1) {
|
||||||
|
@ -63,11 +87,10 @@ Send files to the graveyard (/tmp/.graveyard) instead of unlinking them.")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sources: clap::Values = matches.values_of("SOURCE").unwrap();
|
for source in matches.values_of("SOURCE").unwrap() {
|
||||||
for source in sources {
|
|
||||||
let path: PathBuf = cwd.join(Path::new(source));
|
let path: PathBuf = cwd.join(Path::new(source));
|
||||||
// Can't join absolute paths, so we need to strip the leading "/"
|
|
||||||
let dest: PathBuf = {
|
let dest: PathBuf = {
|
||||||
|
// Can't join absolute paths, so we need to strip the leading "/"
|
||||||
let grave = graveyard.join(path.strip_prefix("/").unwrap());
|
let grave = graveyard.join(path.strip_prefix("/").unwrap());
|
||||||
if grave.exists() { rename_grave(grave) } else { grave }
|
if grave.exists() { rename_grave(grave) } else { grave }
|
||||||
};
|
};
|
||||||
|
@ -80,7 +103,7 @@ Send files to the graveyard (/tmp/.graveyard) instead of unlinking them.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write deletion history to HISTFILE in the format "SOURCE\tDEST".
|
/// Write deletion history to HISTFILE in the format "SOURCEPATH\tGRAVEPATH".
|
||||||
fn write_log(source: PathBuf, dest: PathBuf, graveyard: &Path)
|
fn write_log(source: PathBuf, dest: PathBuf, graveyard: &Path)
|
||||||
-> std::io::Result<()> {
|
-> std::io::Result<()> {
|
||||||
let histfile = graveyard.join(HISTFILE);
|
let histfile = graveyard.join(HISTFILE);
|
||||||
|
|
Loading…
Reference in a new issue