include directories in grouped licensing information
This commit is contained in:
parent
6473ff150f
commit
49b902f06e
@ -13,7 +13,7 @@ pub(crate) enum Node<L> {
|
|||||||
Root { childs: Vec<Node<L>> },
|
Root { childs: Vec<Node<L>> },
|
||||||
Directory { name: PathBuf, childs: Vec<Node<L>>, license: Option<L> },
|
Directory { name: PathBuf, childs: Vec<Node<L>>, license: Option<L> },
|
||||||
File { name: PathBuf, license: L },
|
File { name: PathBuf, license: L },
|
||||||
FileGroup { names: Vec<PathBuf>, license: L },
|
Group { files: Vec<PathBuf>, directories: Vec<PathBuf>, license: L },
|
||||||
Empty,
|
Empty,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ pub(crate) fn simplify(&mut self) {
|
|||||||
self.merge_directories();
|
self.merge_directories();
|
||||||
self.collapse_in_licensed_directories();
|
self.collapse_in_licensed_directories();
|
||||||
self.merge_directory_licenses();
|
self.merge_directory_licenses();
|
||||||
self.merge_file_groups();
|
self.merge_groups();
|
||||||
self.remove_empty();
|
self.remove_empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,8 +64,8 @@ fn merge_directories(&mut self) {
|
|||||||
Node::Root { .. } => {
|
Node::Root { .. } => {
|
||||||
panic!("can't have a root inside another element");
|
panic!("can't have a root inside another element");
|
||||||
}
|
}
|
||||||
Node::FileGroup { .. } => {
|
Node::Group { .. } => {
|
||||||
panic!("FileGroup should not be present at this stage");
|
panic!("Group should not be present at this stage");
|
||||||
}
|
}
|
||||||
Node::Directory { license: Some(_), .. } => {
|
Node::Directory { license: Some(_), .. } => {
|
||||||
panic!("license should not be set at this stage");
|
panic!("license should not be set at this stage");
|
||||||
@ -86,8 +86,8 @@ fn merge_directories(&mut self) {
|
|||||||
}
|
}
|
||||||
Node::Empty => {}
|
Node::Empty => {}
|
||||||
Node::File { .. } => {}
|
Node::File { .. } => {}
|
||||||
Node::FileGroup { .. } => {
|
Node::Group { .. } => {
|
||||||
panic!("FileGroup should not be present at this stage");
|
panic!("Group should not be present at this stage");
|
||||||
}
|
}
|
||||||
Node::Directory { license: Some(_), .. } => {
|
Node::Directory { license: Some(_), .. } => {
|
||||||
panic!("license should not be set at this stage");
|
panic!("license should not be set at this stage");
|
||||||
@ -132,7 +132,7 @@ fn collapse_in_licensed_directories(&mut self) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Node::File { .. } => {}
|
Node::File { .. } => {}
|
||||||
Node::FileGroup { .. } => {}
|
Node::Group { .. } => panic!("group should not be present at this stage"),
|
||||||
Node::Empty => {}
|
Node::Empty => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,8 +165,8 @@ fn merge_directory_licenses(&mut self) {
|
|||||||
Node::Root { .. } => {
|
Node::Root { .. } => {
|
||||||
panic!("can't have a root inside another element");
|
panic!("can't have a root inside another element");
|
||||||
}
|
}
|
||||||
Node::FileGroup { .. } => {
|
Node::Group { .. } => {
|
||||||
panic!("FileGroup should not be present at this stage");
|
panic!("Group should not be present at this stage");
|
||||||
}
|
}
|
||||||
Node::Directory { name: child_child_name, .. } => {
|
Node::Directory { name: child_child_name, .. } => {
|
||||||
*child_child_name = child_name.join(&child_child_name);
|
*child_child_name = child_name.join(&child_child_name);
|
||||||
@ -185,38 +185,74 @@ fn merge_directory_licenses(&mut self) {
|
|||||||
}
|
}
|
||||||
Node::Empty => {}
|
Node::Empty => {}
|
||||||
Node::File { .. } => {}
|
Node::File { .. } => {}
|
||||||
Node::FileGroup { .. } => {}
|
Node::Group { .. } => panic!("Group should not be present at this stage"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This pass groups multiple files in a directory with the same license into a single
|
/// This pass groups multiple files in a directory with the same license into a single
|
||||||
/// "FileGroup", so that the license of all those files can be reported as a group.
|
/// "Group", so that the license of all those files can be reported as a group.
|
||||||
|
///
|
||||||
|
/// This also merges directories *without exceptions*.
|
||||||
///
|
///
|
||||||
/// Crucially this pass runs after collapse_in_licensed_directories, so the most common license
|
/// Crucially this pass runs after collapse_in_licensed_directories, so the most common license
|
||||||
/// will already be marked as the directory's license and won't be turned into a group.
|
/// will already be marked as the directory's license and won't be turned into a group.
|
||||||
fn merge_file_groups(&mut self) {
|
fn merge_groups(&mut self) {
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Grouped {
|
||||||
|
files: Vec<PathBuf>,
|
||||||
|
directories: Vec<PathBuf>,
|
||||||
|
}
|
||||||
match self {
|
match self {
|
||||||
Node::Root { childs } | Node::Directory { childs, .. } => {
|
Node::Root { childs } | Node::Directory { childs, .. } => {
|
||||||
let mut grouped = BTreeMap::new();
|
let mut grouped: BTreeMap<LicenseId, Grouped> = BTreeMap::new();
|
||||||
|
|
||||||
for child in &mut *childs {
|
for child in &mut *childs {
|
||||||
child.merge_file_groups();
|
child.merge_groups();
|
||||||
if let Node::File { name, license } = child {
|
match child {
|
||||||
grouped.entry(*license).or_insert_with(Vec::new).push(name.clone());
|
Node::Directory { name, childs, license: Some(license) } => {
|
||||||
|
if childs.is_empty() {
|
||||||
|
grouped
|
||||||
|
.entry(*license)
|
||||||
|
.or_insert_with(Grouped::default)
|
||||||
|
.directories
|
||||||
|
.push(name.clone());
|
||||||
*child = Node::Empty;
|
*child = Node::Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Node::File { name, license } => {
|
||||||
|
grouped
|
||||||
|
.entry(*license)
|
||||||
|
.or_insert_with(Grouped::default)
|
||||||
|
.files
|
||||||
|
.push(name.clone());
|
||||||
|
*child = Node::Empty;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (license, mut names) in grouped.into_iter() {
|
for (license, mut grouped) in grouped.into_iter() {
|
||||||
if names.len() == 1 {
|
if grouped.files.len() + grouped.directories.len() <= 1 {
|
||||||
childs.push(Node::File { license, name: names.pop().unwrap() });
|
if let Some(name) = grouped.files.pop() {
|
||||||
|
childs.push(Node::File { license, name });
|
||||||
|
} else if let Some(name) = grouped.directories.pop() {
|
||||||
|
childs.push(Node::Directory {
|
||||||
|
name,
|
||||||
|
childs: Vec::new(),
|
||||||
|
license: Some(license),
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
childs.push(Node::FileGroup { license, names });
|
childs.push(Node::Group {
|
||||||
|
license,
|
||||||
|
files: grouped.files,
|
||||||
|
directories: grouped.directories,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Node::File { .. } => {}
|
Node::File { .. } => {}
|
||||||
Node::FileGroup { .. } => panic!("FileGroup should not be present at this stage"),
|
Node::Group { .. } => panic!("FileGroup should not be present at this stage"),
|
||||||
Node::Empty => {}
|
Node::Empty => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,7 +267,7 @@ fn remove_empty(&mut self) {
|
|||||||
}
|
}
|
||||||
childs.retain(|child| !matches!(child, Node::Empty));
|
childs.retain(|child| !matches!(child, Node::Empty));
|
||||||
}
|
}
|
||||||
Node::FileGroup { .. } => {}
|
Node::Group { .. } => {}
|
||||||
Node::File { .. } => {}
|
Node::File { .. } => {}
|
||||||
Node::Empty => {}
|
Node::Empty => {}
|
||||||
}
|
}
|
||||||
@ -278,16 +314,22 @@ pub(crate) fn expand_interned_licenses(
|
|||||||
) -> Node<&License> {
|
) -> Node<&License> {
|
||||||
match node {
|
match node {
|
||||||
Node::Root { childs } => Node::Root {
|
Node::Root { childs } => Node::Root {
|
||||||
childs: childs.into_iter().map(|child| expand_interned_licenses(child, interner)).collect(),
|
childs: childs
|
||||||
|
.into_iter()
|
||||||
|
.map(|child| expand_interned_licenses(child, interner))
|
||||||
|
.collect(),
|
||||||
},
|
},
|
||||||
Node::Directory { name, childs, license } => Node::Directory {
|
Node::Directory { name, childs, license } => Node::Directory {
|
||||||
childs: childs.into_iter().map(|child| expand_interned_licenses(child, interner)).collect(),
|
childs: childs
|
||||||
|
.into_iter()
|
||||||
|
.map(|child| expand_interned_licenses(child, interner))
|
||||||
|
.collect(),
|
||||||
license: license.map(|license| interner.resolve(license)),
|
license: license.map(|license| interner.resolve(license)),
|
||||||
name,
|
name,
|
||||||
},
|
},
|
||||||
Node::File { name, license } => Node::File { name, license: interner.resolve(license) },
|
Node::File { name, license } => Node::File { name, license: interner.resolve(license) },
|
||||||
Node::FileGroup { names, license } => {
|
Node::Group { files, directories, license } => {
|
||||||
Node::FileGroup { names, license: interner.resolve(license) }
|
Node::Group { files, directories, license: interner.resolve(license) }
|
||||||
}
|
}
|
||||||
Node::Empty => Node::Empty,
|
Node::Empty => Node::Empty,
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,8 @@ fn render_recursive(node: &Node, buffer: &mut Vec<u8>, depth: usize) -> Result<(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Node::FileGroup { names, license } => {
|
Node::Group { files, directories, license } => {
|
||||||
render_license(&prefix, names.iter(), license, buffer)?;
|
render_license(&prefix, directories.iter().chain(files.iter()), license, buffer)?;
|
||||||
}
|
}
|
||||||
Node::File { name, license } => {
|
Node::File { name, license } => {
|
||||||
render_license(&prefix, std::iter::once(name), license, buffer)?;
|
render_license(&prefix, std::iter::once(name), license, buffer)?;
|
||||||
@ -76,7 +76,7 @@ pub(crate) enum Node {
|
|||||||
Root { childs: Vec<Node> },
|
Root { childs: Vec<Node> },
|
||||||
Directory { name: String, childs: Vec<Node>, license: License },
|
Directory { name: String, childs: Vec<Node>, license: License },
|
||||||
File { name: String, license: License },
|
File { name: String, license: License },
|
||||||
FileGroup { names: Vec<String>, license: License },
|
Group { files: Vec<String>, directories: Vec<String>, license: License },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
|
Loading…
Reference in New Issue
Block a user