From 7afc4aa095167ef4b9bb7c3b233d4594d48c158a Mon Sep 17 00:00:00 2001 From: Thomas DA ROCHA Date: Mon, 23 Sep 2024 15:45:31 +0200 Subject: [PATCH] feat: Manage stage ARG (#277) * feat: Manage stage ARG * docs: JSON Schema --- docs/dofigen.schema.json | 33 ++++++++++++++------- dofigen.lock | 6 +++- dofigen.yml | 2 ++ src/dofigen_struct.rs | 5 ++++ src/generator.rs | 63 ++++++++++++++++++++++++++++++++++++---- tests/lib_test.rs | 9 ++++-- 6 files changed, 99 insertions(+), 19 deletions(-) diff --git a/docs/dofigen.schema.json b/docs/dofigen.schema.json index 92e874f..5708296 100644 --- a/docs/dofigen.schema.json +++ b/docs/dofigen.schema.json @@ -45,6 +45,17 @@ } ], "properties": { + "arg": { + "anyOf": [ + { + "$ref": "#/definitions/HashMapPatch" + }, + { + "type": "null" + } + ], + "nullable": true + }, "bind": { "anyOf": [ { @@ -336,17 +347,6 @@ ], "nullable": true }, - "exclude": { - "anyOf": [ - { - "$ref": "#/definitions/VecPatch" - }, - { - "type": "null" - } - ], - "nullable": true - }, "keepGitDir": { "default": null, "type": [ @@ -1033,6 +1033,17 @@ } ], "properties": { + "arg": { + "anyOf": [ + { + "$ref": "#/definitions/HashMapPatch" + }, + { + "type": "null" + } + ], + "nullable": true + }, "bind": { "anyOf": [ { diff --git a/dofigen.lock b/dofigen.lock index ea37dc9..efc4486 100644 --- a/dofigen.lock +++ b/dofigen.lock @@ -2,6 +2,8 @@ effective: | context: - /builds workdir: /app + arg: + TARGETPLATFORM: '' copy: - paths: - builds/${TARGETPLATFORM}/dofigen @@ -13,10 +15,12 @@ effective: | images: {} resources: dofigen.yml: - hash: f71f101575b39dec6c2b8d21a2a695173eabd8f5be3d02456b6b6b928677fa59 + hash: 160f8547a6b42e0996778ad72c6a73328f8460e826475def77213acb69f45284 content: | # Runtime workdir: /app + arg: + TARGETPLATFORM: "" copy: - paths: builds/${TARGETPLATFORM}/dofigen target: /bin/ diff --git a/dofigen.yml b/dofigen.yml index f98607e..26f0b59 100644 --- a/dofigen.yml +++ b/dofigen.yml @@ -1,5 +1,7 @@ # Runtime workdir: /app +arg: + TARGETPLATFORM: "" copy: - paths: builds/${TARGETPLATFORM}/dofigen target: /bin/ diff --git a/src/dofigen_struct.rs b/src/dofigen_struct.rs index 00f7156..be2f3da 100644 --- a/src/dofigen_struct.rs +++ b/src/dofigen_struct.rs @@ -97,6 +97,11 @@ pub struct Stage { #[serde(skip_serializing_if = "Option::is_none")] pub workdir: Option, + #[patch(name = "HashMapPatch")] + #[cfg_attr(not(feature = "strict"), patch(attribute(serde(alias = "args"))))] + #[serde(skip_serializing_if = "HashMap::is_empty")] + pub arg: HashMap, + #[patch(name = "HashMapPatch")] #[cfg_attr(not(feature = "strict"), patch(attribute(serde(alias = "envs"))))] #[serde(skip_serializing_if = "HashMap::is_empty")] diff --git a/src/generator.rs b/src/generator.rs index 7c849a0..0323a7e 100644 --- a/src/generator.rs +++ b/src/generator.rs @@ -415,6 +415,24 @@ impl DockerfileGenerator for Stage { }), ]; + // Arg + if !self.arg.is_empty() { + let mut keys = self.arg.keys().collect::>(); + keys.sort(); + keys.iter().for_each(|key| { + let value = self.arg.get(*key).unwrap(); + lines.push(DockerfileLine::Instruction(DockerfileInsctruction { + command: "ARG".into(), + content: if value.is_empty() { + key.to_string() + } else { + format!("{}={}", key, value) + }, + options: vec![], + })); + }); + } + // Env if !self.env.is_empty() { lines.push(DockerfileLine::Instruction(DockerfileInsctruction { @@ -730,16 +748,16 @@ mod test { use super::*; use pretty_assertions_sorted::assert_eq_sorted; - mod builder { + mod stage { use super::*; #[test] fn user_with_user() { - let builder = Stage { + let stage = Stage { user: Some(User::new_without_group("my-user").into()), ..Default::default() }; - let user = builder.user(&GenerationContext::default()); + let user = stage.user(&GenerationContext::default()); assert_eq_sorted!( user, Some(User { @@ -751,10 +769,45 @@ mod test { #[test] fn user_without_user() { - let builder = Stage::default(); - let user = builder.user(&GenerationContext::default()); + let stage = Stage::default(); + let user = stage.user(&GenerationContext::default()); assert_eq_sorted!(user, None); } + + #[test] + fn stage_args() { + let stage = Stage { + arg: HashMap::from([("arg2".into(), "".into()), ("arg1".into(), "value1".into())]), + ..Default::default() + }; + + let lines = stage.generate_dockerfile_lines(&GenerationContext { + stage_name: "test".into(), + ..Default::default() + }); + + assert_eq_sorted!( + lines.unwrap(), + vec![ + DockerfileLine::Comment("test".into()), + DockerfileLine::Instruction(DockerfileInsctruction { + command: "FROM".into(), + content: "scratch AS test".into(), + options: vec![], + }), + DockerfileLine::Instruction(DockerfileInsctruction { + command: "ARG".into(), + content: "arg1=value1".into(), + options: vec![], + }), + DockerfileLine::Instruction(DockerfileInsctruction { + command: "ARG".into(), + content: "arg2".into(), + options: vec![], + }), + ] + ); + } } mod image_name { diff --git a/tests/lib_test.rs b/tests/lib_test.rs index 4f89940..a521e5f 100644 --- a/tests/lib_test.rs +++ b/tests/lib_test.rs @@ -44,11 +44,14 @@ builders: - ls -al - cargo build --release cache: /usr/local/cargo/registry +arg: + TARGETPLATFORM: "" + APP_NAME: template-rust env: fprocess: /app artifacts: - fromBuilder: builder - source: /home/rust/src/target/x86_64-unknown-linux-musl/release/template-rust + source: /home/rust/src/target/x86_64-unknown-linux-musl/release/${APP_NAME} target: /app - fromImage: ghcr.io/openfaas/of-watchdog:0.9.6 source: /fwatchdog @@ -91,12 +94,14 @@ EOF # runtime FROM scratch AS runtime +ARG APP_NAME=template-rust +ARG TARGETPLATFORM ENV fprocess="/app" COPY \ --from=builder \ --chown=1000:1000 \ --link \ - "/home/rust/src/target/x86_64-unknown-linux-musl/release/template-rust" "/app" + "/home/rust/src/target/x86_64-unknown-linux-musl/release/${APP_NAME}" "/app" COPY \ --from=ghcr.io/openfaas/of-watchdog:0.9.6 \ --chown=1000:1000 \