Dockerfile field must be present
ci/woodpecker/push/tests Pipeline was successful

This commit is contained in:
2026-07-31 20:18:29 +00:00
parent 15f619ccf7
commit 5b9d870b46
+27 -52
View File
@@ -8,7 +8,7 @@ use serde::Deserialize;
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct DevContainerBuildSchema { pub struct DevContainerBuildSchema {
#[serde(default)] #[serde(default)]
pub dockerfile: Option<String>, pub dockerfile: String,
#[serde(default)] #[serde(default)]
pub args: HashMap<String, String>, pub args: HashMap<String, String>,
} }
@@ -34,7 +34,6 @@ pub struct DevContainerSchema {
#[derive(Debug)] #[derive(Debug)]
pub struct DevContainer { pub struct DevContainer {
/// Absolute or relative path to the Dockerfile/Containerfile to build.
pub container_file_path: PathBuf, pub container_file_path: PathBuf,
pub name: Option<String>, pub name: Option<String>,
pub build_args: HashMap<String, String>, pub build_args: HashMap<String, String>,
@@ -73,10 +72,7 @@ impl TryFrom<(DevContainerSchema, PathBuf)> for DevContainer {
.parent() .parent()
.ok_or_else(|| ParseError::InvalidDevContainerPath(devcontainer_path.clone()))?; .ok_or_else(|| ParseError::InvalidDevContainerPath(devcontainer_path.clone()))?;
let container_file_path = match schema.build.dockerfile.as_deref() { let container_file_path = base_dir.join(schema.build.dockerfile);
Some(file) => base_dir.join(file),
None => first_existing_container_file(base_dir),
};
if !container_file_path.is_file() { if !container_file_path.is_file() {
return Err(ParseError::ContainerFileNotFound(container_file_path)); return Err(ParseError::ContainerFileNotFound(container_file_path));
@@ -94,14 +90,6 @@ impl TryFrom<(DevContainerSchema, PathBuf)> for DevContainer {
} }
} }
fn first_existing_container_file(base_dir: &Path) -> PathBuf {
["Dockerfile", "Containerfile"]
.iter()
.map(|filename| base_dir.join(filename))
.find(|path| path.is_file())
.unwrap_or_else(|| base_dir.join("Dockerfile"))
}
pub async fn parse(path: impl AsRef<Path>) -> Result<DevContainer, ParseError> { pub async fn parse(path: impl AsRef<Path>) -> Result<DevContainer, ParseError> {
let path = path.as_ref().to_path_buf(); let path = path.as_ref().to_path_buf();
let contents = tokio::fs::read_to_string(&path) let contents = tokio::fs::read_to_string(&path)
@@ -126,50 +114,37 @@ mod tests {
use super::*; use super::*;
use std::fs; use std::fs;
#[test] #[tokio::test]
fn resolves_configured_containerfile_relative_to_devcontainer_file() { async fn parses_devcontainer_file() {
let dir = tempfile::tempdir().unwrap();
let devcontainer_path = dir.path().join("devcontainer.json");
let containerfile_path = dir.path().join("Containerfile");
fs::write(&containerfile_path, "FROM alpine\n").unwrap();
let schema = DevContainerSchema {
name: Some("test".into()),
build: DevContainerBuildSchema {
dockerfile: Some("Containerfile".into()),
args: HashMap::new(),
},
workspace_folder: None,
container_env: HashMap::new(),
post_create_command: None,
post_start_command: None,
};
let config = DevContainer::try_from((schema, devcontainer_path)).unwrap();
assert_eq!(config.container_file_path, containerfile_path);
}
#[test]
fn falls_back_to_dockerfile_before_containerfile() {
let dir = tempfile::tempdir().unwrap(); let dir = tempfile::tempdir().unwrap();
let devcontainer_path = dir.path().join("devcontainer.json"); let devcontainer_path = dir.path().join("devcontainer.json");
let dockerfile_path = dir.path().join("Dockerfile"); let dockerfile_path = dir.path().join("Dockerfile");
fs::write(&dockerfile_path, "FROM alpine\n").unwrap(); fs::write(&dockerfile_path, "FROM alpine\n").unwrap();
fs::write(dir.path().join("Containerfile"), "FROM busybox\n").unwrap(); fs::write(
&devcontainer_path,
r#"{
"name": "test",
"build": {
"dockerfile": "Dockerfile",
"args": {
"VERSION": "1"
}
},
"workspaceFolder": "/workspace",
"containerEnv": {
"RUST_LOG": "debug"
}
}"#,
)
.unwrap();
let schema = DevContainerSchema { let config = parse(&devcontainer_path).await.unwrap();
name: None,
build: DevContainerBuildSchema {
dockerfile: None,
args: HashMap::new(),
},
workspace_folder: None,
container_env: HashMap::new(),
post_create_command: None,
post_start_command: None,
};
let config = DevContainer::try_from((schema, devcontainer_path)).unwrap(); assert_eq!(config.name.as_deref(), Some("test"));
assert_eq!(config.container_file_path, dockerfile_path); assert_eq!(config.container_file_path, dockerfile_path);
assert_eq!(config.build_args.get("VERSION").unwrap(), "1");
assert_eq!(config.container_env.get("RUST_LOG").unwrap(), "debug");
assert_eq!(config.workspace_folder.as_deref(), Some("/workspace"));
} }
} }