Skip to content

Commit 2b380f3

Browse files
committed
Add markdown output format to the list command
This format follows the existing 'human' option, but makes it easier to render as a table in Markdown viewers. Both layouts are present: - Crate - License The backtick (`) is used to make it easier to parse the long list of elements in the second column. This design is partially inspired by the cabal-plan license-report tool [1][2]. Sources: [1] https://hackage.haskell.org/package/cabal-plan [2] https://hackage.haskell.org/package/cabal-plan-0.7.6.1/src/example/cabal-plan.md
1 parent 8d22680 commit 2b380f3

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

docs/src/cli/list.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ The format of the output
1616

1717
* `human` (default) - Simple format where each crate or license is its own line
1818
* `json`
19+
* `markdown`
1920
* `tsv`
2021

2122
### [`--color`](../cli/common.md#--color)

src/cargo-deny/list.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub enum Layout {
1414
pub enum OutputFormat {
1515
Human,
1616
Json,
17+
Markdown,
1718
Tsv,
1819
}
1920

@@ -304,6 +305,60 @@ pub fn cmd(
304305
}
305306
Layout::Crate => serde_json::to_writer(std::io::stdout(), &crate_layout.crates)?,
306307
},
308+
OutputFormat::Markdown => {
309+
let mut output = String::with_capacity(4 * 1024);
310+
match args.layout {
311+
Layout::License => {
312+
// Column headers
313+
{
314+
writeln!(output, "| License | Crates |")?;
315+
writeln!(output, "| ------- | ------ |")?;
316+
}
317+
318+
for (license, krates) in license_layout.licenses {
319+
write!(output, "| **{license}** ({}) | ", krates.len())?;
320+
for (i, krate_id) in krates.iter().enumerate() {
321+
if i != 0 {
322+
write!(output, ", ")?;
323+
}
324+
325+
let (name, version) = krate_id.parts();
326+
write!(output, "`{name}@{version}`")?;
327+
}
328+
329+
writeln!(output, " |")?;
330+
}
331+
}
332+
Layout::Crate => {
333+
// Column headers
334+
{
335+
writeln!(output, "| Crate | Licenses |")?;
336+
writeln!(output, "| ----- | -------- |")?;
337+
}
338+
339+
for (id, krate) in crate_layout.crates {
340+
let (name, version) = id.parts();
341+
342+
write!(
343+
output,
344+
"| **{name}**@_{version}_ ({}) | ",
345+
krate.licenses.len()
346+
)?;
347+
for (i, license) in krate.licenses.iter().enumerate() {
348+
if i != 0 {
349+
write!(output, ", ")?;
350+
}
351+
352+
write!(output, "`{license}`")?;
353+
}
354+
355+
writeln!(output, " |")?;
356+
}
357+
}
358+
}
359+
360+
std::io::Write::write_all(&mut std::io::stdout(), output.as_bytes())?;
361+
}
307362
OutputFormat::Tsv => {
308363
// We ignore the layout specification and always just do a grid of crate rows x license/exception columns
309364
let mut output = String::with_capacity(4 * 1024);

tests/snapshots/cargo_deny__test__cargo_deny-list.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Options:
3030
The format of the output
3131

3232
[default: human]
33-
[possible values: human, json, tsv]
33+
[possible values: human, json, markdown, tsv]
3434

3535
-l, --layout <LAYOUT>
3636
The layout for the output, does not apply to TSV

0 commit comments

Comments
 (0)