Skip to content

Commit 853d34b

Browse files
committed
feat: Add support for NuShell scripts
1 parent 99369ca commit 853d34b

File tree

13 files changed

+115
-16
lines changed

13 files changed

+115
-16
lines changed

bacon.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,14 @@ command = ["cargo", "install", "--path", ".", "--debug", "--locked", "--color",
7474
need_stdout = false
7575
allow_warnings = true
7676
default_watch = false
77-
watch = ["src", "process", "recipe", "template", "utils", "Cargo.toml", "build.rs"]
77+
watch = ["src", "process", "recipe", "template", "utils", "scripts", "Cargo.toml", "build.rs"]
7878

7979
[jobs.install-all]
8080
command = ["cargo", "install", "--all-features", "--path", ".", "--debug", "--locked", "--color", "always"]
8181
need_stdout = false
8282
allow_warnings = true
8383
default_watch = false
84-
watch = ["src", "process", "recipe", "template", "utils", "Cargo.toml", "build.rs"]
84+
watch = ["src", "process", "recipe", "template", "utils", "scripts", "Cargo.toml", "build.rs"]
8585

8686
# You may define here keybindings that would be specific to
8787
# a project, for example a shortcut to launch a specific job.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/libexec/bluebuild/nu/nu
2+
3+
def main [$arg] {
4+
# Parse the JSON string into a NuShell table
5+
let parsed_json = ($arg | from json)
6+
7+
# List all top-level properties and their values
8+
print "Top-level properties and values:"
9+
$parsed_json | items {|key, value| $"Property: ($key), Value: ($value)" }
10+
}

integration-tests/test-repo/recipes/recipe.yml

+8
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ modules:
3434
- type: test-module
3535
source: local
3636

37+
- type: test-nu-modules
38+
source: local
39+
test-prop:
40+
- this
41+
- is
42+
- a
43+
- test
44+
3745
- type: containerfile
3846
containerfiles:
3947
- labels

integration-tests/test-repo/recipes/stages.yml

+9-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ stages:
2020
modules:
2121
- type: files
2222
files:
23-
- usr: /usr
23+
- source: usr
24+
destination: /usr
2425
- type: script
2526
scripts:
2627
- example.sh
@@ -33,3 +34,10 @@ modules:
3334
- labels
3435
snippets:
3536
- RUN echo "This is a snippet"
37+
- type: test-nu-modules
38+
source: local
39+
test-prop:
40+
- this
41+
- is
42+
- a
43+
- test

recipe/src/module.rs

+7
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ impl<'a> ModuleRequiredFields<'a> {
9191
}
9292
}
9393

