Skip to content
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 102 additions & 53 deletions cli/builbo
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,18 @@

function detect_container_command() {


if [ -z "${CONTAINER_CMD}" ]; then
CONTAINER_CMD="$(podman version > /dev/null 2>&1 && echo podman)"
fi

if [ -z "${CONTAINER_CMD}" ]; then
CONTAINER_CMD="$(docker version > /dev/null 2>&1 && echo docker)"

fi
}



# default values for ccommand line options:
# default values for command line options:
LANG=c
REGISTRY=quay.io
CONTAINER_CMD=""
Expand All @@ -25,7 +23,7 @@ fi
DEPS=""
DEFAULT_ACTION="help"
ACTION="$DEFAULT_ACTION"
# action that was explicxitly set from the command line:
# action that was explicitly set from the command line:
EXPLICIT_ACTION=""
# shell for interactive use:
I_SHELL="bash"
Expand All @@ -38,6 +36,14 @@ if [ -z "$CONTAINER_CMD" ]; then
exit 1
fi

# Detect whether GNU getopt is available.
# GNU getopt returns exit code 4 when called with --test; BSD getopt does not.
HAS_GNU_GETOPT=false
getopt --test > /dev/null 2>&1
if [ $? -eq 4 ]; then
HAS_GNU_GETOPT=true
fi

function usage() {
>&2 cat <<EOF

Expand All @@ -50,25 +56,27 @@ These are the supported options:
[ -r | --registry (quay.io|... ] - container registry (default: $REGISTRY)
[ -c | --container-cmd (podman|docker) ] - default: $CONTAINER_CMD (auto-detected)
[ -o | --os (fedora|debian|ubuntu|rocky|suse) ] - linux distro (default: $OS)
[ -n | --registry-namespace (...) ] - default: $NAMESPACE
[ -s | --build-script (command|path) ] - command or local script (in the CWD) for building the project.
[ -n | --registry-namespace (...) ] - default: $NAMESPACE
[ -s | --build-script (command|path) ] - command or local script (in the CWD) for building the project.
[ -d | --deps (pkg,pkg,pkg,...) ] - additional packages to install (comma-separated)
-i | --shell (bash) ] - sinteractive shell (default: $I_SHELL)
[ -h | --help ] - action help: print this usage information
[-t | --test ] - action test: print some diagnostic info for testing this program
[ -t | --test ] - action test: print some diagnostic info for testing this program
[ -b | --build ] - action build: perform a build in the CWD
[ -e | --enter] - action enter: enter container in interactive mode (shell)
[ -e | --enter ] - action enter: enter container in interactive mode (shell)

Note: Long options (e.g. --build, --lang) require GNU getopt.
If GNU getopt is not available (e.g. on macOS without Homebrew's gnu-getopt),
only short options are supported and a warning will be shown for long options.
Install GNU getopt with: brew install gnu-getopt (macOS) or via your Linux package manager.

The Options -l, -r, -o, and -n in combination determine the buildbox image (by tag) to be used.

The Options -l, -r, -o, and -n in combination determine the buildbox image (by tag) to be used.

The options -h, -t, -e, and -b are the available actions (help, test, enter, and build) to be performed.

Exactly one of the actions must be selected.
Exactly one of the actions must be selected.

The build action requires the additional option -s.
The enter action makes use of the --shell option.
The enter action is triggered by the -e flag.

EOF

Expand All @@ -78,8 +86,6 @@ function set_action() {

local action="$1"



if [ -n "$EXPLICIT_ACTION" ]; then
echo "Error: multiple actions specified on cmdline but only one is allowed."
usage
Expand All @@ -91,51 +97,94 @@ if [ -n "$EXPLICIT_ACTION" ]; then
}




# parsing command line arguments:
optstring="l:r:c:o:n:hbtes:d:"
optstring_long="lang:,registry:,container-cmd:,help,test,build,enter,build-script:,deps:"
optstring_long="lang:,registry:,container-cmd:,os:,registry-namespace:,help,test,build,enter,build-script:,deps:"

if $HAS_GNU_GETOPT; then
# GNU getopt is available: support both short and long options.
parsed_args=$(getopt -n "builbo" -o "$optstring" -l "$optstring_long" -- "$@")
args_valid=$?

parsed_args=$(getopt -n "builbo" -o "$optstring" -l "$optstring_long" -- "$@")
args_valid=$?
if [ "$args_valid" != "0" ]; then
echo "error: invalid args."
usage
exit 1
fi

if [ "$args_valid" != "0" ]; then
echo "error:invalid args."
usage
exit 1
# processing parsed args
eval set -- "$parsed_args"
while :
do
case "$1" in
-l | --lang) LANG="$2" ; shift 2 ;;
-r | --registry) REGISTRY="$2" ; shift 2 ;;
-c | --container-cmd) CONTAINER_CMD="$2"; shift 2 ;;
-o | --os) OS="$2" ; shift 2 ;;
-n | --registry-namespace) NAMESPACE="$2" ; shift 2 ;;
-s | --build-script) BUILD_CMD="$2" ; shift 2 ;;
-d | --deps) DEPS="$2" ; shift 2 ;;
-h | --help) set_action "help" ; shift ;;
-b | --build) set_action "build"; shift ;;
-t | --test) set_action "test" ; shift ;;
-e | --enter) set_action "enter"; shift ;;
# -- means end of args; stop processing.
--) shift ; break ;;
*) echo "Unexpected option $1 - this should not happen."
usage
exit 1
;;
esac
done

