Skip to content

Commit

Permalink
New option --runner-script.
Browse files Browse the repository at this point in the history
  • Loading branch information
danfuzz committed Dec 5, 2023
1 parent 0bb7ec9 commit 764ef51
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 0 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ versioning principles. Unstable releases do not.

### [Unreleased]

Breaking changes:
* None.

Other notable changes:
* `bashy-node`:
* New option `--runner-script` for `node-project build-main-module`, using
code extracted from sibling project `lactoserv`.

### v2.8 -- 2023-11-30

This is a stable-ish release. No further breaking changes are currently
Expand Down
16 changes: 16 additions & 0 deletions scripts/lib/bashy-node/node-project/build-main-module
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ define-usage --with-help $'
--out=<dir>
Directory where built output goes. Defaults to `out` directly under the
main product directory.
--runner-script=<name>
Create a script to run the system in the `out` directory, with the given
name.
--unsafely-run-npm-install-scripts
If specified, runs any install-time scripts defined by modules. This is
reasonably considered an unsafe practice (it is a vector for
Expand All @@ -51,6 +54,9 @@ opt-multi --required --var=modulesDirs --filter='/./' modules-dirs
# Built output directory.
opt-value --var=outDir out

# Name of runner script to add to the output, if any.
opt-value --var=runnerScript runner-script

# Run npm install-time scripts?
opt-toggle --var=runNpmInstallScripts unsafely-run-npm-install-scripts

Expand Down Expand Up @@ -380,5 +386,15 @@ if (( !platformSpecific )); then
|| exit "$?"
fi

if [[ ${runnerScript} != '' ]]; then
progress-msg 'Copying runner script...'
binDir="${outProjectDir}/bin"
true \
&& mkdir -p "${binDir}" \
&& cp "$(this-cmd-dir)/runner-script.txt" "${binDir}/${runnerScript}" \
&& chmod 755 "${binDir}/${runnerScript}" \
|| exit "$?"
fi

progress-msg
progress-msg "Built Node project ${projectName}."
150 changes: 150 additions & 0 deletions scripts/lib/bashy-node/node-project/runner-script.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#!/bin/bash
#
# Copyright 2022-2023 the Bashy-lib Authors (Dan Bornstein et alia).
# SPDX-License-Identifier: Apache-2.0

# Figure out the symlink-resolved program name and directory.
cmdName="$(readlink -f "$0")" || exit "$?"
cmdDir="${cmdName%/*}"
cmdName="${cmdName##*/}"
baseDir="${cmdDir%/*}"


#
# Argument processing
#

# This _just_ extracts `--print-node-command` and `--node-opts ... --`, leaving
# everything else intact, because the bulk of the options are processed by the
# main program.

# Options to pass to `node`.
nodeOpts=()

# Arguments to pass to the main program.
mainArgs=()

# Print the `node ...` command to stderr before actually running it?
printNodeCommand=0

# Collect node options?
wantNodeOpts=0

while (( $# != 0 )); do
if (( wantNodeOpts )); then
if [[ $1 == '--' ]]; then
wantNodeOpts=0
else
nodeOpts+=("$1")
fi
shift
continue
fi

case "$1" in
--node-opts)
wantNodeOpts=1
;;
--print-node-command)
printNodeCommand=1
;;
--*|-?*)
# Option to pass through.
mainArgs+=("$1")
;;
*)
# Non-option argument (including `--` to explicitly end options).
break
;;
esac

shift
done

# Append the rest of the arguments to `mainArgs`.
mainArgs+=("$@")


#
# Helper functions
#

# Prints an error message to `stderr`.
function error-msg {
echo 1>&2 "$@"
}

# Checks one dependency.
function check-dependency {
local name="$1"
local versionCmd="$2"
local match="$3"
local versionMsg="$4"

# Extract just the binary (executable / command / tool) name.
local cmdName=''
if [[ ${versionCmd} =~ ^([^ ]+) ]]; then
cmdName="${BASH_REMATCH[1]}"
else
# Note: This indicates a bug in this script, not a problem with the
# environment.
error-msg "Could not determine binary name for ${name}."
return 1
fi

# Verify that the command exists at all.
if ! which "${cmdName}" >/dev/null 2>&1; then
error-msg "Missing required binary for ${name}: ${cmdName}"
return 1
fi

local version
version=$(eval "${versionCmd}") \
|| {
# Note: This indicates a bug in this script, not a problem with the
# environment.
error-msg "Trouble running version command for ${name}."
return 1
}

if [[ !(${version} =~ ${match}) ]]; then
error-msg "Unsupported version of ${name}: ${version}"
error-msg " required: ${versionMsg}"
return 1
fi
}


#
# Main script
#

check-dependency \
'Node' \
'node --version | sed -e "s/^v//g"' \
'^(18|19|20)\.' \
'18..20' \
|| exit "$?"

# Notes:
# * `--no-warnings` suppresses Node's built-in warning printer, which we do
# because the program is expected to include its own warning handler.
# * `--experimental-vm-modules` enables the `node:vm/Module` class and related
# functionality.
fullCommand=(
node "${nodeOpts[@]}" --no-warnings --experimental-vm-modules
"${baseDir}/lib/code/index.js"
--outer-command-name="${cmdName}"
"${mainArgs[@]}"
)

if (( printNodeCommand )); then
echo 1>&2 'Running system via command:'
printf 1>&2 ' %q\n' "${fullCommand[@]}"
fi

# Note: `exec` minimizes the number of processes left lying around. That is, no
# need for this script to take up space once the system is running. In addition
# to just being tidy, it helps when this program is run via / within a service
# manager such as `systemd`.
exec "${fullCommand[@]}"

0 comments on commit 764ef51

Please sign in to comment.