94+
#[must_use]
95+
pub fn is_local_source(&self) -> bool {
96+
self.source
97+
.as_deref()
98+
.is_some_and(|source| source == "local")
99+
}
100+
94101
#[must_use]
95102
pub fn generate_akmods_info(&'a self, os_version: &u64) -> AkmodsInfo {
96103
#[derive(Debug, Default, Copy, Clone)]

recipe/src/recipe.rs

+5
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ pub struct Recipe<'a> {
5454
#[builder(into)]
5555
pub alt_tags: Option<Vec<String>>,
5656

57+
/// The version of nushell to use for modules.
58+
#[builder(into)]
59+
#[serde(skip_serializing_if = "Option::is_none", rename = "nushell-version")]
60+
pub nushell_version: Option<Cow<'a, str>>,
61+
5762
/// The stages extension of the recipe.
5863
///
5964
/// This hold the list of stages that can

scripts/run_module.sh

+41-3
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,54 @@ print_banner() {
1919
printf '%*.*s%s%*.*s\n' 0 "$padlen" "$padding" "$text" 0 "$padlen" "$padding"
2020
}
2121

22+
get_script_path() {
23+
local script_name="$1"
24+
local extensions=("nu" "sh" "bash")
25+
local base_script_path="/tmp/modules/${script_name}/${script_name}"
26+
local tried_scripts=()
27+
28+
# See if
29+
if [[ -f "${base_script_path}" ]]; then
30+
echo "${base_script_path}"
31+
return 0
32+
fi
33+
tried_scripts+=("${script_name}")
34+
35+
# Iterate through each extension and check if the file exists
36+
for ext in "${extensions[@]}"; do
37+
local script_path="${base_script_path}.${ext}"
38+
tried_scripts+=("${script_name}.${ext}")
39+
40+
if [[ -f "$script_path" ]]; then
41+
# Output only the script path without extra information
42+
echo "$script_path"
43+
return 0 # Exit the function when the first matching file is found
44+
fi
45+
done
46+
47+
# If no matching file was found
48+
echo "Failed to find scripts matching: ${tried_scripts[*]}" >&2
49+
return 1
50+
}
51+
2252
module="$1"
2353
params="$2"
24-
script_path="/tmp/modules/${module}/${module}.sh"
54+
script_path="$(get_script_path "$module")"
55+
nushell_version="$(echo "${params}" | jq '.["nushell-version"] // empty')"
56+
57+
export PATH="/usr/libexec/bluebuild/nu/:$PATH"
2558

2659
color_string "$(print_banner "Start '${module}' Module")" "33"
27-
chmod +x ${script_path}
60+
chmod +x "${script_path}"
2861

29-
if ${script_path} "${params}"; then
62+
if "${script_path}" "${params}"; then
3063
color_string "$(print_banner "End '${module}' Module")" "32"
64+
3165
else
3266
color_string "$(print_banner "Failed '${module}' Module")" "31"
3367
exit 1
3468
fi
69+
70+
if command -v ostree > /dev/null; then
71+
ostree container commit
72+
fi

src/commands/validate/yaml_span.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ mod test {
290290
#[case(RECIPE, "/description", (109, 29))]
291291
#[case(RECIPE, "/image-version", (199, 6))]
292292
#[case(RECIPE, "/modules/4/install", (605, 24))]
293-
#[case(RECIPE, "/modules/7/snippets", (824, 57))]
293+
#[case(RECIPE, "/modules/8/snippets", (931, 57))]
294294
#[case(RECIPE_INVALID, "/image-version", (182, 11))]
295295
#[case(RECIPE_INVALID_STAGE, "/stages/0/from", (262, 8))]
296296
#[case(RECIPE_INVALID_MODULE, "/modules/7/containerfiles", (807, 8))]
@@ -317,7 +317,7 @@ mod test {
317317
#[case("test: value", "/mapping")]
318318
#[case(RECIPE, "/test")]
319319
#[case(RECIPE, "/image-version/2")]
320-
#[case(RECIPE, "/modules/12")]
320+
#[case(RECIPE, "/modules/13")]
321321
fn test_getspan_err(#[case] file: &str, #[case] path: &str) {
322322
let file = Arc::new(file.to_owned());
323323
let location = Location::try_from(path).unwrap();

template/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub struct ContainerFileTemplate<'a> {
2929
build_scripts_image: Cow<'a, str>,
3030
repo: Cow<'a, str>,
3131
base_digest: Cow<'a, str>,
32+
nushell_version: Option<Cow<'a, str>>,
3233
}
3334

3435
#[derive(Debug, Clone, Template, Builder)]

template/templates/Containerfile.j2

+10
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ RUN --mount=type=bind,from=stage-bins,src=/bins,dst=/tmp/bins \
3535
&& cp /tmp/bins/* /usr/bin/ \
3636
&& ostree container commit
3737

38+
RUN --mount=type=bind,from={{ blue_build_utils::constants::NUSHELL_IMAGE }}:
39+
{%- if let Some(version) = nushell_version -%}
40+
{{ version }}
41+
{%- else -%}
42+
default
43+
{%- endif %},src=/nu,dst=/tmp/nu \
44+
mkdir -p /usr/libexec/bluebuild/nu \
45+
&& cp -r /tmp/nu/* /usr/libexec/bluebuild/nu/ \
46+
&& ostree container commit
47+
3848
RUN --mount=type=bind,from={{ build_scripts_image }},src=/scripts/,dst=/scripts/ \
3949
/scripts/pre_build.sh
4050

template/templates/modules/modules.j2

+7-4
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,18 @@ RUN \
1919
{%- endif %}
2020
{%- if let Some(source) = module.get_non_local_source() %}
2121
--mount=type=bind,from={{ source }},src=/modules,dst=/tmp/modules,rw \
22-
{%- else %}
22+
{%- else if module.is_local_source() %}
2323
--mount=type=bind,from=stage-modules,src=/modules,dst=/tmp/modules,rw \
24+
{%- else %}
25+
--mount=type=bind,from=ghcr.io/blue-build/modules/{{ module.module_type }}:latest,src=/modules,dst=/tmp/modules,rw \
2426
{%- endif %}
2527
{%- if module.module_type == "akmods" %}
2628
--mount=type=bind,from=stage-akmods-{{ module.generate_akmods_info(os_version).stage_name }},src=/rpms,dst=/tmp/rpms,rw \
2729
{%- endif %}
2830
--mount=type=bind,from={{ build_scripts_image }},src=/scripts/,dst=/tmp/scripts/ \
2931
--mount=type=cache,dst=/var/cache/rpm-ostree,id=rpm-ostree-cache-{{ recipe.name }}-{{ recipe.image_version }},sharing=locked \
3032
--mount=type=cache,dst=/var/cache/libdnf5,id=dnf-cache-{{ recipe.name }}-{{ recipe.image_version }},sharing=locked \
31-
/tmp/scripts/run_module.sh '{{ module.module_type }}' '{{ module|json|safe }}' \
32-
&& ostree container commit
33+
/tmp/scripts/run_module.sh '{{ module.module_type }}' '{{ module|json|safe }}'
3334
{%- endif %}
3435
{%- endif %}
3536
{%- endfor %}
@@ -57,8 +58,10 @@ RUN \
5758
{%- endif %}
5859
{%- if let Some(source) = module.get_non_local_source() %}
5960
--mount=type=bind,from={{ source }},src=/modules,dst=/tmp/modules,rw \
60-
{%- else %}
61+
{%- else if module.is_local_source() %}
6162
--mount=type=bind,from=stage-modules,src=/modules,dst=/tmp/modules,rw \
63+
{%- else %}
64+
--mount=type=bind,from=ghcr.io/blue-build/modules/{{ module.module_type }}:latest,src=/modules,dst=/tmp/modules,rw \
6265
{%- endif %}
6366
--mount=type=bind,from={{ build_scripts_image }},src=/scripts/,dst=/tmp/scripts/ \
6467
/tmp/scripts/run_module.sh '{{ module.module_type }}' '{{ module|json|safe }}'

template/templates/stages.j2

+11-4
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
{%- if self::files_dir_exists() %}
55
FROM scratch AS stage-files
66
COPY ./files /files
7-
{% else if self::config_dir_exists() %}
7+
8+
{%~ else if self::config_dir_exists() %}
89
FROM scratch AS stage-config
910
COPY ./config /config
1011
{% endif %}
1112

13+
{%~ if self::modules_exists() %}
1214
# Copy modules
1315
# The default modules are inside blue-build/modules
1416
# Custom modules overwrite defaults
1517
FROM scratch AS stage-modules
16-
COPY --from=ghcr.io/blue-build/modules:latest /modules /modules
17-
{%- if self::modules_exists() %}
1818
COPY ./modules /modules
1919
{% endif %}
2020

@@ -25,7 +25,7 @@ COPY ./modules /modules
2525
# can be added to the ostree commits.
2626
FROM scratch AS stage-bins
2727
COPY --from={{ blue_build_utils::constants::COSIGN_IMAGE }} /ko-app/cosign /bins/cosign
28-
COPY --from=ghcr.io/blue-build/cli:
28+
COPY --from={{ blue_build_utils::constants::BLUE_BULID_IMAGE_REF }}:
2929
{%- if let Some(tag) = recipe.blue_build_tag -%}
3030
{{ tag }}
3131
{%- else -%}
@@ -59,6 +59,13 @@ ARG RUST_LOG_STYLE=always
5959
{%- endif %}
6060

6161
{%- if stage.from != "scratch" %}
62+
COPY --from={{ blue_build_utils::constants::NUSHELL_IMAGE }}:
63+
{%- if let Some(version) = nushell_version -%}
64+
{{ version }}
65+
{%- else -%}
66+
default
67+
{%- endif %} /nu/* /usr/libexec/bluebuild/nu/
68+
6269
# Add compatibility for modules
6370
RUN --mount=type=bind,from=stage-bins,src=/bins/,dst=/tmp/bins/ \
6471
--mount=type=bind,from={{ build_scripts_image }},src=/scripts/,dst=/tmp/scripts/ \

utils/src/constants.rs

+2
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ pub const XDG_RUNTIME_DIR: &str = "XDG_RUNTIME_DIR";
7474

7575
// Misc
7676
pub const BUILD_SCRIPTS_IMAGE_REF: &str = "ghcr.io/blue-build/cli/build-scripts";
77+
pub const BLUE_BULID_IMAGE_REF: &str = "ghcr.io/blue-build/cli";
7778
pub const COSIGN_IMAGE: &str = "ghcr.io/sigstore/cosign/cosign:v2.4.1";
79+
pub const NUSHELL_IMAGE: &str = "ghcr.io/blue-build/nushell-image";
7880
pub const OCI_ARCHIVE: &str = "oci-archive";
7981
pub const OSTREE_IMAGE_SIGNED: &str = "ostree-image-signed";
8082
pub const OSTREE_UNVERIFIED_IMAGE: &str = "ostree-unverified-image";

0 commit comments

Comments
 (0)