Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new Ratio output type --output-format=Ratio #167

Merged
merged 4 commits into from
Dec 25, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cargo-geiger/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ OPTIONS:
--format <FORMAT> Format string used for printing dependencies
[default: {p}].
--output-format Output format for the report: Ascii, GitHubMarkdown,
Json, Utf8 [default: Utf8]
Json, Utf8, Ratio [default: Utf8]
--update-readme Writes output to ./README.md. Looks for a Safety
Report section, replaces if found, adds if not.
Throws an error if no README.md exists.
Expand Down
1 change: 1 addition & 0 deletions cargo-geiger/src/format/print_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub enum OutputFormat {
Json,
GitHubMarkdown,
Utf8,
Ratio,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you order the OutputFormat types alphabetically here and in the updated help message please?

}

impl Default for OutputFormat {
Expand Down
140 changes: 113 additions & 27 deletions cargo-geiger/src/format/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,32 +107,117 @@ fn table_footer(
output_format: OutputFormat,
status: CrateDetectionStatus,
) -> ColoredString {
let fmt = |used: &Count, not_used: &Count| {
format!("{}/{}", used.unsafe_, used.unsafe_ + not_used.unsafe_)
};
let output = format!(
"{: <10} {: <12} {: <6} {: <7} {: <7}",
fmt(&used.functions, &not_used.functions),
fmt(&used.exprs, &not_used.exprs),
fmt(&used.item_impls, &not_used.item_impls),
fmt(&used.item_traits, &not_used.item_traits),
fmt(&used.methods, &not_used.methods),
);
colorize(&status, output_format, output)
match output_format {
OutputFormat::Ratio => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to split out two functions here, one for OutputFormat::Ratio and one for _ with unit tests for each? It might be nice to have a function and tests for the ratio calculation too?

// print safe ratio
let fmt = |used: &Count, not_used: &Count| {
format!(
"{:>5}/{:<}={:.2}%",
(used.safe + not_used.safe),
(used.safe
+ used.unsafe_
+ not_used.unsafe_
+ not_used.safe),
if used.safe
+ used.unsafe_
+ not_used.unsafe_
+ not_used.safe
== 0
{
100.0
} else {
(100.00 * (used.safe + not_used.safe) as f32)
/ ((used.safe
+ used.unsafe_
+ not_used.unsafe_
+ not_used.safe)
as f32)
}
)
};
let output = format!(
"{: <12} {: <18} {: <18} {: <12} {: <12}",
fmt(&used.functions, &not_used.functions),
fmt(&used.exprs, &not_used.exprs),
fmt(&used.item_impls, &not_used.item_impls),
fmt(&used.item_traits, &not_used.item_traits),
fmt(&used.methods, &not_used.methods),
);
colorize(&status, output_format, output)
}
_ => {
let fmt = |used: &Count, not_used: &Count| {
format!("{}/{}", used.unsafe_, used.unsafe_ + not_used.unsafe_)
};
let output = format!(
"{: <10} {: <12} {: <6} {: <7} {: <7}",
fmt(&used.functions, &not_used.functions),
fmt(&used.exprs, &not_used.exprs),
fmt(&used.item_impls, &not_used.item_impls),
fmt(&used.item_traits, &not_used.item_traits),
fmt(&used.methods, &not_used.methods),
);
colorize(&status, output_format, output)
}
}
}

