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