Skip to content

Commit

Permalink
feat: Add support for NuShell scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
gmpinder committed Jan 5, 2025
1 parent 1889bd9 commit 74bd056
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 16 deletions.
4 changes: 2 additions & 2 deletions bacon.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ command = ["cargo", "install", "--path", ".", "--debug", "--locked", "--color",
need_stdout = false
allow_warnings = true
default_watch = false
watch = ["src", "process", "recipe", "template", "utils", "Cargo.toml", "build.rs"]
watch = ["src", "process", "recipe", "template", "utils", "scripts", "Cargo.toml", "build.rs"]

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

# You may define here keybindings that would be specific to
# a project, for example a shortcut to launch a specific job.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/libexec/bluebuild/nu/nu

def main [$arg] {
# Parse the JSON string into a NuShell table
let parsed_json = ($arg | from json)

# List all top-level properties and their values
print "Top-level properties and values:"
$parsed_json | items {|key, value| $"Property: ($key), Value: ($value)" }
}
8 changes: 8 additions & 0 deletions integration-tests/test-repo/recipes/recipe.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ modules:
- type: test-module
source: local

- type: test-nu-modules
source: local
test-prop:
- this
- is
- a
- test

- type: containerfile
containerfiles:
- labels
Expand Down
10 changes: 9 additions & 1 deletion integration-tests/test-repo/recipes/stages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ stages:
modules:
- type: files
files:
- usr: /usr
- source: usr
destination: /usr
- type: script
scripts:
- example.sh
Expand All @@ -33,3 +34,10 @@ modules:
- labels
snippets:
- RUN echo "This is a snippet"
- type: test-nu-modules
source: local
test-prop:
- this
- is
- a
- test
7 changes: 7 additions & 0 deletions recipe/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ impl<'a> ModuleRequiredFields<'a> {
}
}

#[must_use]
pub fn is_local_source(&self) -> bool {
self.source
.as_deref()
.is_some_and(|source| source == "local")
}

