1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use crate::Cli;
use futures::StreamExt;
use licensebat_core::{licrc::LicRc, FileCollector, RetrievedDependency};
use std::sync::Arc;
const LICENSE_CACHE: &[u8] = std::include_bytes!("../license-cache.bin.zstd");
#[derive(Debug, thiserror::Error)]
enum CheckError {
#[error("Error reading dependency file: {0}")]
DependencyFile(#[from] std::io::Error),
}
pub struct RunResult {
pub licrc: LicRc,
pub dependencies: Vec<RetrievedDependency>,
}
pub async fn run(cli: Cli) -> anyhow::Result<RunResult> {
tracing::info!(
dependency_file = %cli.dependency_file,
"Licensebat running! Using {}", cli.dependency_file
);
let store = Arc::new(askalono::Store::from_cache(LICENSE_CACHE).ok());
let client = reqwest::Client::new();
tracing::debug!("Reading .licrc file");
let licrc = LicRc::from_relative_path(cli.licrc_file)?;
tracing::debug!("Getting dependency file content");
let dep_file_content = get_dep_file_content(&cli.dependency_file).await?;
tracing::debug!("Building collectors");
let npm_retriever = licensebat_js::retriever::Npm::new(client.clone());
let npm_collector = licensebat_js::collector::Npm::new(npm_retriever.clone());
let yarn_collector = licensebat_js::collector::Yarn::new(npm_retriever);
let rust_collector =
licensebat_rust::collector::Rust::with_docs_rs_retriever(client.clone(), store.clone());
let dart_collector = licensebat_dart::collector::Dart::with_hosted_retriever(client, store);
let file_collectors: Vec<Box<dyn FileCollector>> = vec![
Box::new(npm_collector),
Box::new(yarn_collector),
Box::new(rust_collector),
Box::new(dart_collector),
];
let mut stream = file_collectors
.iter()
.find(|c| cli.dependency_file.contains(&c.get_dependency_filename()))
.and_then(|c| c.get_dependencies(&dep_file_content).ok())
.expect("No collector found for dependency file");
tracing::debug!("Validating dependencies");
let mut validated_deps = vec![];
while let Some(mut dependency) = stream.next().await {
licrc.validate(&mut dependency);
validated_deps.push(dependency);
}
tracing::info!("Done!");
Ok(RunResult {
licrc,
dependencies: validated_deps,
})
}
async fn get_dep_file_content(dependency_file: &str) -> Result<String, CheckError> {
async {
let dep_file_path = std::env::current_dir()?.join(dependency_file);
let dep_file_content = tokio::fs::read_to_string(dep_file_path).await?;
Ok(dep_file_content)
}
.await
.map_err(CheckError::DependencyFile)
}