sbang: vendor sbang

`sbang` now lives at https://github.com/spack/sbang, and it has its own
test suite that's more extensive than what's in Spack. We'll leave sbang
tests to sbang from now on, and just vendor `bin/sbang` directly.
Remaining `sbang` tests have to do with patching files, not with
`sbang`'s functionality.

This update also fixes a bug with `sbang` and multiple command line
arguments that was introduced in #19529. See:
  * https://github.com/spack/sbang/pull/1
  * https://github.com/spack/sbang/pull/2

- [x] include latest `sbang` from https://github.com/spack/sbang
- [x] remove old `sbang` tests from Spack
- [x] update `COPYRIGHT` and `cmd/license.py`
This commit is contained in:
Todd Gamblin
2020-10-28 14:07:05 -07:00
parent 44bacefb27
commit aebf20ebdc
4 changed files with 24 additions and 164 deletions

110
bin/sbang
View File

@@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
# sbang project developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
@@ -12,85 +12,16 @@
# arguments in shebang lines, making it hard to use interpreters that are
# deep in the directory hierarchy or require special arguments.
#
# `sbang` can run such scripts, either as a shebang interpreter, or
# directly on the command line.
# To use, put the long shebang on the second line of your script, and
# make sbang the interpreter, like this:
#
# Usage
# -----
# Suppose you have a script, long-shebang.sh, like this:
# #!/bin/sh /path/to/sbang
# #!/long/path/to/real/interpreter with arguments
#
# 1 #!/very/long/path/to/some/interp
# 2
# 3 echo "success!"
# `sbang` will run the real interpreter with the script as its argument.
#
# Invoking this script will result in an error on some OS's. On
# Linux, you get this:
# See https://github.com/spack/sbang for more details.
#
# $ ./longshebang.sh
# -bash: ./longshebang.sh: /very/long/path/to/some/interp: bad interpreter:
# No such file or directory
#
# On macOS, the system simply assumes the interpreter is the shell and
# tries to run with it, which is not likely what you want.
#
#
# `sbang` on the command line
# ---------------------------
# You can use `sbang` in two ways. The first is to use it directly,
# from the command line, like this:
#
# $ sbang ./long-shebang.sh
# success!
#
#
# `sbang` as the interpreter
# --------------------------
# You can also use `sbang` *as* the interpreter for your script. Put
# `#!/bin/sh /path/to/sbang` on line 1, and move the original
# shebang to line 2 of the script:
#
# 1 #!/bin/sh /path/to/sbang
# 2 #!/long/path/to/real/interpreter with arguments
# 3
# 4 echo "success!"
#
# $ ./long-shebang.sh
# success!
#
# On Linux, you could shorten line 1 to `#!/path/to/sbang`, but other
# operating systems like Mac OS X require the interpreter to be a binary,
# so it's best to use `sbang` as an argument to `/bin/sh`. Obviously, for
# this to work, `sbang` needs to have a short enough path that *it* will
# run without hitting OS limits.
#
# For Lua, node, and php scripts, the second line can't start with #!, as
# # is not the comment character in these languages (though they all
# ignore #! on the *first* line of a script). So, instrument such scripts
# like this, using --, //, or <?php ... ?> instead of # on the second
# line, e.g.:
#
# 1 #!/bin/sh /path/to/sbang
# 2 --!/long/path/to/lua with arguments
# 3 print "success!"
#
# 1 #!/bin/sh /path/to/sbang
# 2 //!/long/path/to/node with arguments
# 3 print "success!"
#
# 1 #!/bin/sh /path/to/sbang
# 2 <?php #/long/path/to/php with arguments ?>
# 3 <?php echo "success!\n"; ?>
#
# How it works
# ------------
# `sbang` is a very simple posix shell script. It looks at the first two
# lines of a script argument and runs the last line starting with `#!`,
# with the script as an argument. It also forwards arguments.
#
# We disable two shellcheck errors below:
# SC2124: when saving arguments, we intentionally assign as an array
# SC2086: when splitting $shebang_line and exec args, we want to expand args
# Generic error handling
die() {
@@ -130,27 +61,16 @@ while read -r line && [ $lines -ne 2 ]; do
lines=$((lines+1))
done < "$script"
# shellcheck disable=SC2124
# this saves arguments for later and intentionally assigns as an array
args="$@"
# handle scripts with sbang parameters, e.g.:
#
# #!/<spack-long-path>/perl -w
#
# put the shebang line with all the parameters in the $@ array and get
# the first element.
# shellcheck disable=SC2086
set $shebang_line
set -- "$@"
interpreter="$1"
arg1="$2"
# error if we did not find any interpreter
if [ -z "$interpreter" ]; then
if [ -z "$shebang_line" ]; then
die "error: sbang found no interpreter in $script"
fi
# parse out the interpreter and first argument
IFS=' ' read -r interpreter arg1 rest <<EOF
$shebang_line
EOF
# Determine if the interpreter is a particular program, accounting for the
# '#!/usr/bin/env PROGRAM' convention. So:
#
@@ -176,8 +96,8 @@ fi
#
if interpreter_is perl || interpreter_is ruby; then
# shellcheck disable=SC2086
$exec $shebang_line -x "$args"
$exec $shebang_line -x "$@"
else
# shellcheck disable=SC2086
$exec $shebang_line "$args"
$exec $shebang_line "$@"
fi