provenant/parsers/
autotools.rs1use crate::models::PackageData;
25use crate::models::{DatasourceId, PackageType};
26use packageurl::PackageUrl;
27use std::fs;
28use std::path::Path;
29
30use super::PackageParser;
31
32pub struct AutotoolsConfigureParser;
36
37const AUTOCONF_CONFIGURE_MARKERS: &[&str] = &[
38 "generated by gnu autoconf",
39 "generated automatically using autoconf",
40 "please tell bug-autoconf@gnu.org",
41 "configure script for ",
42];
43
44fn looks_like_autoconf_generated_configure(path: &Path) -> bool {
45 fs::read(path)
46 .ok()
47 .map(|content| {
48 String::from_utf8_lossy(&content)
49 .lines()
50 .take(250)
51 .map(|line| line.trim().to_ascii_lowercase())
52 .any(|line| {
53 AUTOCONF_CONFIGURE_MARKERS
54 .iter()
55 .any(|marker| line.contains(marker))
56 })
57 })
58 .unwrap_or(false)
59}
60
61impl PackageParser for AutotoolsConfigureParser {
62 const PACKAGE_TYPE: PackageType = PackageType::Autotools;
63
64 fn is_match(path: &Path) -> bool {
65 match path.file_name().and_then(|name| name.to_str()) {
66 Some("configure.ac") => true,
67 Some("configure") => looks_like_autoconf_generated_configure(path),
68 _ => false,
69 }
70 }
71
72 fn extract_packages(path: &Path) -> Vec<PackageData> {
73 let name = path
74 .parent()
75 .and_then(|p| p.file_name())
76 .and_then(|n| n.to_str())
77 .map(|s| s.to_string())
78 .or_else(|| {
79 path.file_name()
80 .is_some_and(|name| name == "configure" || name == "configure.ac")
81 .then_some("input".to_string())
82 });
83
84 let purl = name.as_deref().and_then(|name| {
85 PackageUrl::new(Self::PACKAGE_TYPE.as_str(), name)
86 .ok()
87 .map(|purl| purl.to_string())
88 });
89
90 vec![PackageData {
91 package_type: Some(Self::PACKAGE_TYPE),
92 name,
93 datasource_id: Some(DatasourceId::AutotoolsConfigure),
94 purl,
95 ..Default::default()
96 }]
97 }
98
99 fn metadata() -> Vec<super::metadata::ParserMetadata> {
100 vec![super::metadata::ParserMetadata {
101 description: "Autotools configure script",
102 file_patterns: &["**/configure", "**/configure.ac"],
103 package_type: "autotools",
104 primary_language: "C",
105 documentation_url: Some("https://www.gnu.org/software/autoconf/"),
106 }]
107 }
108}