This commit is contained in:
@@ -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,
|
||||||
let schema = DevContainerSchema {
|
r#"{
|
||||||
name: None,
|
"name": "test",
|
||||||
build: DevContainerBuildSchema {
|
"build": {
|
||||||
dockerfile: None,
|
"dockerfile": "Dockerfile",
|
||||||
args: HashMap::new(),
|
"args": {
|
||||||
|
"VERSION": "1"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
workspace_folder: None,
|
"workspaceFolder": "/workspace",
|
||||||
container_env: HashMap::new(),
|
"containerEnv": {
|
||||||
post_create_command: None,
|
"RUST_LOG": "debug"
|
||||||
post_start_command: None,
|
}
|
||||||
};
|
}"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let config = DevContainer::try_from((schema, devcontainer_path)).unwrap();
|
let config = parse(&devcontainer_path).await.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"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user