use super::{CommandExecutor, CommandOutput, DockerCommand};
use crate::error::Result;
use async_trait::async_trait;
#[derive(Debug, Clone)]
pub struct PullCommand {
image: String,
all_tags: bool,
disable_content_trust: bool,
platform: Option<String>,
quiet: bool,
pub executor: CommandExecutor,
}
impl PullCommand {
#[must_use]
pub fn new<S: Into<String>>(image: S) -> Self {
Self {
image: image.into(),
all_tags: false,
disable_content_trust: false,
platform: None,
quiet: false,
executor: CommandExecutor::new(),
}
}
#[must_use]
pub fn all_tags(mut self) -> Self {
self.all_tags = true;
self
}
#[must_use]
pub fn disable_content_trust(mut self) -> Self {
self.disable_content_trust = true;
self
}
#[must_use]
pub fn platform<S: Into<String>>(mut self, platform: S) -> Self {
self.platform = Some(platform.into());
self
}
#[must_use]
pub fn quiet(mut self) -> Self {
self.quiet = true;
self
}
#[must_use]
pub fn get_image(&self) -> &str {
&self.image
}
#[must_use]
pub fn is_all_tags(&self) -> bool {
self.all_tags
}
#[must_use]
pub fn is_quiet(&self) -> bool {
self.quiet
}
#[must_use]
pub fn get_platform(&self) -> Option<&str> {
self.platform.as_deref()
}
#[must_use]
pub fn is_content_trust_disabled(&self) -> bool {
self.disable_content_trust
}
#[must_use]
pub fn get_executor(&self) -> &CommandExecutor {
&self.executor
}
#[must_use]
pub fn get_executor_mut(&mut self) -> &mut CommandExecutor {
&mut self.executor
}
}
impl Default for PullCommand {
fn default() -> Self {
Self::new("hello-world")
}
}
#[async_trait]
impl DockerCommand for PullCommand {
type Output = CommandOutput;
fn get_executor(&self) -> &CommandExecutor {
&self.executor
}
fn get_executor_mut(&mut self) -> &mut CommandExecutor {
&mut self.executor
}
fn build_command_args(&self) -> Vec<String> {
let mut args = vec!["pull".to_string()];
if self.all_tags {
args.push("--all-tags".to_string());
}
if self.disable_content_trust {
args.push("--disable-content-trust".to_string());
}
if let Some(ref platform) = self.platform {
args.push("--platform".to_string());
args.push(platform.clone());
}
if self.quiet {
args.push("--quiet".to_string());
}
args.push(self.image.clone());
args.extend(self.executor.raw_args.clone());
args
}
async fn execute(&self) -> Result<Self::Output> {
let args = self.build_command_args();
self.execute_command(args).await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_pull_command_basic() {
let pull_cmd = PullCommand::new("nginx:latest");
let args = pull_cmd.build_command_args();
assert_eq!(args, vec!["pull", "nginx:latest"]);
assert_eq!(pull_cmd.get_image(), "nginx:latest");
assert!(!pull_cmd.is_all_tags());
assert!(!pull_cmd.is_quiet());
assert!(!pull_cmd.is_content_trust_disabled());
assert_eq!(pull_cmd.get_platform(), None);
}
#[test]
fn test_pull_command_with_all_tags() {
let pull_cmd = PullCommand::new("alpine").all_tags();
let args = pull_cmd.build_command_args();
assert!(args.contains(&"--all-tags".to_string()));
assert!(args.contains(&"alpine".to_string()));
assert_eq!(args[0], "pull");
assert!(pull_cmd.is_all_tags());
}
#[test]
fn test_pull_command_with_platform() {
let pull_cmd = PullCommand::new("nginx:latest").platform("linux/arm64");
let args = pull_cmd.build_command_args();
assert!(args.contains(&"--platform".to_string()));
assert!(args.contains(&"linux/arm64".to_string()));
assert!(args.contains(&"nginx:latest".to_string()));
assert_eq!(args[0], "pull");
assert_eq!(pull_cmd.get_platform(), Some("linux/arm64"));
}
#[test]
fn test_pull_command_with_quiet() {
let pull_cmd = PullCommand::new("redis:7.0").quiet();
let args = pull_cmd.build_command_args();
assert!(args.contains(&"--quiet".to_string()));
assert!(args.contains(&"redis:7.0".to_string()));
assert_eq!(args[0], "pull");
assert!(pull_cmd.is_quiet());
}
#[test]
fn test_pull_command_disable_content_trust() {
let pull_cmd = PullCommand::new("ubuntu:22.04").disable_content_trust();
let args = pull_cmd.build_command_args();
assert!(args.contains(&"--disable-content-trust".to_string()));
assert!(args.contains(&"ubuntu:22.04".to_string()));
assert_eq!(args[0], "pull");
assert!(pull_cmd.is_content_trust_disabled());
}
#[test]
fn test_pull_command_all_options() {
let pull_cmd = PullCommand::new("postgres")
.all_tags()
.platform("linux/amd64")
.quiet()
.disable_content_trust();
let args = pull_cmd.build_command_args();
assert!(args.contains(&"--all-tags".to_string()));
assert!(args.contains(&"--platform".to_string()));
assert!(args.contains(&"linux/amd64".to_string()));
assert!(args.contains(&"--quiet".to_string()));
assert!(args.contains(&"--disable-content-trust".to_string()));
assert!(args.contains(&"postgres".to_string()));
assert_eq!(args[0], "pull");
assert!(pull_cmd.is_all_tags());
assert!(pull_cmd.is_quiet());
assert!(pull_cmd.is_content_trust_disabled());
assert_eq!(pull_cmd.get_platform(), Some("linux/amd64"));
assert_eq!(pull_cmd.get_image(), "postgres");
}
#[test]
fn test_pull_command_with_registry() {
let pull_cmd = PullCommand::new("registry.hub.docker.com/library/nginx:alpine");
let args = pull_cmd.build_command_args();
assert_eq!(
args,
vec!["pull", "registry.hub.docker.com/library/nginx:alpine"]
);
assert_eq!(
pull_cmd.get_image(),
"registry.hub.docker.com/library/nginx:alpine"
);
}
#[test]
fn test_pull_command_with_digest() {
let pull_cmd = PullCommand::new(
"nginx@sha256:abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab",
);
let args = pull_cmd.build_command_args();
assert_eq!(
args,
vec![
"pull",
"nginx@sha256:abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab"
]
);
}
#[test]
fn test_pull_command_order() {
let pull_cmd = PullCommand::new("alpine:3.18")
.quiet()
.platform("linux/arm64")
.all_tags();
let args = pull_cmd.build_command_args();
assert_eq!(args[0], "pull");
assert_eq!(args.last(), Some(&"alpine:3.18".to_string()));
assert!(args.contains(&"--all-tags".to_string()));
assert!(args.contains(&"--platform".to_string()));
assert!(args.contains(&"linux/arm64".to_string()));
assert!(args.contains(&"--quiet".to_string()));
}
#[test]
fn test_pull_command_default() {
let pull_cmd = PullCommand::default();
assert_eq!(pull_cmd.get_image(), "hello-world");
}
}