use crate::RetrievedDependency;
use serde::{Deserialize, Serialize};
use tracing::instrument;
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
pub struct LicRc {
pub licenses: LicRcLicenses,
pub dependencies: LicRcDependencies,
pub behavior: LicRcBehavior,
}
#[cfg(feature = "licrc-from-file")]
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Error trying to open and read the .licrc file: {0}")]
Io(#[from] std::io::Error),
#[error("Error trying to parse the .licrc file: {0}")]
Toml(#[from] toml::de::Error),
}
#[cfg(feature = "licrc-from-file")]
impl LicRc {
#[instrument(skip(relative_path))]
pub fn from_relative_path(relative_path: impl AsRef<std::path::Path>) -> Result<Self, Error> {
let licrc_path = std::env::current_dir()?.join(relative_path);
let licrc_content = std::fs::read_to_string(licrc_path)?;
let licrc = toml::from_str(&licrc_content)?;
Ok(licrc)
}
}
impl LicRc {
#[instrument(skip(self))]
pub fn validate(&self, dependency: &mut RetrievedDependency) {
dependency.validated = true;
if self
.dependencies
.ignored
.as_ref()
.unwrap_or(&vec![])
.contains(&dependency.name)
{
dependency.is_ignored = true;
tracing::debug!(dependency = ?dependency, "Dependency has been ignored");
return;
}
if !dependency.is_valid {
tracing::debug!(dependency = ?dependency, "Dependency is invalid");
return;
}
if let Some(licenses) = dependency.licenses.clone() {
for lic in &licenses {
if let Some(accepted) = self.licenses.accepted.as_ref() {
if !accepted.contains(lic) {
make_invalid(dependency, lic);
}
} else if let Some(unaccepted) = self.licenses.unaccepted.as_ref() {
if unaccepted.contains(lic) {
make_invalid(dependency, lic);
}
}
}
} else {
tracing::error!("Licenses are None!! At this point, this shouldn't happen. Check out the dependency validation logic");
}
}
}
#[instrument]
fn make_invalid(dependency: &mut RetrievedDependency, license: &str) {
tracing::debug!(
?dependency,
license,
"No compliant dependency marked as invalid"
);
dependency.is_valid = false;
if dependency.error.is_none() {
dependency.error = Some("Not compliant".to_string());
}
}
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
pub struct LicRcLicenses {
pub accepted: Option<Vec<String>>,
pub unaccepted: Option<Vec<String>>,
}
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
pub struct LicRcDependencies {
pub ignored: Option<Vec<String>>,
}
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
pub struct LicRcBehavior {
pub run_only_on_dependency_modification: Option<bool>,
pub do_not_block_pr: Option<bool>,
}