fn table_row(used: &CounterBlock, not_used: &CounterBlock) -> String {
let fmt = |used: &Count, not_used: &Count| {
format!("{}/{}", used.unsafe_, used.unsafe_ + not_used.unsafe_)
};
format!(
"{: <10} {: <12} {: <6} {: <7} {: <7}",
fmt(&used.functions, &not_used.functions),
fmt(&used.exprs, &not_used.exprs),
fmt(&used.item_impls, &not_used.item_impls),
fmt(&used.item_traits, &not_used.item_traits),
fmt(&used.methods, &not_used.methods),
)
fn table_row(
used: &CounterBlock,
not_used: &CounterBlock,
output_format: OutputFormat,
) -> String {
match output_format {
OutputFormat::Ratio => {
// print safe ratio
let fmt = |used: &Count, not_used: &Count| {
format!(
"{:>5}/{:<}={:.2}%",
(used.safe + not_used.safe),
(used.safe
+ used.unsafe_
+ not_used.unsafe_
+ not_used.safe),
if used.safe
+ used.unsafe_
+ not_used.unsafe_
+ not_used.safe
== 0
{
100.0
} else {
(100.00 * (used.safe + not_used.safe) as f32)
/ ((used.safe
+ used.unsafe_
+ not_used.unsafe_
+ not_used.safe)
as f32)
}
)
};
format!(
"{: <12} {: <18} {: <18} {: <12} {: <12}",
fmt(&used.functions, &not_used.functions),
fmt(&used.exprs, &not_used.exprs),
fmt(&used.item_impls, &not_used.item_impls),
fmt(&used.item_traits, &not_used.item_traits),
fmt(&used.methods, &not_used.methods)
)
}
_ => {
let fmt = |used: &Count, not_used: &Count| {
format!("{}/{}", used.unsafe_, used.unsafe_ + not_used.unsafe_)
};
format!(
"{: <10} {: <12} {: <6} {: <7} {: <7}",
fmt(&used.functions, &not_used.functions),
fmt(&used.exprs, &not_used.exprs),
fmt(&used.item_impls, &not_used.item_impls),
fmt(&used.item_traits, &not_used.item_traits),
fmt(&used.methods, &not_used.methods)
)
}
}
}

fn table_row_empty() -> String {
Expand All @@ -142,7 +227,7 @@ fn table_row_empty() -> String {
.iter()
.map(|s| s.len())
.sum::<usize>()
+ headers_but_last.len() // Space after each column
+ headers_but_last.len() + 4// Space after each column
+ 2 // Unsafety symbol width
+ 1; // Space after symbol
" ".repeat(n)
Expand Down Expand Up @@ -232,14 +317,15 @@ mod table_tests {
.collect();
let unsafety = unsafe_stats(&package_metrics, &rs_files_used);

let table_row = table_row(&unsafety.used, &unsafety.unused);
let table_row =
table_row(&unsafety.used, &unsafety.unused, OutputFormat::Ascii);
assert_eq!(table_row, "4/6 8/12 12/18 16/24 20/30 ");
}

#[rstest]
fn table_row_empty_test() {
let empty_table_row = table_row_empty();
assert_eq!(empty_table_row.len(), 51);
assert_eq!(empty_table_row.len(), 55);
}

#[rstest(
Expand Down
6 changes: 5 additions & 1 deletion cargo-geiger/src/format/table/handle_text_tree_line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,11 @@ pub fn handle_text_tree_line_package(
let unsafe_info = colorize(
&crate_detection_status,
table_parameters.print_config.output_format,
table_row(&unsafe_info.used, &unsafe_info.unused),
table_row(
&unsafe_info.used,
&unsafe_info.unused,
table_parameters.print_config.output_format,
),
);

let shift_chars = unsafe_info.chars().count() + 4;
Expand Down
26 changes: 21 additions & 5 deletions cargo-geiger/src/scan/default/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,27 @@ fn construct_key_lines(
let mut output_key_lines = Vec::<String>::new();

output_key_lines.push(String::new());
output_key_lines.push(String::from("Metric output format: x/y"));
output_key_lines
.push(String::from(" x = unsafe code used by the build"));
output_key_lines
.push(String::from(" y = total unsafe code found in the crate"));
match output_format {
OutputFormat::Ratio => {
// Change the prompt for Safe Ratio report:
output_key_lines.push(String::from("Metric output format: x/y=z%"));
output_key_lines
.push(String::from(" x = safe code found in the crate"));
output_key_lines
.push(String::from(" y = total code found in the crate"));
output_key_lines.push(String::from(
" z = percentage of safe ratio as defined by x/y",
));
}
_ => {
output_key_lines.push(String::from("Metric output format: x/y"));
output_key_lines
.push(String::from(" x = unsafe code used by the build"));
output_key_lines.push(String::from(
" y = total unsafe code found in the crate",
));
}
}
output_key_lines.push(String::new());
output_key_lines.push(String::from("Symbols: "));

Expand Down