else
# GNU getopt is not available; fall back to Bash built-in getopts (short options only).
echo "warning: GNU getopt is not available on this system. Only short options are supported." >&2
echo " Install GNU getopt for long option support (e.g. brew install gnu-getopt on macOS)." >&2

# Error on any long options passed by the user.
# Track value-consuming short options so their values are not mistaken for long options.
skip_next=false
for arg in "$@"; do
if $skip_next; then
skip_next=false
continue
fi
if [[ "$arg" == --?* ]]; then
echo "error: long option '$arg' is not supported without GNU getopt." >&2
echo " Please use the equivalent short option, or install GNU getopt." >&2
usage
exit 1
fi
# Short options that consume the next argument (from optstring: l:r:c:o:n:s:d:)
if [[ "$arg" =~ ^-[lrconsd]$ ]]; then
skip_next=true
fi
done

while getopts "$optstring" opt; do
case "$opt" in
l) LANG="$OPTARG" ;;
r) REGISTRY="$OPTARG" ;;
c) CONTAINER_CMD="$OPTARG";;
o) OS="$OPTARG" ;;
n) NAMESPACE="$OPTARG" ;;
s) BUILD_CMD="$OPTARG" ;;
d) DEPS="$OPTARG" ;;
h) set_action "help" ;;
b) set_action "build" ;;
t) set_action "test" ;;
e) set_action "enter" ;;
*)
echo "error: invalid args."
usage
exit 1
;;
esac
done
shift $((OPTIND - 1))
fi

# processing parsed args

eval set -- "$parsed_args"
while :
do
case "$1" in
-l | --lang) LANG="$2" ; shift 2 ;;
-r | --registry) REGISTRY="$2" ; shift 2 ;;
-c | --container-cmd) CONTAINER_CMD="$2"; shift 2 ;;
-o | --os) OS="$2"; shift 2 ;;
-n | --registry-namespace) NAMESPACE="$2" ; shift 2 ;;
-s | --build-script) BUILD_CMD="$2" ; shift 2 ;;
-d | --deps) DEPS="$2"; shift 2 ;;
-h | --help) set_action "help" ; shift ;;
-b| --build) set_action "build" ; shift ;;
-t| --test) set_action "test" ; shift ;;
-e|--enter) set_action "enter" ; shift ;;


# -- means end of args. ignore and stop processing.
--) shift ; break ;;
*) echo "Unexpected option $1. - this should not happen."
# this should have been caught above with args_valid
usage
exit 1
;;
esac
done

# done processing args


Expand Down
Loading