commit 1d4fd61d620ea15c2ef27cf0d2b43393e67143bf from: Murilo Ijanc date: Sat Apr 25 18:50:23 2026 UTC fetch and propagate upstream link.mk to vendor/.mk Upstream libs that need native link flags or compile-time env vars ship a link.mk at the repository root. marmita now reads it on add and update, copies it into the consumer's vendor/ directory renamed to .mk, and removes it on rm. The consumer's Makefile picks the file up via -include $(wildcard vendor/*.mk). commit - 909f9a264cd944a07663229da8c7a3bcea3b8669 commit + 1d4fd61d620ea15c2ef27cf0d2b43393e67143bf blob - 3052036d179adf94e91e509edee5c4300de5ebb2 blob + 19085ff7394171e68015bf889e644db55d39e9a8 --- marmita.rs +++ marmita.rs @@ -27,6 +27,7 @@ use std::{ const VENDOR_DIR: &str = "vendor"; const VENDOR_FILE: &str = "vendor/VENDOR"; +const LINK_FILE: &str = "link.mk"; const TRAILER: &str = "Managed by marmita(1). Use 'marmita update' to refresh.\n"; @@ -523,6 +524,14 @@ fn deduce_filename(url: &str) -> String { format!("{stem}.rs") } +fn link_name(file: &str) -> String { + let stem = Path::new(file) + .file_stem() + .and_then(|s| s.to_str()) + .unwrap_or(file); + format!("{stem}.mk") +} + fn looks_like_oid(s: &str) -> bool { s.len() >= 7 && s.len() <= 40 && s.chars().all(|c| c.is_ascii_hexdigit()) } @@ -571,13 +580,14 @@ fn fetch_file( url: &str, spec: &str, file: &str, -) -> Result<(String, Vec), String> { +) -> Result<(String, Vec, Option>), String> { let tmp = make_tempdir()?; let result = (|| { let repo = clone(url, &tmp)?; let commit = resolve_commit(&repo, spec)?; let bytes = read_blob(&repo, &commit, file)?; - Ok((commit, bytes)) + let link = read_blob(&repo, &commit, LINK_FILE).ok(); + Ok((commit, bytes, link)) })(); let _ = fs::remove_dir_all(&tmp); result @@ -611,13 +621,21 @@ fn cmd_add(args: &[String]) -> Result<(), String> { let file = file_arg.unwrap_or_else(|| deduce_filename(&url)); let spec = reference.as_deref().unwrap_or("HEAD"); - let (commit, bytes) = fetch_file(&url, spec, &file)?; + let (commit, bytes, link) = fetch_file(&url, spec, &file)?; fs::create_dir_all(VENDOR_DIR) .map_err(|e| format!("mkdir {VENDOR_DIR}: {e}"))?; let dest = Path::new(VENDOR_DIR).join(&file); fs::write(&dest, &bytes) .map_err(|e| format!("write {}: {e}", dest.display()))?; + let link_dest = Path::new(VENDOR_DIR).join(link_name(&file)); + match link { + Some(b) => fs::write(&link_dest, b) + .map_err(|e| format!("write {}: {e}", link_dest.display()))?, + None => { + let _ = fs::remove_file(&link_dest); + } + } let mut entries: Vec = read_manifest()? .into_iter() @@ -672,10 +690,19 @@ fn cmd_update(args: &[String]) -> Result<(), String> { continue; } }; - let (commit, bytes) = fetch_file(&e.origin, &spec, &e.file)?; + let (commit, bytes, link) = fetch_file(&e.origin, &spec, &e.file)?; let dest = Path::new(VENDOR_DIR).join(&e.file); fs::write(&dest, &bytes) .map_err(|err| format!("write {}: {err}", dest.display()))?; + let link_dest = Path::new(VENDOR_DIR).join(link_name(&e.file)); + match link { + Some(b) => fs::write(&link_dest, b).map_err(|err| { + format!("write {}: {err}", link_dest.display()) + })?, + None => { + let _ = fs::remove_file(&link_dest); + } + } let changed = e.commit != commit; e.commit = commit.clone(); e.date = today_utc(); @@ -712,6 +739,8 @@ fn cmd_rm(args: &[String]) -> Result<(), String> { Err(e) if e.kind() == std::io::ErrorKind::NotFound => {} Err(e) => return Err(format!("remove {}: {e}", path.display())), } + let link_path = Path::new(VENDOR_DIR).join(link_name(file)); + let _ = fs::remove_file(&link_path); write_manifest(&mut entries)?; println!("removed {file}"); Ok(())