mirror of
https://github.com/sergi0g/cup.git
synced 2025-11-17 09:33:38 -05:00
Replace reference regex with homemade logic. Can we go faster?
This commit is contained in:
@@ -1,51 +1,48 @@
|
|||||||
use once_cell::sync::Lazy;
|
|
||||||
use regex::Regex;
|
|
||||||
|
|
||||||
use crate::error;
|
|
||||||
|
|
||||||
const DEFAULT_REGISTRY: &str = "registry-1.docker.io";
|
const DEFAULT_REGISTRY: &str = "registry-1.docker.io";
|
||||||
|
|
||||||
/// Takes an image and splits it into registry, repository and tag, based on the reference.
|
/// 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']`.
|
/// For example, `ghcr.io/sergi0g/cup:latest` becomes `['ghcr.io', 'sergi0g/cup', 'latest']`.
|
||||||
pub fn split(reference: &str) -> (String, String, String) {
|
pub fn split(reference: &str) -> (String, String, String) {
|
||||||
match REFERENCE_REGEX.captures(reference) {
|
let splits = reference.split('/').collect::<Vec<&str>>();
|
||||||
Some(c) => {
|
let (registry, repository_and_tag) = match splits.len() {
|
||||||
let registry = match c.name("registry") {
|
0 => unreachable!(),
|
||||||
Some(registry) => registry.as_str().to_owned(),
|
1 => (DEFAULT_REGISTRY, reference.to_string()),
|
||||||
None => String::from(DEFAULT_REGISTRY),
|
_ => {
|
||||||
};
|
// Check if we're looking at a domain
|
||||||
let is_default_registry = registry == DEFAULT_REGISTRY;
|
if splits[0] == "localhost" || splits[0].contains('.') || splits[0].contains(':') {
|
||||||
return (
|
(splits[0], splits[1..].join("/"))
|
||||||
registry,
|
} else {
|
||||||
match c.name("repository") {
|
(DEFAULT_REGISTRY, reference.to_string())
|
||||||
Some(repository) => {
|
}
|
||||||
let repo = repository.as_str().to_owned();
|
|
||||||
if !repo.contains('/') && is_default_registry {
|
|
||||||
format!("library/{}", repo)
|
|
||||||
} else {
|
|
||||||
repo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => 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())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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()
|
|
||||||
});
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -53,17 +50,17 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn reference() {
|
fn reference() {
|
||||||
assert_eq!(split("alpine"), (String::from(DEFAULT_REGISTRY), String::from("library/alpine"), String::from("latest")));
|
assert_eq!(split("alpine" ), (String::from(DEFAULT_REGISTRY ), String::from("library/alpine" ), String::from("latest")));
|
||||||
assert_eq!(split("alpine:latest"), (String::from(DEFAULT_REGISTRY), String::from("library/alpine"), String::from("latest")));
|
assert_eq!(split("alpine:latest" ), (String::from(DEFAULT_REGISTRY ), String::from("library/alpine" ), String::from("latest")));
|
||||||
assert_eq!(split("library/alpine"), (String::from(DEFAULT_REGISTRY), String::from("library/alpine"), String::from("latest")));
|
assert_eq!(split("library/alpine" ), (String::from(DEFAULT_REGISTRY ), String::from("library/alpine" ), String::from("latest")));
|
||||||
assert_eq!(split("localhost/test"), (String::from("localhost"), String::from("test"), String::from("latest")));
|
assert_eq!(split("localhost/test" ), (String::from("localhost" ), String::from("test" ), String::from("latest")));
|
||||||
assert_eq!(split("localhost:1234/test"), (String::from("localhost:1234"), String::from("test"), String::from("latest")));
|
assert_eq!(split("localhost:1234/test" ), (String::from("localhost:1234" ), String::from("test" ), String::from("latest")));
|
||||||
assert_eq!(split("test:1234/idk"), (String::from("test:1234"), String::from("idk"), String::from("latest")));
|
assert_eq!(split("test:1234/idk" ), (String::from("test:1234" ), String::from("idk" ), String::from("latest")));
|
||||||
assert_eq!(split("alpine:3.7"), (String::from(DEFAULT_REGISTRY), String::from("library/alpine"), String::from("3.7")));
|
assert_eq!(split("alpine:3.7" ), (String::from(DEFAULT_REGISTRY ), String::from("library/alpine" ), String::from("3.7" )));
|
||||||
assert_eq!(split("docker.example.com/examplerepo/alpine:3.7"), (String::from("docker.example.com"), String::from("examplerepo/alpine"), String::from("3.7")));
|
assert_eq!(split("docker.example.com/examplerepo/alpine:3.7" ), (String::from("docker.example.com" ), String::from("examplerepo/alpine" ), String::from("3.7" )));
|
||||||
assert_eq!(split("docker.example.com/examplerepo/alpine/test2:3.7"), (String::from("docker.example.com"), String::from("examplerepo/alpine/test2"), String::from("3.7")));
|
assert_eq!(split("docker.example.com/examplerepo/alpine/test2:3.7" ), (String::from("docker.example.com" ), String::from("examplerepo/alpine/test2" ), String::from("3.7" )));
|
||||||
assert_eq!(split("docker.example.com/examplerepo/alpine/test2/test3:3.7"), (String::from("docker.example.com"), String::from("examplerepo/alpine/test2/test3"), String::from("3.7")));
|
assert_eq!(split("docker.example.com/examplerepo/alpine/test2/test3:3.7"), (String::from("docker.example.com" ), String::from("examplerepo/alpine/test2/test3"), String::from("3.7" )));
|
||||||
assert_eq!(split("docker.example.com:5000/examplerepo/alpine:latest"), (String::from("docker.example.com:5000"), String::from("examplerepo/alpine"), String::from("latest")));
|
assert_eq!(split("docker.example.com:5000/examplerepo/alpine:latest" ), (String::from("docker.example.com:5000"), String::from("examplerepo/alpine" ), String::from("latest")));
|
||||||
assert_eq!(split("portainer/portainer:latest"), (String::from(DEFAULT_REGISTRY), String::from("portainer/portainer"), String::from("latest")));
|
assert_eq!(split("portainer/portainer:latest" ), (String::from(DEFAULT_REGISTRY ), String::from("portainer/portainer" ), String::from("latest")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user