m/cup
1
0
mirror of https://github.com/sergi0g/cup.git synced 2025-11-17 01:23:39 -05:00

Replace reference regex with homemade logic. Can we go faster?

This commit is contained in:
Sergio
2024-12-05 21:07:13 +02:00
parent 6a77b85141
commit ce08e00bb4

View File

@@ -1,50 +1,47 @@
use once_cell::sync::Lazy;
use regex::Regex;
use crate::error;
const DEFAULT_REGISTRY: &str = "registry-1.docker.io";
/// Takes an image and splits it into registry, repository and tag, based on the reference.
/// For example, `ghcr.io/sergi0g/cup:latest` becomes `['ghcr.io', 'sergi0g/cup', 'latest']`.
pub fn split(reference: &str) -> (String, String, String) {
match REFERENCE_REGEX.captures(reference) {
Some(c) => {
let registry = match c.name("registry") {
Some(registry) => registry.as_str().to_owned(),
None => String::from(DEFAULT_REGISTRY),
};
let is_default_registry = registry == DEFAULT_REGISTRY;
return (
registry,
match c.name("repository") {
Some(repository) => {
let repo = repository.as_str().to_owned();
if !repo.contains('/') && is_default_registry {
format!("library/{}", repo)
let splits = reference.split('/').collect::<Vec<&str>>();
let (registry, repository_and_tag) = match splits.len() {
0 => unreachable!(),
1 => (DEFAULT_REGISTRY, reference.to_string()),
_ => {
// Check if we're looking at a domain
if splits[0] == "localhost" || splits[0].contains('.') || splits[0].contains(':') {
(splits[0], splits[1..].join("/"))
} else {
repo
(DEFAULT_REGISTRY, reference.to_string())
}
}
None => error!("Failed to parse image {}", reference),
},
match c.name("tag") {
Some(tag) => tag.as_str().to_owned(),
None => String::from("latest"),
},
);
}
None => error!("Failed to parse image {}", reference),
};
let splits = repository_and_tag.split(':').collect::<Vec<&str>>();
let (repository, tag) = match splits.len() {
1 | 2 => {
let repository_components = splits[0].split('/').collect::<Vec<&str>>();
let repository = match repository_components.len() {
0 => unreachable!(),
1 => {
if registry == DEFAULT_REGISTRY {
format!("library/{}", repository_components[0])
} else {
splits[0].to_string()
}
}
/// Regex to match Docker image references against, so registry, repository and tag can be extracted.
static REFERENCE_REGEX: Lazy<Regex> = Lazy::new(|| {
Regex::new(
r#"^(?P<name>(?:(?P<registry>(?:(?:localhost|[\w-]+(?:\.[\w-]+)+)(?::\d+)?)|[\w]+:\d+)/)?(?P<repository>[a-z0-9_.-]+(?:/[a-z0-9_.-]+)*))(?::(?P<tag>[\w][\w.-]{0,127}))?$"#, // From https://regex101.com/r/nmSDPA/1
)
.unwrap()
});
_ => splits[0].to_string(),
};
let tag = match splits.len() {
1 => "latest",
2 => splits[1],
_ => unreachable!(),
};
(repository, tag)
}
_ => unreachable!(),
};
(registry.to_string(), repository, tag.to_string())
}
#[cfg(test)]
mod tests {