mirror of https://github.com/bpkg/bpkg
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
5.7 KiB
Bash
268 lines
5.7 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
if ! type -f bpkg-utils &>/dev/null; then
|
|
echo "error: bpkg-utils not found, aborting"
|
|
exit 1
|
|
fi
|
|
|
|
# shellcheck source=lib/utils/utils.sh
|
|
source "$(which bpkg-utils)"
|
|
|
|
# shellcheck source=lib/realpath/realpath.sh
|
|
bpkg_exec_or_exit bpkg-realpath &&
|
|
source "$(which bpkg-realpath)"
|
|
|
|
# shellcheck source=lib/install/install.sh
|
|
bpkg_exec_or_exit bpkg-install &&
|
|
source "$(which bpkg-install)"
|
|
|
|
# shellcheck source=lib/package/package.sh
|
|
bpkg_exec_or_exit bpkg-package &&
|
|
source "$(which bpkg-package)"
|
|
|
|
bpkg_initrc
|
|
|
|
## output usage
|
|
usage () {
|
|
echo 'usage: bpkg-run [-h|--help]'
|
|
echo ' or: bpkg-run [-l|--list]'
|
|
echo ' or: bpkg-run [-s|--source] <package> [command]'
|
|
echo ' or: bpkg-run [-s|--source] <user>/<package> [command]'
|
|
}
|
|
|
|
bpkg_list_commands () {
|
|
local commands
|
|
local col_len
|
|
local description
|
|
|
|
commands="$(bpkg_package 2>/dev/null | grep '\["commands"' | sed 's/\["commands","\([^"]*\).*/\1/')"
|
|
|
|
col_len="$(wc -L <<< "${commands}")"
|
|
|
|
if [ "${col_len}" -eq 0 ]; then
|
|
bpkg_error "No commands provided in BPKG package file."
|
|
return 1
|
|
fi
|
|
|
|
for command in ${commands}; do
|
|
description="$(bpkg_package commands-description "${command}")"
|
|
|
|
if [ -z "${description}" ]; then
|
|
description="Runs the ${command} command as defined in BPKG configuration"
|
|
fi
|
|
printf " "
|
|
|
|
bpkg_exec_exist bpkg-term &&
|
|
bpkg-term color cyan
|
|
|
|
printf "%-${col_len}s " "${command}"
|
|
|
|
bpkg_exec_exist bpkg-term && {
|
|
bpkg-term reset
|
|
bpkg-term bright
|
|
}
|
|
|
|
printf "%s\n" "${description}"
|
|
|
|
bpkg_exec_exist bpkg-term &&
|
|
bpkg-term reset
|
|
done
|
|
|
|
return 0
|
|
}
|
|
|
|
bpkg_runner () {
|
|
local cmd="$1"
|
|
shift
|
|
|
|
eval "$cmd"
|
|
|
|
return $?
|
|
}
|
|
|
|
bpkg_run () {
|
|
local should_emit_source=0
|
|
local should_source=0
|
|
local should_clean=0
|
|
local needs_name=0
|
|
local dest=''
|
|
local name=''
|
|
|
|
for opt in "$@"; do
|
|
case "$opt" in
|
|
-h|--help)
|
|
usage
|
|
return 0
|
|
;;
|
|
|
|
-l|--list)
|
|
bpkg_list_commands
|
|
return $?
|
|
;;
|
|
|
|
-s|--source)
|
|
should_source=1
|
|
shift
|
|
;;
|
|
|
|
--emit-source)
|
|
should_emit_source=1
|
|
shift
|
|
;;
|
|
|
|
-c|--clean)
|
|
should_clean=1
|
|
shift
|
|
;;
|
|
|
|
-t|--target|--name)
|
|
needs_name=1
|
|
shift
|
|
;;
|
|
|
|
*)
|
|
if (( 1 == needs_name )); then
|
|
name="$opt"
|
|
shift
|
|
fi
|
|
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ -n "$1" ]; then
|
|
local cmd="$(bpkg_package commands "$1" 2>/dev/null)"
|
|
|
|
if [ -n "$cmd" ]; then
|
|
local root="$(dirname "$(bpkg_package --path)")"
|
|
cd "$root" || return 1
|
|
# shellcheck disable=SC2230
|
|
# shellcheck source=lib/env/env.sh
|
|
source "$(which bpkg-env)"
|
|
|
|
local parts=()
|
|
# shellcheck disable=SC2086
|
|
read -r -a parts <<< $cmd
|
|
local args=()
|
|
local prefix="${parts[0]}"
|
|
|
|
for (( i = 1; i < ${#parts[@]}; i++ )); do
|
|
if [[ "${parts[$i]}" =~ \*.\* ]]; then
|
|
local found=($(find . -path "${parts[$i]}"))
|
|
if (( ${#found[@]} > 0 )); then
|
|
args+=("${found[@]}")
|
|
else
|
|
# shellcheck disable=SC2086
|
|
args+=($($(which ls) ${parts[$i]} 2>/dev/null))
|
|
fi
|
|
else
|
|
args+=("${parts[$i]}")
|
|
fi
|
|
done
|
|
|
|
shift
|
|
bpkg_runner "$prefix ${args[*]}" "$@"
|
|
return $?
|
|
fi
|
|
fi
|
|
|
|
if which "$name" 2>/dev/null; then
|
|
return 0
|
|
fi
|
|
|
|
if ! pushd . >/dev/null; then
|
|
bpkg_error "Failed to 'pushd' to current working directory."
|
|
return 1
|
|
fi
|
|
|
|
if (( 0 == should_clean )); then
|
|
dest=$(bpkg_install --no-prune -g "${name:-$1}" | grep 'Cloning' | sed 's/.* to //g' | xargs echo)
|
|
else
|
|
dest=$(bpkg_install -g "${name:-$1}" | grep 'Cloning' | sed 's/.* to //g' | xargs echo)
|
|
fi
|
|
|
|
if [ -z "$dest" ]; then
|
|
if (( 1 == should_emit_source )); then
|
|
bpkg_error "The source '${name:-1}' was not found locally in a 'bpkg.json' or published as a package."
|
|
else
|
|
bpkg_error "The command '$1' was not found locally in a 'bpkg.json' or published as a package."
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
if ! cd "$dest" >/dev/null; then
|
|
bpkg_error "Failed to change directory to package: '$dest'."
|
|
return 1
|
|
fi
|
|
|
|
local pkg_name="$(bpkg_package name 2>/dev/null)"
|
|
if [ -n "$pkg_name" ]; then
|
|
name="$pkg_name"
|
|
fi
|
|
|
|
if (( 1 == should_emit_source )); then
|
|
if which "$name" 2>/dev/null; then
|
|
:
|
|
elif test -f "$1"; then
|
|
bpkg_realpath "$1"
|
|
elif [ -n "$1" ] && which "$1" 2>/dev/null; then
|
|
:
|
|
fi
|
|
else
|
|
shift
|
|
|
|
if (( 1 == should_source )); then
|
|
# shellcheck disable=SC1090
|
|
source "$(which "$name")"
|
|
else
|
|
# shellcheck disable=SC2230
|
|
# shellcheck source=lib/env/env.sh
|
|
source "$(which bpkg-env)"
|
|
|
|
cmd="$(bpkg_package commands "$1" 2>/dev/null)"
|
|
|
|
if [ -n "$cmd" ]; then
|
|
local parts=()
|
|
# shellcheck disable=SC2086
|
|
read -r -a parts <<< $cmd
|
|
local args=()
|
|
local prefix="${parts[0]}"
|
|
|
|
for (( i = 1; i < ${#parts[@]}; i++ )); do
|
|
if [[ "${parts[$i]}" =~ \*.\* ]]; then
|
|
local found=($(find . -path "${parts[$i]}"))
|
|
if (( ${#found[@]} > 0 )); then
|
|
args+=("${found[@]}")
|
|
else
|
|
# shellcheck disable=SC2086
|
|
args+=($($(which ls) ${parts[$i]} 2>/dev/null))
|
|
fi
|
|
fi
|
|
done
|
|
|
|
shift
|
|
bpkg_runner "$prefix ${args[*]}" "$@"
|
|
fi
|
|
|
|
# shellcheck disable=SC2068
|
|
"$(which "$name")" $@
|
|
fi
|
|
fi
|
|
|
|
if ! popd >/dev/null; then
|
|
bpkg_error "Failed to 'popd' to previous working directory."
|
|
return 1
|
|
fi
|
|
|
|
return $?
|
|
}
|
|
|
|
## Use as lib or perform install
|
|
if [[ ${BASH_SOURCE[0]} != "$0" ]]; then
|
|
export -f bpkg_run
|
|
else
|
|
bpkg_run "$@"
|
|
exit $?
|
|
fi
|