Implement the dry-run cmd line parameter and flow

This commit is contained in:
Zykino 2019-09-15 19:50:19 +02:00
parent 98325027c7
commit 803b1cf46c
3 changed files with 44 additions and 20 deletions

View File

@ -7,24 +7,35 @@ The software is still in early developments. I'm using it as a way to introduce
# Usage # Usage
The simplest way to use this program is to simply call it on a comic folder. This way it will ensure the pages are formatted with just the right number of leading 0 to pad the number part of the page. The simplest way to use this program is to simply call it on a comic folder. This way it will ensure the pages are formatted with just the right number of leading 0 to pad the number part of the page.
``` ```
cbb comic/ $ cbb comic/
``` ```
You may want to customize the number of leading 0, it is useful when you plan on adding more pages later. You may want to customize the number of leading 0, it is useful when you plan on adding more pages later.
``` ```
cbb comic/ --pad=3 $ cbb comic/ --pad=3 --dry-run
7.txt -> 07.txt
10.txt -> 10.txt
5.txt -> 05.txt
3.txt -> 03.txt
4.txt -> 04.txt
8.txt -> 08.txt
2.txt -> 02.txt
6.txt -> 06.txt
1.txt -> 01.txt
9.txt -> 09.txt
``` ```
# TODO # TODO
* [ ] Add tests: I'm not used to create tests on projects (unit & integration). * [ ] Add tests: I am not used to create tests on projects (unit & integration)
* [ ] Add tests: HELP WANTED: how can I tests operations on the filesystem? * [ ] Add tests: HELP WANTED: how can I tests operations on the filesystem?
* [ ] Add some quality of life features: * [ ] Add some quality of life features:
* [ ] Dry-run: Show how the files will be changed without modifying anything * [X] Dry-run: Show how the files will be changed without modifying anything
* [ ] Recursivity: user select a "library" folder for which each sub-folder is considered to be a comic book (or an other library) * [ ] Recursivity: user select a "library" folder for which each sub-folder is considered to be a comic book (or an other library)
* [ ] Prefix: let the user set the prefix of the pages: Useful when the name contains a number: "Name-Season5-chapter02-page10.png" => prefix = "Name-Season5-chapter02-page". * [ ] Prefix (name pattern?): let the user set the prefix of the pages: Useful when the name contains a number: "Name-Season5-Chapter02-Page10.png" => prefix = "Name-Season5-Chapter02-Page"
* [ ] Deduce the prefix from the file name (nice to have, not sure it is used that often) * [ ] Deduce the prefix from the file name: try to find the invariant part and the bumping number (nice to have, not sure it is used that often)
* [ ] Integrate an archive crate to be able to open/create `.cba`, `.cbr` `.cbt`, or `.cbz` archives. * [ ] Rename: Totally erase the current name of the file to replace with the cross-platform numerotation based named. The input list should be sorted (possibly coupled with the option prefix/name pattern to have a powerfull renaming tool)
* [ ] Integrate an archive crate to be able to open/create `.cba`, `.cbr` `.cbt`, or `.cbz` archives
* [ ] Add documentation * [ ] Add documentation
* [ ] Maybe integrate rayon (test with a benchmark if it really help: part 1 of the tool is listing the files, part 2 is based on `os::rename` operations). * [ ] Maybe integrate rayon (test with a benchmark if it really help: part 1 of the tool is listing the files, part 2 is based on `os::rename` operations)
Also I saw on Wikipedia that it is possible to include metadata such as [artists, story information, table of contents or even a separate text layer for comic book translations](https://en.wikipedia.org/wiki/Comic_book_archive). If the feature is requested I could check if the different way to include this metadata are well spread. This however will not be discussed before (almost) releasing the 1.0. Also I saw on Wikipedia that it is possible to include metadata such as [artists, story information, table of contents or even a separate text layer for comic book translations](https://en.wikipedia.org/wiki/Comic_book_archive). If the feature is requested I could check if the different way to include this metadata are well spread. This however will not be discussed before (almost) releasing the 1.0.

View File

@ -15,6 +15,12 @@ pub struct Opt {
// TODO: check if I really do this or not when implementing the recursive option // TODO: check if I really do this or not when implementing the recursive option
pub comic_folder: PathBuf, pub comic_folder: PathBuf,
/// Do a dry run of the program printing to stdout the action it would take
///
/// Print how each file would be renamed.
#[structopt(long)]
pub dry_run: bool,
/// Set the pad you want to use /// Set the pad you want to use
/// ///
/// If not set or set to a value inferior to the maximum pad of the comic, the value is /// If not set or set to a value inferior to the maximum pad of the comic, the value is
@ -55,7 +61,6 @@ struct Page {
impl Page { impl Page {
fn new(prefix: String, number: String, suffix: String) -> Page { fn new(prefix: String, number: String, suffix: String) -> Page {
eprintln!("N p:{} n: {} s: {}", prefix, number, suffix);
Page { Page {
prefix, prefix,
number, number,
@ -64,15 +69,10 @@ impl Page {
} }
fn original_filename(&self) -> String { fn original_filename(&self) -> String {
eprintln!("OF p:{} n: {} s: {}", self.prefix, self.number, self.suffix);
format!("{}{}{}", self.prefix, self.number, self.suffix) format!("{}{}{}", self.prefix, self.number, self.suffix)
} }
fn new_filename(&self, pad: usize) -> String { fn new_filename(&self, pad: usize) -> String {
eprintln!(
"NF p: '{}' n: '{}' s: '{}'",
self.prefix, self.number, self.suffix
);
// format!("{:0pad$}-{}{}{}", number, self.prefix, self.number, self.suffix, pad = pad) // format!("{:0pad$}-{}{}{}", number, self.prefix, self.number, self.suffix, pad = pad)
// TODO I think I will need this on in the end // TODO I think I will need this on in the end
format!( format!(
@ -111,7 +111,10 @@ impl ComicBook {
} }
} }
pub fn bind(&mut self) { pub fn bind<T>(&mut self, transform_page: T)
where
T: Fn(String, String),
{
let pad = self.get_pad_size().expect("get_pad_size"); // TODO have a nice error message (the user may habe specifyed a folder that does not contains cb pages) let pad = self.get_pad_size().expect("get_pad_size"); // TODO have a nice error message (the user may habe specifyed a folder that does not contains cb pages)
for page in self.pages.iter() { for page in self.pages.iter() {
@ -119,9 +122,7 @@ impl ComicBook {
let original_file = page.original_filename(); let original_file = page.original_filename();
let new_file = page.new_filename(pad); let new_file = page.new_filename(pad);
eprintln!("{} -> {}", original_file, new_file); transform_page(original_file, new_file);
// fs::rename(original_file, new_file).expect("RENAME FAILED");
//} //}
} }
} }

View File

@ -22,5 +22,17 @@ fn main() {
env::set_current_dir(opt.comic_folder).unwrap(); env::set_current_dir(opt.comic_folder).unwrap();
let mut book = ComicBook::new(fs::read_dir(".").unwrap(), opt.pad); let mut book = ComicBook::new(fs::read_dir(".").unwrap(), opt.pad);
book.bind(); let bind_func = if opt.dry_run { dry_run } else { rename };
book.bind(bind_func);
}
fn dry_run(original: String, new: String) {
// TODO: Is it possible to be certain that the alignment is kept (like in a table)?
// I think there is at least a crate doing that. But I do not want to add bloat only for this
// => To benchmark (binary size, clean compile)
println!("{}\t-> {}", original, new);
}
fn rename(original: String, new: String) {
fs::rename(original, new).expect("RENAME FAILED");
} }