From 55b9b498b7b05a3bd1f8d7ec492a7d9bd9c7b0fc Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 26 Jul 2020 17:40:37 +0800 Subject: [PATCH] Add --list flag Related to #6 --- src/bin/main.rs | 9 ++ src/lib.rs | 93 +++++++++++++++---- .../snapshots/success-list-no-limit-with-zero | 10 ++ tests/snapshots/success-list-with-limit | 9 ++ tests/stateless-journey.sh | 25 +++++ 5 files changed, 130 insertions(+), 16 deletions(-) create mode 100644 tests/snapshots/success-list-no-limit-with-zero create mode 100644 tests/snapshots/success-list-with-limit diff --git a/src/bin/main.rs b/src/bin/main.rs index 3954a40..9c92a68 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -35,6 +35,13 @@ mod args { /// if set, no change will actually be made to the Cargo.toml file, simulating what would be done instead. pub dry_run: bool, + #[argh(option, short = 'l')] + /// provide any number N to limit the output to the N biggest files, ascending. + /// + /// if to 0, list all entries that would be in the crate with the current configuration. + /// Otherwise list the given amount of entries. + pub list: Option, + #[argh(option, from_str_fn(parse_size))] /// if set, and the estimated compressed size of the package would exceed the given size, i.e. 40KB, the command /// will exit with a non-zero exit code. @@ -75,6 +82,7 @@ fn main() -> anyhow::Result<()> { version, reset_manifest: reset, dry_run, + list, package_size_limit, #[cfg(feature = "dev-support")] save_package_for_unit_test, @@ -88,6 +96,7 @@ fn main() -> anyhow::Result<()> { reset, dry_run, colored_output: atty::is(atty::Stream::Stdout), + list, package_size_limit, #[cfg(feature = "dev-support")] save_package_for_unit_test, diff --git a/src/lib.rs b/src/lib.rs index f290fed..b50f852 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,7 +28,7 @@ fn report_lean_crate(mut out: impl std::io::Write) -> std::io::Result<()> { fn report_savings( total_size_in_bytes: u64, total_files: u64, - mut wasted_files: Vec, + wasted_files: Vec, mut out: impl std::io::Write, ) -> std::io::Result<()> { if wasted_files.is_empty() { @@ -38,6 +38,30 @@ fn report_savings( )?; return Ok(()); } + + let file_len = wasted_files.len(); + let wasted_bytes = entries_to_table(wasted_files, &mut out, None)?; + + writeln!( + out, + "Saved {:.0}% or {} in {} files (of {} and {} files in entire crate)", + (wasted_bytes as f32 / total_size_in_bytes as f32) * 100.0, + ByteSize(wasted_bytes), + file_len, + ByteSize(total_size_in_bytes), + total_files + )?; + Ok(()) +} + +fn entries_to_table( + mut entries: Vec, + mut out: impl std::io::Write, + items: Option, +) -> std::io::Result { + if entries.is_empty() { + return Ok(0); + } use ascii_table::{Align, AsciiTable, Column}; use std::fmt::Display; @@ -62,23 +86,21 @@ fn report_savings( }, ); - wasted_files.sort_by(|x, y| x.1.cmp(&y.1)); - let wasted_bytes: u64 = wasted_files.iter().map(|(_, size)| size).sum(); - let data: Vec> = wasted_files + entries.sort_by(|x, y| y.1.cmp(&x.1)); + let bytes: u64 = entries .iter() + .take(items.unwrap_or(entries.len())) + .rev() + .map(|(_, size)| size) + .sum(); + let data: Vec> = entries + .iter() + .take(items.unwrap_or(entries.len())) + .rev() .map(|(path, size)| vec![path as &dyn Display, size as &dyn Display]) .collect(); - ascii_table.print(data); - writeln!( - out, - "Saved {:.0}% or {} in {} files (of {} and {} files in entire crate)", - (wasted_bytes as f32 / total_size_in_bytes as f32) * 100.0, - ByteSize(wasted_bytes), - wasted_files.len(), - ByteSize(total_size_in_bytes), - total_files - )?; - Ok(()) + out.write_all(ascii_table.format(data).as_bytes())?; + Ok(bytes) } fn edit( @@ -290,6 +312,7 @@ pub struct Options { pub reset: bool, pub dry_run: bool, pub colored_output: bool, + pub list: Option, pub package_size_limit: Option, #[cfg(feature = "dev-support")] pub save_package_for_unit_test: Option, @@ -387,6 +410,9 @@ pub fn execute(options: Options, mut output: impl std::io::Write) -> Result<()> if options.reset && options.dry_run { std::fs::write(&manifest_path, &cargo_manifest_original_content)?; } + let list = options + .list + .map(|list| (list, package.entries_meta_data.clone())); let document = edit(document, package, &mut output)?; write_manifest( &manifest_path, @@ -398,7 +424,42 @@ pub fn execute(options: Options, mut output: impl std::io::Write) -> Result<()> )?; if let Some((package, package_size_limit)) = package_size_limit { - check_package_size(package, package_size_limit, output, options.colored_output)?; + check_package_size( + package, + package_size_limit, + &mut output, + options.colored_output, + )?; + } + if let Some((list, entries)) = list { + list_entries(list, &mut output, entries)?; } Ok(()) } + +fn list_entries( + num_entries: usize, + mut out: impl std::io::Write, + entries: Vec, +) -> Result<()> { + let num_entries = if num_entries == 0 { + entries.len() + } else { + num_entries.min(entries.len()) + }; + let bytes = entries_to_table( + entries + .into_iter() + .map(|tf| (tar_path_to_utf8_str(&tf.path).into(), tf.size)) + .collect(), + &mut out, + Some(num_entries), + )?; + writeln!( + out, + "Crate contains a total of {} files and {}", + num_entries, + ByteSize(bytes) + )?; + Ok(()) +} diff --git a/tests/snapshots/success-list-no-limit-with-zero b/tests/snapshots/success-list-no-limit-with-zero new file mode 100644 index 0000000..522af65 --- /dev/null +++ b/tests/snapshots/success-list-no-limit-with-zero @@ -0,0 +1,10 @@ +Your crate is perfectly lean! +There would be no change. +┌─────────────┬─────────────┐ +│ File │ Size (Byte) │ +├─────────────┼─────────────┤ +│ README.md │ 0 │ +│ src/main.rs │ 45 │ +│ Cargo.toml │ 270 │ +└─────────────┴─────────────┘ +Crate contains a total of 3 files and \ No newline at end of file diff --git a/tests/snapshots/success-list-with-limit b/tests/snapshots/success-list-with-limit new file mode 100644 index 0000000..f241e1b --- /dev/null +++ b/tests/snapshots/success-list-with-limit @@ -0,0 +1,9 @@ +Your crate is perfectly lean! +There would be no change. +┌─────────────┬─────────────┐ +│ File │ Size (Byte) │ +├─────────────┼─────────────┤ +│ src/main.rs │ 45 │ +│ Cargo.toml │ 270 │ +└─────────────┴─────────────┘ +Crate contains a total of 2 files and \ No newline at end of file diff --git a/tests/stateless-journey.sh b/tests/stateless-journey.sh index 76b2bfc..b0f9923 100755 --- a/tests/stateless-journey.sh +++ b/tests/stateless-journey.sh @@ -231,6 +231,31 @@ function remove_bytecounts() { } ) ) + + (with "the --list flag" + (when "a small amount is specified" + it "runs successfully and lists the given amount of entries entries in the package" && { + SNAPSHOT_FILTER=remove_bytecounts \ + WITH_SNAPSHOT="$snapshot/success-list-with-limit" \ + expect_run ${SUCCESSFULLY} "$exe" diet -n --list 2 + } + + it "does not put a file in target/package" && { + expect_run ${WITH_FAILURE} find target/package + } + ) + (when "a 0 is specified as amount" + it "runs successfully and lists all entries entries in the package" && { + SNAPSHOT_FILTER=remove_bytecounts \ + WITH_SNAPSHOT="$snapshot/success-list-no-limit-with-zero" \ + expect_run ${SUCCESSFULLY} "$exe" diet -n --list 0 + } + + it "does not put a file in target/package" && { + expect_run ${WITH_FAILURE} find target/package + } + ) + ) ) ) )