diff --git a/src/api.rs b/src/api.rs index c2eb244..50f0c7e 100644 --- a/src/api.rs +++ b/src/api.rs @@ -36,24 +36,23 @@ use crate::error::ApiError; /// configured `registry_url` base and the given `path`, or if there is an /// error deserializing the HTTP response body as JSON, or if there is an /// error parsing the `Link` header value as an RFC5988 URL. -pub async fn fetch_all Deserialize<'de>>( - base: &Url, +pub async fn fetch_paginated Deserialize<'de>>( + origin: &Url, path: &str, ) -> Result, ApiError> { - log::trace!("fetch_all({path:?})"); + log::trace!("fetch_paginated(origin: {origin:?}, path: {path:?})"); let mut responses: Vec = Vec::default(); - let mut path = String::from(path); + let mut next_path = String::from(path); loop { - log::debug!("GET {path:?}"); - let url = base.join(&path)?; + let url = origin.join(&next_path)?; let resp = reqwest::get(url).await?; let headers = resp.headers().clone(); responses.push(resp.json().await?); if let Some(p) = parse_rfc5988(headers.get(http::header::LINK))? { - path = p; + next_path = p; } else { break; } @@ -74,7 +73,7 @@ pub async fn fetch_all Deserialize<'de>>( /// Returns and `ApiError` if there is a problem parsing contents of the /// supplied header value. fn parse_rfc5988(header_value: Option<&http::HeaderValue>) -> Result, ApiError> { - log::trace!("parse_rfc5988({header_value:?})"); + log::trace!("parse_rfc5988(header_value: {header_value:?})"); if let Some(link_value) = header_value { let link_str = link_value.to_str()?; @@ -124,6 +123,8 @@ fn parse_rfc5988(header_value: Option<&http::HeaderValue>) -> Result Result<(), ApiError> { + log::trace!("parse_response_status(response: {response:?})"); + match response.status() { http::StatusCode::OK => { let headers = response.headers(); diff --git a/src/cli.rs b/src/cli.rs index a1255ea..833bdb8 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -33,10 +33,6 @@ pub(crate) struct Cli { #[command(subcommand)] pub command: Commands, - /// Optional configuration file override. - #[arg(short = 'c', long = "config")] - pub config: Option, - #[arg( long = "log-level", require_equals = true, @@ -48,7 +44,7 @@ pub(crate) struct Cli { )] pub log_level: LogLevel, - /// The host or host:port for the Docker Registry + /// The host or host:port or full base URL of the Docker Registry pub registry: String, } diff --git a/src/commands.rs b/src/commands.rs index 0721c80..e7957aa 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -35,10 +35,10 @@ pub async fn catalog_handler(registry_url: &Url) -> Result<(), ApiError> { repositories: Vec, } - log::trace!("catalog_handler()"); + log::trace!("catalog_handler(registry_url: {registry_url:?})"); let path = "v2/_catalog"; - let responses: Vec = api::fetch_all(registry_url, path).await?; + let responses: Vec = api::fetch_paginated(registry_url, path).await?; let repository_list: Vec<&str> = responses .iter() .flat_map(|r| r.repositories.iter().map(String::as_str)) @@ -66,10 +66,10 @@ pub async fn tags_handler(registry_url: &Url, name: &str) -> Result<(), ApiError tags: Vec, } - log::trace!("tags_handler(name: {name})"); + log::trace!("tags_handler(registry_url: {registry_url:?}, name: {name})"); let path = format!("/v2/{name}/tags/list"); - let responses: Vec = api::fetch_all(registry_url, &path).await?; + let responses: Vec = api::fetch_paginated(registry_url, &path).await?; let tag_list: Vec<&str> = responses .iter() .flat_map(|r| r.tags.iter().map(String::as_str)) @@ -90,7 +90,7 @@ pub async fn tags_handler(registry_url: &Url, name: &str) -> Result<(), ApiError /// is a problem parsing the response from the Docker Registry API. #[allow(clippy::unused_async)] pub async fn show_handler(registry_url: &Url, image: &str, tag: &str) -> Result<(), ApiError> { - log::trace!("show_handler(image: {image}, tag: {tag})"); + log::trace!("show_handler(registry_url: {registry_url:?}, image: {image}, tag: {tag})"); let path = format!("/v2/{image}/manifests/{tag}"); let _url = registry_url.join(&path)?; Ok(()) @@ -104,8 +104,8 @@ pub async fn show_handler(registry_url: &Url, image: &str, tag: &str) -> Result< /// manifest digest, or if there is a problem deleting the manifest from the /// Docker Registry API. #[allow(clippy::unused_async)] -pub async fn delete_handler(_registry_url: &Url, image: &str, tag: &str) -> Result<(), ApiError> { - log::trace!("delete_handler(image: {image}, tag: {tag})"); +pub async fn delete_handler(registry_url: &Url, image: &str, tag: &str) -> Result<(), ApiError> { + log::trace!("delete_handler(registry_url: {registry_url:?}, image: {image}, tag: {tag})"); todo!() } @@ -118,14 +118,12 @@ pub async fn delete_handler(_registry_url: &Url, image: &str, tag: &str) -> Resu /// Returns an `ApiError` if there is a problem communicating with the /// endpoint or if the required version is not supported. pub async fn check_handler(registry_url: &Url) -> Result<(), ApiError> { - log::trace!("check_handler()"); + log::trace!("check_handler(registry_url: {registry_url:?})"); let path = "/v2"; let url = registry_url.join(path)?; let response = reqwest::get(url).await?; - api::parse_response_status(&response)?; - println!("Ok"); Ok(()) }