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