Skip to content

Commit

Permalink
feat: implement patch detection
Browse files Browse the repository at this point in the history
  • Loading branch information
louib committed Aug 21, 2023
1 parent cf7b84a commit cd04970
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 80 deletions.
1 change: 1 addition & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# https://rust-lang.github.io/rustfmt for all the options.
merge_derives = false
max_width = 112
empty_item_single_line = false
19 changes: 11 additions & 8 deletions src/cyclone_dx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use chrono::{DateTime, Utc};
use serde::{de::Deserialize, ser::Serialize};

use serde_cyclonedx::cyclonedx::v_1_4::{
Component, ComponentBuilder, CycloneDxBuilder, ExternalReference, ExternalReferenceBuilder,
Metadata, ToolBuilder,
Component, ComponentBuilder, CycloneDxBuilder, ExternalReference, ExternalReferenceBuilder, Metadata,
ToolBuilder,
};

const CURRENT_SPEC_VERSION: &str = "1.4";
Expand Down Expand Up @@ -42,10 +42,7 @@ pub fn dump(package_graph: &crate::nix::PackageGraph) -> String {
serde_json::to_string_pretty(&cyclonedx).unwrap()
}

pub fn dump_derivation(
derivation_path: &str,
package_node: &crate::nix::PackageNode,
) -> Option<Component> {
pub fn dump_derivation(derivation_path: &str, package_node: &crate::nix::PackageNode) -> Option<Component> {
log::debug!("Dumping derivation for {}", &derivation_path);
let mut component_builder = ComponentBuilder::default();

Expand Down Expand Up @@ -86,8 +83,14 @@ pub fn dump_derivation(
.build()
.unwrap(),
);
if let Some(git_url) = crate::utils::get_git_url_from_generic_url(&homepage) {
log::warn!("Found git url {} for homepage {}", &git_url, &homepage);
}
for source in &package_node.sources {
let source_url = match source.get_url() {
Some(u) => u,
None => continue,
};
if let Some(git_url) = crate::utils::get_git_url_from_generic_url(&source_url) {
log::warn!("Found git url {} for source URL {}", &git_url, &source_url);
external_references.push(
ExternalReferenceBuilder::default()
.type_("vcs")
Expand Down
39 changes: 29 additions & 10 deletions src/nix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,7 @@ impl Derivation {
Ok(flat_derivations)
}

pub fn build_and_get_derivations(
file_path: &str,
derivation_ref: &str,
) -> Result<Derivations, Error> {
pub fn build_and_get_derivations(file_path: &str, derivation_ref: &str) -> Result<Derivations, Error> {
let derivation_path = format!("{}#{}", file_path, derivation_ref);
let output = Command::new("nix")
.arg("build")
Expand Down Expand Up @@ -138,6 +135,18 @@ impl Derivation {
}
None
}

// Returns the out path of the patches for that derivation
pub fn get_patches(&self) -> Vec<String> {
if let Some(patches) = self.env.get("patches") {
let mut response: Vec<String> = vec![];
for patch in patches.split(" ") {
response.push(patch.to_string());
}
return response;
}
vec![]
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -171,8 +180,7 @@ pub fn get_packages() -> Result<Packages, String> {
.output()
.map_err(|e| e.to_string())?;

let raw_packages: Packages =
serde_json::from_slice(&output.stdout).map_err(|e| e.to_string())?;
let raw_packages: Packages = serde_json::from_slice(&output.stdout).map_err(|e| e.to_string())?;

let mut packages: Packages = Packages::default();
// Re-index the packages using the internal package name.
Expand Down Expand Up @@ -327,8 +335,13 @@ pub struct LicenseDetails {
#[derive(Debug)]
pub struct PackageNode {
pub main_derivation: Derivation,

pub package: Package,

pub sources: Vec<Derivation>,

pub patches: Vec<Derivation>,

pub children: HashSet<String>,
}

Expand Down Expand Up @@ -358,7 +371,9 @@ pub fn get_package_graph(
main_derivation: derivation.clone(),
children: HashSet::default(),
sources: vec![],
patches: vec![],
};
let current_node_patches = derivation.get_patches();

let mut child_derivation_paths: BTreeSet<String> = BTreeSet::default();
for input_derivation_path in derivation.input_derivations.keys() {
Expand Down Expand Up @@ -386,9 +401,7 @@ pub fn get_package_graph(
};
if child_derivation_name != "source" && packages.get(child_derivation_name).is_some() {
log::info!("Found a child derivation that is a main package!!!!!!");
current_node
.children
.insert(child_derivation_path.to_string());
current_node.children.insert(child_derivation_path.to_string());
// FIXME should we really continue here? Are there derivations that define both a
// package meta and urls to fetch?
continue;
Expand All @@ -401,7 +414,13 @@ pub fn get_package_graph(
continue;
}
if child_derivation.get_url().is_some() {
current_node.sources.push(child_derivation.clone());
if child_derivation.env.get("out").is_some()
&& current_node_patches.contains(child_derivation.env.get("out").unwrap())
{
current_node.patches.push(child_derivation.clone());
} else {
current_node.sources.push(child_derivation.clone());
}
}

for input_derivation_path in child_derivation.input_derivations.keys() {
Expand Down
84 changes: 22 additions & 62 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ use lazy_static::lazy_static;
use regex::Regex;

lazy_static! {
static ref SEMVER_REGEX: Regex =
Regex::new(r"([0-9]+.[0-9]+.[0-9]+)(-[0-9a-zA-Z_]+)?").unwrap();
static ref SEMVER_REGEX: Regex = Regex::new(r"([0-9]+.[0-9]+.[0-9]+)(-[0-9a-zA-Z_]+)?").unwrap();
}

lazy_static! {
static ref GIT_PROJECT_URL_REGEX: Regex =
Regex::new(r"https?://([0-9a-zA-Z/._-]+)\.git").unwrap();
static ref GIT_PROJECT_URL_REGEX: Regex = Regex::new(r"https?://([0-9a-zA-Z/._-]+)\.git").unwrap();
}

lazy_static! {
Expand All @@ -27,8 +25,7 @@ lazy_static! {
}

lazy_static! {
static ref PAGURE_PROJECT_REGEX: Regex =
Regex::new(r"https://pagure.io/([0-9a-zA-Z_-]+)").unwrap();
static ref PAGURE_PROJECT_REGEX: Regex = Regex::new(r"https://pagure.io/([0-9a-zA-Z_-]+)").unwrap();
}

lazy_static! {
Expand All @@ -49,6 +46,7 @@ lazy_static! {
static ref BITBUCKET_PROJECT_REGEX: Regex =
Regex::new(r"https?://bitbucket.org/([0-9a-zA-Z_-]+)/([0-9a-zA-Z_-]+)").unwrap();
}

pub fn get_git_url_from_generic_url(generic_url: &str) -> Option<String> {
if let Some(git_url) = get_github_url_from_generic_url(generic_url) {
return Some(git_url);
Expand Down Expand Up @@ -89,10 +87,7 @@ pub fn get_github_url_from_generic_url(generic_url: &str) -> Option<String> {
}
let user_name: String = captured_groups[1].to_string();
let project_name: String = captured_groups[2].to_string();
return Some(format!(
"https://github.com/{}/{}.git",
user_name, project_name
));
return Some(format!("https://github.com/{}/{}.git", user_name, project_name));
}

pub fn get_gitlab_url_from_generic_url(generic_url: &str) -> Option<String> {
Expand All @@ -105,10 +100,7 @@ pub fn get_gitlab_url_from_generic_url(generic_url: &str) -> Option<String> {
}
let user_name: String = captured_groups[1].to_string();
let project_name: String = captured_groups[2].to_string();
return Some(format!(
"https://gitlab.com/{}/{}.git",
user_name, project_name
));
return Some(format!("https://gitlab.com/{}/{}.git", user_name, project_name));
}

pub fn get_gnome_gitlab_url_from_generic_url(generic_url: &str) -> Option<String> {
Expand Down Expand Up @@ -148,10 +140,7 @@ pub fn get_gnu_url_from_generic_url(generic_url: &str) -> Option<String> {
return None;
}
let project_name: String = captured_groups[1].to_string();
return Some(format!(
"https://git.savannah.gnu.org/git/{}.git",
project_name
));
return Some(format!("https://git.savannah.gnu.org/git/{}.git", project_name));
}

pub fn get_nongnu_release_url_from_generic_url(generic_url: &str) -> Option<String> {
Expand Down Expand Up @@ -196,10 +185,7 @@ pub fn get_bitbucket_url_from_generic_url(generic_url: &str) -> Option<String> {
}
let username: String = captured_groups[1].to_string();
let project_name: String = captured_groups[2].to_string();
return Some(format!(
"https://bitbucket.org/{}/{}.git",
username, project_name
));
return Some(format!("https://bitbucket.org/{}/{}.git", username, project_name));
}

#[cfg(test)]
Expand All @@ -208,9 +194,8 @@ mod tests {

#[test]
pub fn test_get_git_url_from_generic_url() {
let git_url = crate::utils::get_git_url_from_generic_url(
"https://github.com/sass/libsass/archive/3.6.4.tar.gz",
);
let git_url =
crate::utils::get_git_url_from_generic_url("https://github.com/sass/libsass/archive/3.6.4.tar.gz");
assert!(git_url.is_some());
assert_eq!(git_url.unwrap(), "https://github.com/sass/libsass.git");

Expand All @@ -222,35 +207,21 @@ mod tests {
"https://gitlab.com/rszibele/e-juice-calc/-/archive/1.0.7/e-juice-calc-1.0.7.tar.bz2",
);
assert!(git_url.is_some());
assert_eq!(
git_url.unwrap(),
"https://gitlab.com/rszibele/e-juice-calc.git"
);
assert_eq!(git_url.unwrap(), "https://gitlab.com/rszibele/e-juice-calc.git");

let git_url =
crate::utils::get_git_url_from_generic_url("https://gitlab.com/rszibele/e-juice-calc");
let git_url = crate::utils::get_git_url_from_generic_url("https://gitlab.com/rszibele/e-juice-calc");
assert!(git_url.is_some());
assert_eq!(
git_url.unwrap(),
"https://gitlab.com/rszibele/e-juice-calc.git"
);
assert_eq!(git_url.unwrap(), "https://gitlab.com/rszibele/e-juice-calc.git");

let git_url = crate::utils::get_git_url_from_generic_url(
"https://gitlab.gnome.org/GNOME/libsecret/-/archive/0.19.1/libsecret-0.19.1.tar.gz",
);
assert!(git_url.is_some());
assert_eq!(
git_url.unwrap(),
"https://gitlab.gnome.org/GNOME/libsecret.git"
);
assert_eq!(git_url.unwrap(), "https://gitlab.gnome.org/GNOME/libsecret.git");

let git_url =
crate::utils::get_git_url_from_generic_url("https://gitlab.gnome.org/GNOME/libsecret");
let git_url = crate::utils::get_git_url_from_generic_url("https://gitlab.gnome.org/GNOME/libsecret");
assert!(git_url.is_some());
assert_eq!(
git_url.unwrap(),
"https://gitlab.gnome.org/GNOME/libsecret.git"
);
assert_eq!(git_url.unwrap(), "https://gitlab.gnome.org/GNOME/libsecret.git");

let git_url = crate::utils::get_git_url_from_generic_url(
"https://pagure.io/libaio/archive/libaio-0.3.111/libaio-libaio-0.3.111.tar.gz",
Expand All @@ -262,19 +233,12 @@ mod tests {
"https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.16.tar.gz",
);
assert!(git_url.is_some());
assert_eq!(
git_url.unwrap(),
"https://git.savannah.gnu.org/git/libiconv.git"
);
assert_eq!(git_url.unwrap(), "https://git.savannah.gnu.org/git/libiconv.git");

let git_url = crate::utils::get_git_url_from_generic_url(
"http://ftp.gnu.org/gnu/autoconf/autoconf-2.13.tar.gz",
);
let git_url =
crate::utils::get_git_url_from_generic_url("http://ftp.gnu.org/gnu/autoconf/autoconf-2.13.tar.gz");
assert!(git_url.is_some());
assert_eq!(
git_url.unwrap(),
"https://git.savannah.gnu.org/git/autoconf.git"
);
assert_eq!(git_url.unwrap(), "https://git.savannah.gnu.org/git/autoconf.git");

let git_url = crate::utils::get_git_url_from_generic_url(
"https://download.savannah.nongnu.org/releases/openexr/openexr-2.2.1.tar.gz",
Expand All @@ -294,13 +258,9 @@ mod tests {
"https://git.savannah.nongnu.org/git/icoutils.git"
);

let git_url =
crate::utils::get_git_url_from_generic_url("https://savannah.nongnu.org/projects/acl");
let git_url = crate::utils::get_git_url_from_generic_url("https://savannah.nongnu.org/projects/acl");
assert!(git_url.is_some());
assert_eq!(
git_url.unwrap(),
"https://git.savannah.nongnu.org/git/acl.git"
);
assert_eq!(git_url.unwrap(), "https://git.savannah.nongnu.org/git/acl.git");

let git_url = crate::utils::get_git_url_from_generic_url(
"https://bitbucket.org/Doomseeker/doomseeker/get/1.3.1.tar.bz2",
Expand Down

0 comments on commit cd04970

Please sign in to comment.