generate-copyright: Render Node with rinja too.

This commit is contained in:
Jonathan Pallant 2024-07-31 19:26:44 +01:00
parent 37ab09010c
commit 30ac7c9a81
No known key found for this signature in database
4 changed files with 115 additions and 77 deletions

View File

@ -1407,9 +1407,9 @@ version = "0.1.0"
dependencies = [
"anyhow",
"cargo_metadata 0.18.1",
"rinja 0.2.0",
"serde",
"serde_json",
"tempfile",
"thiserror",
]
@ -3100,6 +3100,18 @@ dependencies = [
"walkdir",
]
[[package]]
name = "rinja"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d47a46d7729e891c8accf260e9daa02ae6d570aa2a94fb1fb27eb5364a2323"
dependencies = [
"humansize",
"num-traits",
"percent-encoding",
"rinja_derive 0.2.0",
]
[[package]]
name = "rinja"
version = "0.3.0"
@ -3107,7 +3119,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d3762e3740cdbf2fd2be465cc2c26d643ad17353cc2e0223d211c1b096118bd"
dependencies = [
"itoa",
"rinja_derive",
"rinja_derive 0.3.0",
]
[[package]]
name = "rinja_derive"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44dae9afe59d58ed8d988d67d1945f3638125d2fd2104058399382e11bd3ea2a"
dependencies = [
"basic-toml",
"mime",
"mime_guess",
"once_map",
"proc-macro2",
"quote",
"rinja_parser 0.2.0",
"serde",
"syn 2.0.67",
]
[[package]]
@ -3123,11 +3152,20 @@ dependencies = [
"once_map",
"proc-macro2",
"quote",
"rinja_parser",
"rinja_parser 0.3.0",
"serde",
"syn 2.0.67",
]
[[package]]
name = "rinja_parser"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1771c78cd5d3b1646ef8d8f2ed100db936e8b291d3cc06e92a339ff346858c"
dependencies = [
"nom",
]
[[package]]
name = "rinja_parser"
version = "0.3.0"
@ -4606,7 +4644,7 @@ dependencies = [
"minifier",
"pulldown-cmark 0.9.6",
"regex",
"rinja",
"rinja 0.3.0",
"rustdoc-json-types",
"serde",
"serde_json",

View File

@ -9,9 +9,7 @@ description = "Produces a manifest of all the copyrighted materials in the Rust
[dependencies]
anyhow = "1.0.65"
cargo_metadata = "0.18.1"
html-escape = "0.2.13"
rinja = "0.2.0"
serde = { version = "1.0.147", features = ["derive"] }
serde_json = "1.0.85"
tempfile = "3"
thiserror = "1"

View File

@ -62,8 +62,9 @@ struct Metadata {
}
/// Describes one node in our metadata tree
#[derive(serde::Deserialize)]
#[derive(serde::Deserialize, rinja::Template)]
#[serde(rename_all = "kebab-case", tag = "type")]
#[template(path = "Node.html")]
pub(crate) enum Node {
Root { children: Vec<Node> },
Directory { name: String, children: Vec<Node>, license: Option<License> },
@ -71,76 +72,6 @@ pub(crate) enum Node {
Group { files: Vec<String>, directories: Vec<String>, license: License },
}
fn with_box<F>(fmt: &mut std::fmt::Formatter<'_>, inner: F) -> std::fmt::Result
where
F: FnOnce(&mut std::fmt::Formatter<'_>) -> std::fmt::Result,
{
writeln!(fmt, r#"<div style="border:1px solid black; padding: 5px;">"#)?;
inner(fmt)?;
writeln!(fmt, "</div>")?;
Ok(())
}
impl std::fmt::Display for Node {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Node::Root { children } => {
if children.len() > 1 {
with_box(fmt, |f| {
for child in children {
writeln!(f, "{child}")?;
}
Ok(())
})
} else {
for child in children {
writeln!(fmt, "{child}")?;
}
Ok(())
}
}
Node::Directory { name, children, license } => with_box(fmt, |f| {
render_tree_license(std::iter::once(name), license.as_ref(), f)?;
if !children.is_empty() {
writeln!(f, "<p><b>Exceptions:</b></p>")?;
for child in children {
writeln!(f, "{child}")?;
}
}
Ok(())
}),
Node::Group { files, directories, license } => with_box(fmt, |f| {
render_tree_license(directories.iter().chain(files.iter()), Some(license), f)
}),
Node::File { name, license } => {
with_box(fmt, |f| render_tree_license(std::iter::once(name), Some(license), f))
}
}
}
}
/// Draw a series of sibling files/folders, as HTML, into the given formatter.
fn render_tree_license<'a>(
names: impl Iterator<Item = &'a String>,
license: Option<&License>,
f: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
writeln!(f, "<p><b>File/Directory:</b> ")?;
for name in names {
writeln!(f, "<code>{}</code>", html_escape::encode_text(&name))?;
}
writeln!(f, "</p>")?;
if let Some(license) = license {
writeln!(f, "<p><b>License:</b> {}</p>", html_escape::encode_text(&license.spdx))?;
for copyright in license.copyright.iter() {
writeln!(f, "<p><b>Copyright:</b> {}</p>", html_escape::encode_text(&copyright))?;
}
}
Ok(())
}
/// A License has an SPDX license name and a list of copyright holders.
#[derive(serde::Deserialize)]
struct License {

View File

@ -0,0 +1,71 @@
{% match self %}
{% when Node::Root { children } %}
{% for child in children %}
{{ child|safe }}
{% endfor %}
{% when Node::Directory { name, children, license } %}
<div style="border:1px solid black; padding: 5px;">
<p>
<b>File/Directory:</b> <code>{{ name }}</code>
</p>
{% if let Some(license) = license %}
<p><b>License:</b> {{ license.spdx }}</p>
{% for copyright in license.copyright.iter() %}
<p><b>Copyright:</b> {{ copyright }}</p>
{% endfor %}
{% endif %}
{% if !children.is_empty() %}
<p><b>Exceptions:</b></p>
{% for child in children %}
{{ child|safe }}
{% endfor %}
{% endif %}
</div>
{% when Node::File { name, license } %}
<div style="border:1px solid black; padding: 5px;">
<p>
<b>File/Directory:</b> <code>{{ name }}</code>
</p>
<p><b>License:</b> {{ license.spdx }}</p>
{% for copyright in license.copyright.iter() %}
<p><b>Copyright:</b> {{ copyright }}</p>
{% endfor %}
</div>
{% when Node::Group { files, directories, license } %}
<div style="border:1px solid black; padding: 5px;">
<p>
<b>File/Directory:</b>
{% for name in files %}
<code>{{ name }}</code>
{% endfor %}
{% for name in directories %}
<code>{{ name }}</code>
{% endfor %}
</p>
<p><b>License:</b> {{ license.spdx }}</p>
{% for copyright in license.copyright.iter() %}
<p><b>Copyright:</b> {{ copyright }}</p>
{% endfor %}
</div>
{% endmatch %}