Skip to content

Commit 8caaf3f

Browse files
committed
fix docker image url parsing
1 parent 717c40f commit 8caaf3f

5 files changed

Lines changed: 132 additions & 17 deletions

File tree

.github/workflows/test.yaml

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,54 @@ env:
1414
jobs:
1515
check-linux:
1616
name: check-linux
17-
runs-on: ubuntu-latest
17+
strategy:
18+
matrix:
19+
platform:
20+
- os_name: Linux-x86_64
21+
os: ubuntu-latest
22+
target: x86_64-unknown-linux-musl
23+
bin: coman
24+
name: coman-Linux-x86_64-musl.tar.gz
25+
cargo_command: cargo
26+
27+
- os_name: Windows-aarch64
28+
os: windows-latest
29+
target: aarch64-pc-windows-msvc
30+
bin: coman.exe
31+
name: coman-Windows-aarch64.zip
32+
cargo_command: cargo
33+
34+
# enable this if there's ever a case where something works on linux but not on macos
35+
# - os_name: macOS-x86_64
36+
# os: macOS-latest
37+
# target: x86_64-apple-darwin
38+
# bin: coman
39+
# name: coman-Darwin-x86_64.tar.gz
40+
# cargo_command: cargo
41+
runs-on: ${{ matrix.platform.os }}
1842
steps:
1943
- name: Checkout
2044
uses: actions/checkout@v5
21-
- name: setup rust
22-
run: |
23-
rustup update stable
24-
rustup default stable
25-
rustup component add --toolchain nightly-x86_64-unknown-linux-gnu rustfmt
45+
- name: Install toolchain
46+
# nightly needed for cargo fmt
47+
uses: dtolnay/rust-toolchain@nightly
48+
with:
49+
targets: ${{ matrix.platform.target }}
50+
components: clippy rustfmt
2651
- name: Rust cache
2752
uses: Swatinem/rust-cache@v2
2853
with:
2954
prefix-key: "v0-rust"
55+
cache-workspace-crates: "true"
3056
- name: install tooling
3157
run: cargo install oas3-gen@0.21.1
3258
- name: Build
3359
run: cargo build --verbose
3460
- name: Check formatting
61+
if: contains(matrix.platform.os, 'ubuntu')
3562
run: cargo +nightly fmt --check
3663
- name: Lint
64+
if: contains(matrix.platform.os, 'ubuntu')
3765
run: cargo clippy --all-targets --all-features -p coman
3866
- name: Test
3967
run: cargo test --verbose

Cargo.lock

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coman/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,6 @@ aws-sdk-s3 = "1.115.0"
7676
[build-dependencies]
7777
anyhow = "1.0.90"
7878
vergen-gix = { version = "1.0.2", features = ["build", "cargo"] }
79+
80+
[dev-dependencies]
81+
rstest = "0.26.1"

coman/src/util/types.rs

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use nom::{
99
bytes::tag,
1010
character::complete::{alphanumeric1, digit1},
1111
combinator::{complete, opt, recognize},
12-
multi::separated_list1,
12+
multi::{many_m_n, many1, separated_list0, separated_list1},
1313
sequence::{preceded, terminated},
1414
};
1515
use oci_distribution::{
@@ -127,18 +127,31 @@ impl FromStr for DockerImageUrl {
127127
type Err = Report;
128128

129129
fn from_str(s: &str) -> Result<Self, Self::Err> {
130-
let mut parser = complete((
131-
opt(terminated(
130+
// see https://ktomk.github.io/pipelines/doc/DOCKER-NAME-TAG.html#syntax
131+
let host = opt(terminated(
132+
alt((
133+
recognize((separated_list1(tag("."), alphanumeric1), tag(":"), digit1)),
134+
recognize(separated_list1(tag("."), alphanumeric1)),
135+
)),
136+
tag("/"),
137+
));
138+
let image = recognize(separated_list0(
139+
tag("/"),
140+
separated_list0(
132141
alt((
133-
recognize((separated_list1(tag("."), alphanumeric1), tag(":"), digit1)),
134-
recognize(separated_list1(tag("."), alphanumeric1)),
142+
tag("."),
143+
recognize(many_m_n(1, 2, tag("_"))),
144+
recognize(many1(tag("-"))),
135145
)),
136-
tag("/"),
137-
)),
138-
alt((recognize((alphanumeric1, tag("/"), alphanumeric1)), alphanumeric1)),
139-
opt(preceded(tag(":"), alphanumeric1)),
140-
opt(preceded(tag("@sha256:"), alphanumeric1)),
146+
alphanumeric1,
147+
),
148+
));
149+
let docker_tag = opt(preceded(
150+
tag(":"),
151+
recognize(separated_list0(alt((tag("."), tag("-"))), alphanumeric1)),
141152
));
153+
let digest = opt(preceded(tag("@sha256:"), alphanumeric1));
154+
let mut parser = complete((host, image, docker_tag, digest));
142155
let parsed: DockerParseType = parser.parse(s);
143156
match parsed {
144157
Ok(result) => Ok(DockerImageUrl {
@@ -178,3 +191,26 @@ impl Display for DockerImageUrl {
178191
Ok(())
179192
}
180193
}
194+
195+
#[cfg(test)]
196+
mod tests {
197+
use rstest::rstest;
198+
199+
use super::*;
200+
201+
#[rstest]
202+
#[case("ubuntu",(None,"ubuntu",None,None))]
203+
#[case("docker.io/library/hello-world:latest@sha256:deadbeef",(Some("docker.io"),"library/hello-world",Some("latest"),Some("deadbeef")))]
204+
#[case("ghcr.io/swissdatasciencecenter/renku-frontend-buildpacks/run-image:0.2.1",(Some("ghcr.io"),"swissdatasciencecenter/renku-frontend-buildpacks/run-image",Some("0.2.1"),None))]
205+
#[case("test.ghcr.io/a/b/c/d/e:a-1.f-2", (Some("test.ghcr.io"), "a/b/c/d/e", Some("a-1.f-2"), None))]
206+
fn test_docker_parsing(
207+
#[case] docker_url: &str,
208+
#[case] expected: (Option<&str>, &str, Option<&str>, Option<&str>),
209+
) {
210+
let image = DockerImageUrl::from_str(docker_url).expect("couldn't parse image");
211+
assert_eq!(image.registry, expected.0.map(|s| s.to_owned()));
212+
assert_eq!(image.image.as_str(), expected.1);
213+
assert_eq!(image.tag, expected.2.map(|s| s.to_owned()));
214+
assert_eq!(image.digest, expected.3.map(|s| s.to_owned()));
215+
}
216+
}

firecrest_client/src/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//! AUTO-GENERATED CODE - DO NOT EDIT!
1010
//!
1111
//! FirecREST
12-
//! Source: /tmp/.tmprFbIr1.json
12+
//! Source: /tmp/.tmppwtkBD.json
1313
//! Version: 2.4.1
1414
//! Generated by `oas3-gen v0.21.1`
1515
//!

0 commit comments

Comments
 (0)