#[must_use]
pub fn generate_akmods_info(&'a self, os_version: &u64) -> AkmodsInfo {
#[derive(Debug, Default, Copy, Clone)]
Expand Down
5 changes: 5 additions & 0 deletions recipe/src/recipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ pub struct Recipe<'a> {
#[builder(into)]
pub alt_tags: Option<Vec<String>>,

/// The version of nushell to use for modules.
#[builder(into)]
#[serde(skip_serializing_if = "Option::is_none", rename = "nushell-version")]
pub nushell_version: Option<Cow<'a, str>>,

/// The stages extension of the recipe.
///
/// This hold the list of stages that can
Expand Down
44 changes: 41 additions & 3 deletions scripts/run_module.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,54 @@ print_banner() {
printf '%*.*s%s%*.*s\n' 0 "$padlen" "$padding" "$text" 0 "$padlen" "$padding"
}

get_script_path() {
local script_name="$1"
local extensions=("nu" "sh" "bash")
local base_script_path="/tmp/modules/${script_name}/${script_name}"
local tried_scripts=()

# See if
if [[ -f "${base_script_path}" ]]; then
echo "${base_script_path}"
return 0
fi
tried_scripts+=("${script_name}")

# Iterate through each extension and check if the file exists
for ext in "${extensions[@]}"; do
local script_path="${base_script_path}.${ext}"
tried_scripts+=("${script_name}.${ext}")

if [[ -f "$script_path" ]]; then
# Output only the script path without extra information
echo "$script_path"
return 0 # Exit the function when the first matching file is found
fi
done

# If no matching file was found
echo "Failed to find scripts matching: ${tried_scripts[*]}" >&2
return 1
}

module="$1"
params="$2"
script_path="/tmp/modules/${module}/${module}.sh"
script_path="$(get_script_path "$module")"
nushell_version="$(echo "${params}" | jq '.["nushell-version"] // empty')"

export PATH="/usr/libexec/bluebuild/nu/:$PATH"

color_string "$(print_banner "Start '${module}' Module")" "33"
chmod +x ${script_path}
chmod +x "${script_path}"

if ${script_path} "${params}"; then
if "${script_path}" "${params}"; then
color_string "$(print_banner "End '${module}' Module")" "32"

else
color_string "$(print_banner "Failed '${module}' Module")" "31"
exit 1
fi

if command -v ostree > /dev/null; then
ostree container commit
fi
4 changes: 2 additions & 2 deletions src/commands/validate/yaml_span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ mod test {
#[case(RECIPE, "/description", (109, 29))]
#[case(RECIPE, "/image-version", (199, 6))]
#[case(RECIPE, "/modules/4/install", (605, 24))]
#[case(RECIPE, "/modules/7/snippets", (824, 57))]
#[case(RECIPE, "/modules/8/snippets", (931, 57))]
#[case(RECIPE_INVALID, "/image-version", (182, 11))]
#[case(RECIPE_INVALID_STAGE, "/stages/0/from", (262, 8))]
#[case(RECIPE_INVALID_MODULE, "/modules/7/containerfiles", (807, 8))]
Expand All @@ -317,7 +317,7 @@ mod test {
#[case("test: value", "/mapping")]
#[case(RECIPE, "/test")]
#[case(RECIPE, "/image-version/2")]
#[case(RECIPE, "/modules/12")]
#[case(RECIPE, "/modules/13")]
fn test_getspan_err(#[case] file: &str, #[case] path: &str) {
let file = Arc::new(file.to_owned());
let location = Location::try_from(path).unwrap();
Expand Down
1 change: 1 addition & 0 deletions template/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub struct ContainerFileTemplate<'a> {
build_scripts_image: Cow<'a, str>,
repo: Cow<'a, str>,
base_digest: Cow<'a, str>,
nushell_version: Option<Cow<'a, str>>,
}

#[derive(Debug, Clone, Template, Builder)]
Expand Down
10 changes: 10 additions & 0 deletions template/templates/Containerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ RUN --mount=type=bind,from=stage-bins,src=/bins,dst=/tmp/bins \
&& cp /tmp/bins/* /usr/bin/ \
&& ostree container commit

RUN --mount=type=bind,from={{ blue_build_utils::constants::NUSHELL_IMAGE }}:
{%- if let Some(version) = nushell_version -%}
{{ version }}
{%- else -%}
default
{%- endif %},src=/nu,dst=/tmp/nu \
mkdir -p /usr/libexec/bluebuild/nu \
&& cp -r /tmp/nu/* /usr/libexec/bluebuild/nu/ \
&& ostree container commit

RUN --mount=type=bind,from={{ build_scripts_image }},src=/scripts/,dst=/scripts/ \
/scripts/pre_build.sh

Expand Down
11 changes: 7 additions & 4 deletions template/templates/modules/modules.j2
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@ RUN \
{%- endif %}
{%- if let Some(source) = module.get_non_local_source() %}
--mount=type=bind,from={{ source }},src=/modules,dst=/tmp/modules,rw \
{%- else %}
{%- else if module.is_local_source() %}
--mount=type=bind,from=stage-modules,src=/modules,dst=/tmp/modules,rw \
{%- else %}
--mount=type=bind,from=ghcr.io/blue-build/modules/{{ module.module_type }}:latest,src=/modules,dst=/tmp/modules,rw \
{%- endif %}
{%- if module.module_type == "akmods" %}
--mount=type=bind,from=stage-akmods-{{ module.generate_akmods_info(os_version).stage_name }},src=/rpms,dst=/tmp/rpms,rw \
{%- endif %}
--mount=type=bind,from={{ build_scripts_image }},src=/scripts/,dst=/tmp/scripts/ \
--mount=type=cache,dst=/var/cache/rpm-ostree,id=rpm-ostree-cache-{{ recipe.name }}-{{ recipe.image_version }},sharing=locked \
--mount=type=cache,dst=/var/cache/libdnf5,id=dnf-cache-{{ recipe.name }}-{{ recipe.image_version }},sharing=locked \
/tmp/scripts/run_module.sh '{{ module.module_type }}' '{{ module|json|safe }}' \
&& ostree container commit
/tmp/scripts/run_module.sh '{{ module.module_type }}' '{{ module|json|safe }}'
{%- endif %}
{%- endif %}
{%- endfor %}
Expand Down Expand Up @@ -57,8 +58,10 @@ RUN \
{%- endif %}
{%- if let Some(source) = module.get_non_local_source() %}
--mount=type=bind,from={{ source }},src=/modules,dst=/tmp/modules,rw \
{%- else %}
{%- else if module.is_local_source() %}
--mount=type=bind,from=stage-modules,src=/modules,dst=/tmp/modules,rw \
{%- else %}
--mount=type=bind,from=ghcr.io/blue-build/modules/{{ module.module_type }}:latest,src=/modules,dst=/tmp/modules,rw \
{%- endif %}
--mount=type=bind,from={{ build_scripts_image }},src=/scripts/,dst=/tmp/scripts/ \
/tmp/scripts/run_module.sh '{{ module.module_type }}' '{{ module|json|safe }}'
Expand Down
15 changes: 11 additions & 4 deletions template/templates/stages.j2
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
{%- if self::files_dir_exists() %}
FROM scratch AS stage-files
COPY ./files /files
{% else if self::config_dir_exists() %}

{%~ else if self::config_dir_exists() %}
FROM scratch AS stage-config
COPY ./config /config
{% endif %}

{%~ if self::modules_exists() %}
# Copy modules
# The default modules are inside blue-build/modules
# Custom modules overwrite defaults
FROM scratch AS stage-modules
COPY --from=ghcr.io/blue-build/modules:latest /modules /modules
{%- if self::modules_exists() %}
COPY ./modules /modules
{% endif %}

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

{%- if stage.from != "scratch" %}
COPY --from={{ blue_build_utils::constants::NUSHELL_IMAGE }}:
{%- if let Some(version) = nushell_version -%}
{{ version }}
{%- else -%}
default
{%- endif %} /nu/* /usr/libexec/bluebuild/nu/

# Add compatibility for modules
RUN --mount=type=bind,from=stage-bins,src=/bins/,dst=/tmp/bins/ \
--mount=type=bind,from={{ build_scripts_image }},src=/scripts/,dst=/tmp/scripts/ \
Expand Down
2 changes: 2 additions & 0 deletions utils/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ pub const XDG_RUNTIME_DIR: &str = "XDG_RUNTIME_DIR";

// Misc
pub const BUILD_SCRIPTS_IMAGE_REF: &str = "ghcr.io/blue-build/cli/build-scripts";
pub const BLUE_BULID_IMAGE_REF: &str = "ghcr.io/blue-build/cli";
pub const COSIGN_IMAGE: &str = "ghcr.io/sigstore/cosign/cosign:v2.4.1";
pub const NUSHELL_IMAGE: &str = "ghcr.io/blue-build/nushell-image";
pub const OCI_ARCHIVE: &str = "oci-archive";
pub const OSTREE_IMAGE_SIGNED: &str = "ostree-image-signed";
pub const OSTREE_UNVERIFIED_IMAGE: &str = "ostree-unverified-image";
Expand Down

0 comments on commit 74bd056

Please sign in to comment.