-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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[@]}" |