From 80bf38904a525674d34222454de2fc2fc96056f2 Mon Sep 17 00:00:00 2001 From: Joey Riches Date: Sat, 22 Feb 2025 14:41:16 +0000 Subject: [PATCH 1/2] boulder/draft: Allow transforming the given URL We may want to sanitize the URL given in some cases. --- boulder/src/draft/metadata.rs | 11 ++++++++++- boulder/src/draft/metadata/basic.rs | 1 + boulder/src/draft/metadata/github.rs | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/boulder/src/draft/metadata.rs b/boulder/src/draft/metadata.rs index c775a06f..2e8585e0 100644 --- a/boulder/src/draft/metadata.rs +++ b/boulder/src/draft/metadata.rs @@ -20,6 +20,7 @@ pub struct Source { pub name: String, pub version: String, pub homepage: String, + pub uri: String, } impl Metadata { @@ -45,7 +46,15 @@ impl Metadata { pub fn upstreams(&self) -> String { self.upstreams .iter() - .map(|Upstream { uri, hash }| format!(" - {uri} : {hash}")) + .enumerate() + .map(|(i, Upstream { uri, hash })| { + let uri_to_use = if i == 0 && !self.source.uri.is_empty() { + &self.source.uri + } else { + uri.as_str() + }; + format!(" - {uri_to_use} : {hash}") + }) .join("\n") } } diff --git a/boulder/src/draft/metadata/basic.rs b/boulder/src/draft/metadata/basic.rs index 43957956..40a0d89c 100644 --- a/boulder/src/draft/metadata/basic.rs +++ b/boulder/src/draft/metadata/basic.rs @@ -24,5 +24,6 @@ pub fn source(upstream: &Url) -> Option { name, version, homepage: homepage.to_owned(), + uri: upstream.to_string(), }) } diff --git a/boulder/src/draft/metadata/github.rs b/boulder/src/draft/metadata/github.rs index 5c435789..989b34af 100644 --- a/boulder/src/draft/metadata/github.rs +++ b/boulder/src/draft/metadata/github.rs @@ -30,6 +30,7 @@ pub fn source(upstream: &Url) -> Option { name: project.to_lowercase(), version, homepage: format!("https://github.com/{owner}/{project}"), + uri: upstream.to_string(), }); } From 4fbebd76084a6718e03156d65c3b1e098410dea5 Mon Sep 17 00:00:00 2001 From: Joey Riches Date: Sat, 22 Feb 2025 14:42:13 +0000 Subject: [PATCH 2/2] boulder/draft: Add metadata matching for pypi.org --- boulder/src/draft/metadata.rs | 5 +++- boulder/src/draft/metadata/pypi.rs | 37 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 boulder/src/draft/metadata/pypi.rs diff --git a/boulder/src/draft/metadata.rs b/boulder/src/draft/metadata.rs index 2e8585e0..0faf31b8 100644 --- a/boulder/src/draft/metadata.rs +++ b/boulder/src/draft/metadata.rs @@ -8,6 +8,7 @@ use super::Upstream; mod basic; mod github; +mod pypi; #[derive(Default)] pub struct Metadata { @@ -33,6 +34,7 @@ impl Metadata { if let Some(matched) = match matcher { Matcher::Basic => basic::source(&upstream.uri), Matcher::Github => github::source(&upstream.uri), + Matcher::Pypi => pypi::source(&upstream.uri), } { source = matched; break; @@ -62,8 +64,9 @@ impl Metadata { enum Matcher { Basic, Github, + Pypi, } impl Matcher { - const ALL: &'static [Self] = &[Self::Github, Self::Basic]; + const ALL: &'static [Self] = &[Self::Github, Self::Pypi, Self::Basic]; } diff --git a/boulder/src/draft/metadata/pypi.rs b/boulder/src/draft/metadata/pypi.rs new file mode 100644 index 00000000..99d1b086 --- /dev/null +++ b/boulder/src/draft/metadata/pypi.rs @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: Copyright © 2020-2025 Serpent OS Developers +// +// SPDX-License-Identifier: MPL-2.0 + +use regex::Regex; +use url::Url; + +use crate::util; + +use super::Source; + +pub fn source(upstream: &Url) -> Option { + let regex = Regex::new( + r"^https://files\.pythonhosted\.org/packages/[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]+/([^/]+)-([\d.]+)\.tar\.gz$", + ) + .ok()?; + + let filename = util::uri_file_name(upstream); + + let captures = regex.captures(upstream.as_str())?; + + let mut name = captures.get(1)?.as_str().to_owned(); + let version = captures.get(2)?.as_str().to_owned(); + + let first_char = &name.chars().next().unwrap_or_default(); + + if !name.starts_with("python-") { + name = format!("python-{name}"); + } + + Some(Source { + name: name.to_owned(), + version, + homepage: format!("https://pypi.org/project/{name}"), + uri: format!("https://files.pythonhosted.org/packages/source/{first_char}/{name}/{filename}"), + }) +}