pub mod backend;
pub mod buildah;
pub mod builder;
pub mod dockerfile;
pub mod error;
#[cfg(target_os = "macos")]
pub mod macos_compat;
#[cfg(target_os = "macos")]
pub mod macos_image_resolver;
#[cfg(target_os = "macos")]
pub mod macos_toolchain;
pub mod pipeline;
#[cfg(target_os = "macos")]
pub mod sandbox_builder;
pub mod templates;
pub mod tui;
pub mod wasm_builder;
pub mod zimage;
pub use buildah::{
current_platform,
install_instructions,
is_platform_supported,
BuildahCommand,
BuildahExecutor,
BuildahInstallation,
BuildahInstaller,
CommandOutput,
InstallError,
};
#[cfg(feature = "cache")]
pub use builder::CacheBackendConfig;
pub use builder::{
BuildOptions, BuildOutput, BuiltImage, ImageBuilder, PullBaseMode, RegistryAuth,
};
pub use dockerfile::{
expand_variables,
AddInstruction,
ArgInstruction,
CopyInstruction,
Dockerfile,
EnvInstruction,
ExposeInstruction,
ExposeProtocol,
HealthcheckInstruction,
ImageRef,
Instruction,
RunInstruction,
ShellOrExec,
Stage,
VariableContext,
};
pub use error::{BuildError, Result};
pub use templates::{
detect_runtime, detect_runtime_with_version, get_template, get_template_by_name,
list_templates, resolve_runtime, Runtime, RuntimeInfo,
};
pub use tui::{BuildEvent, BuildTui, InstructionStatus, PlainLogger};
#[cfg(target_os = "macos")]
pub use sandbox_builder::{SandboxBuildResult, SandboxImageBuilder, SandboxImageConfig};
pub use pipeline::{
parse_pipeline, PipelineCacheConfig, PipelineDefaults, PipelineExecutor, PipelineImage,
PipelineResult, PushConfig, ZPipeline,
};
#[cfg(target_os = "macos")]
pub use backend::SandboxBackend;
pub use backend::{detect_backend, BuildBackend, BuildahBackend};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_and_convert_simple() {
let dockerfile = Dockerfile::parse(
r#"
FROM alpine:3.18
RUN echo "hello"
COPY . /app
WORKDIR /app
"#,
)
.unwrap();
assert_eq!(dockerfile.stages.len(), 1);
let stage = &dockerfile.stages[0];
assert_eq!(stage.instructions.len(), 3);
let container = "test-container";
for instruction in &stage.instructions {
let cmds = BuildahCommand::from_instruction(container, instruction);
assert!(!cmds.is_empty() || matches!(instruction, Instruction::Arg(_)));
}
}
#[test]
fn test_parse_multistage_and_convert() {
let dockerfile = Dockerfile::parse(
r#"
FROM golang:1.21 AS builder
WORKDIR /src
COPY . .
RUN go build -o /app
FROM alpine:3.18
COPY --from=builder /app /app
ENTRYPOINT ["/app"]
"#,
)
.unwrap();
assert_eq!(dockerfile.stages.len(), 2);
let builder = &dockerfile.stages[0];
assert_eq!(builder.name, Some("builder".to_string()));
assert_eq!(builder.instructions.len(), 3);
let runtime = &dockerfile.stages[1];
assert!(runtime.name.is_none());
assert_eq!(runtime.instructions.len(), 2);
if let Instruction::Copy(copy) = &runtime.instructions[0] {
assert_eq!(copy.from, Some("builder".to_string()));
} else {
panic!("Expected COPY instruction");
}
}
#[test]
fn test_variable_expansion() {
let mut ctx = VariableContext::new();
ctx.add_arg("VERSION", Some("1.0".to_string()));
ctx.set_env("HOME", "/app".to_string());
assert_eq!(ctx.expand("$VERSION"), "1.0");
assert_eq!(ctx.expand("$HOME"), "/app");
assert_eq!(ctx.expand("${UNSET:-default}"), "default");
}
#[test]
fn test_buildah_command_generation() {
let container = "test";
let run = Instruction::Run(RunInstruction {
command: ShellOrExec::Shell("apt-get update".to_string()),
mounts: vec![],
network: None,
security: None,
});
let cmds = BuildahCommand::from_instruction(container, &run);
assert_eq!(cmds.len(), 1);
assert!(cmds[0].args.contains(&"run".to_string()));
let mut vars = std::collections::HashMap::new();
vars.insert("PATH".to_string(), "/usr/local/bin".to_string());
let env = Instruction::Env(EnvInstruction { vars });
let cmds = BuildahCommand::from_instruction(container, &env);
assert_eq!(cmds.len(), 1);
assert!(cmds[0].args.contains(&"config".to_string()));
assert!(cmds[0].args.contains(&"--env".to_string()));
let workdir = Instruction::Workdir("/app".to_string());
let cmds = BuildahCommand::from_instruction(container, &workdir);
assert_eq!(cmds.len(), 1);
assert!(cmds[0].args.contains(&"--workingdir".to_string()));
}
}