diff --git a/src/cook/package.rs b/src/cook/package.rs index 1d76ec64..2f033133 100644 --- a/src/cook/package.rs +++ b/src/cook/package.rs @@ -12,7 +12,7 @@ use crate::{ config::CookConfig, cook::{fetch, fs::*, pty::PtyOut}, log_to_pty, - recipe::{BuildKind, CookRecipe, OptionalPackageRecipe, Recipe}, + recipe::{BuildKind, CookRecipe, OptionalPackageRecipe}, }; pub fn package( @@ -192,7 +192,7 @@ pub fn package_toml( let package = Package { name: recipe.name.with_prefix(PackagePrefix::Any), - version: package_version(&recipe.recipe), + version: recipe.guess_version().unwrap_or("TODO".into()), target: recipe.target.to_string(), blake3: hash, network_size, @@ -208,22 +208,6 @@ pub fn package_toml( return Ok(()); } -fn package_version(recipe: &Recipe) -> String { - if recipe.build.kind == BuildKind::None { - "".into() - } else if let Some(v) = &recipe.package.version { - v.to_string() - } else if let Some(r) = &recipe.source { - if let Some(m) = r.guess_version() { - m - } else { - "TODO".into() - } - } else { - "TODO".into() - } -} - pub fn package_target(name: &PackageName) -> &'static str { if name.is_host() { redoxer::host_target() diff --git a/src/recipe.rs b/src/recipe.rs index 979ba9d6..97bbc06c 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -66,26 +66,6 @@ pub enum SourceRecipe { }, } -impl SourceRecipe { - pub fn guess_version(&self) -> Option { - match self { - SourceRecipe::Tar { - tar, - blake3: _, - patches: _, - script: _, - } => { - let re = Regex::new(r"\d+\.\d+\.\d+").unwrap(); - if let Some(arm) = re.captures(&tar) { - return Some(arm.get(0).unwrap().as_str().to_string()); - } - None - } - _ => None, - } - } -} - /// Specifies how to build a recipe #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(tag = "template")] @@ -498,6 +478,62 @@ impl CookRecipe { Ok(()) } + + pub fn guess_version(&self) -> Option { + let recipe = &self.recipe; + if recipe.build.kind == BuildKind::None { + return Some("".into()); // signifies a meta package + } else if let Some(v) = &recipe.package.version { + return Some(v.to_string()); + } + + let re = VersionExtractor::new(); + let mut dir = self.dir.to_path_buf(); + if let Some(r) = &recipe.source { + match r { + SourceRecipe::Tar { + tar, + blake3: _, + patches: _, + script: _, + } => { + if let Some(ver) = re.extract_ver(&tar) { + return Some(ver); + } + } + SourceRecipe::Git { + git: _, + upstream: _, + branch, + rev, + shallow_clone: _, + patches: _, + script: _, + } => { + if let Some(rev) = rev { + if let Some(ver) = re.extract_ver(&rev) { + return Some(ver); + } + } + if let Some(branch) = branch { + if let Some(ver) = re.extract_ver(&branch) { + return Some(ver); + } + } + } + SourceRecipe::SameAs { same_as } => { + dir = self.dir.join(same_as); + } + _ => {} + } + }; + + let cargo_path = dir.join("source/Cargo.toml"); + if let Some(ver) = VersionExtractor::extract_cargo_ver(&cargo_path) { + return Some(ver); + } + None + } } // TODO: Wrap these vectors in a struct @@ -531,6 +567,47 @@ pub struct AutoDeps { pub packages: BTreeSet, } +pub struct VersionExtractor { + regex: Regex, +} + +impl VersionExtractor { + pub fn new() -> Self { + Self { + regex: Regex::new(r"\d+(\.\d+){1,2}").unwrap(), + } + } + pub fn extract_ver(&self, text: &str) -> Option { + if let Some(arm) = self.regex.captures(&text) { + return Some(arm.get(0)?.as_str().to_string()); + } + None + } + fn extract_cargo_ver(path: &Path) -> Option { + let content = std::fs::read_to_string(path).ok()?; + let manifest = content.parse::().ok()?; + + if let Some(version) = manifest + .get("package") + .and_then(|pkg| pkg.get("version")) + .and_then(|v| v.as_str()) + { + return Some(version.to_string()); + } + + if let Some(version) = manifest + .get("workspace") + .and_then(|ws| ws.get("package")) + .and_then(|pkg| pkg.get("version")) + .and_then(|v| v.as_str()) + { + return Some(version.to_string()); + } + + None + } +} + #[cfg(test)] mod tests { use pkg::PackageName; @@ -610,9 +687,6 @@ mod tests { ..Default::default() } ); - - let source = recipe.source.unwrap(); - assert_eq!(source.guess_version(), Some("1.3.3".to_string())); } #[test]