You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
353 lines
9.9 KiB
353 lines
9.9 KiB
#!/bin/sh
|
|
set -eu
|
|
|
|
# Astronaut configuration
|
|
|
|
# Build/install-time directories
|
|
dir_build='/tmp/astronaut/build' # Temporary directory to build packages
|
|
dir_source='/tmp/astronaut/source' # Directory where the package sources will be placed
|
|
dir_install='/tmp/astronaut/install' # Directory where the package will be installed
|
|
# The source directory will have subdirs for each different $name,
|
|
# specified inside the satellite file.
|
|
|
|
# Runtime directories
|
|
dir_prefix='usr' # Prefix directory
|
|
|
|
# Finer-grained control of runtime dirs
|
|
# This can't be set from the command line, but might need to be adapted for your distro.
|
|
|
|
dir_bin='bin'
|
|
dir_sbin='sbin'
|
|
dir_libexec='libexec'
|
|
dir_sysconf='etc'
|
|
dir_lib='lib'
|
|
dir_include='include'
|
|
dir_data='share'
|
|
dir_info='share/info'
|
|
dir_locale='share/locale'
|
|
dir_man='share/man'
|
|
dir_doc='share/doc'
|
|
|
|
# Default commands
|
|
cmd_download='curl -# -L -o {dst} {src}' # Command to execute to download files
|
|
cmd_extract='tar -x -C {dst} -f {src}' # Command to execute to extract files
|
|
|
|
# If we can't find the satellite file, we'll look in this directory for it.
|
|
dir_satellites=
|
|
|
|
# Options are comma-separated and parsed from front to back.
|
|
# This means that in '!opt,someotheropt,opt', opt is disabled.
|
|
|
|
options= # The least-priority global options
|
|
package_options() { :; } # Per-package options function.
|
|
# Example for package_options:
|
|
# package_options() {
|
|
# case "$1" in
|
|
# package1) echo 'opt1,opt2,opt3' ;;
|
|
# package2) echo 'someotheropts' ;;
|
|
# esac
|
|
# }
|
|
|
|
# Load any user configuration
|
|
[ -f /etc/astronaut.conf ] && . /etc/astronaut.conf
|
|
[ -f "$HOME/.astronaut.conf" ] && . "$HOME/.astronaut.conf"
|
|
|
|
# Options not in the configuration
|
|
download_only=false
|
|
_astronaut_vcs_only=false
|
|
_astronaut_nuke_install=false
|
|
_astronaut_options_user= # Options specified in the command line get the highest priority
|
|
|
|
# Should be specified in the satellite
|
|
version=
|
|
update_url=
|
|
vcs_compile=false
|
|
|
|
# Check if running from a wrapper
|
|
if [ "$(basename "$0")" != "astronaut" ]; then
|
|
type _astronaut_wrapper_pre > /dev/null || _astronaut_wrapper_pre() { :; }
|
|
type _astronaut_wrapper_post > /dev/null || _astronaut_wrapper_post() { :; }
|
|
else
|
|
_astronaut_wrapper_pre() { :; }
|
|
_astronaut_wrapper_post() { :; }
|
|
fi
|
|
|
|
# Some printing functions
|
|
_show_help() {
|
|
echo "This astronaut will help you build some satellites.
|
|
Just describe what he's got to do in a satellite file.
|
|
Usage: $0 [-bsip <dir>] [-hIdv] [-o <options>] <satellite>...
|
|
|
|
-h/? Show this message
|
|
-b Set build directory [WARNING: Will be deleted before build]
|
|
-s Set source directory
|
|
-i Set install directory
|
|
-p Set prefix directory
|
|
-I Nuke install directory before build [WARNING: You will not be prompted]
|
|
-d Only download package files
|
|
-v Only build vcs package if any updates have been made to it
|
|
-o Set package options (comma-separated)
|
|
|
|
Tips:$([ "$(basename "$0")" = "astronaut" ] && printf "\n- Use \`head -n 49 $0 | tail -n +4 > astronaut.conf.example\` to generate a default configuration file.")
|
|
- Keep in mind that when specifying options on the command line in a string, the first always takes priority.
|
|
For example, in \"opt,someotheropt,!opt\", opt is enabled, due to it being the first occurrence.
|
|
- If you have set \$dir_satellites in the config, you can omit the .sat suffix.
|
|
"
|
|
}
|
|
|
|
_astronaut_msg() {
|
|
echo "=> $@"
|
|
}
|
|
|
|
_astronaut_error() {
|
|
echo "===> Houston, we've got a problem: $@" 1>&2
|
|
exit 1
|
|
}
|
|
|
|
# Gather info
|
|
while getopts "h?s:b:i:p:Idvo:" opt; do
|
|
case "$opt" in
|
|
h|\?)
|
|
_show_help
|
|
exit 0
|
|
;;
|
|
|
|
s) dir_source="$OPTARG" ;;
|
|
b) dir_build="$OPTARG" ;;
|
|
i) dir_install="$OPTARG" ;;
|
|
p) dir_prefix="$OPTARG" ;;
|
|
|
|
I) _astronaut_nuke_install=true ;;
|
|
d) download_only=true ;;
|
|
v) _astronaut_vcs_only=true ;;
|
|
o) _astronaut_options_user="$OPTARG,$_astronaut_options_user" ;;
|
|
esac
|
|
done
|
|
|
|
shift $(expr $OPTIND - 1)
|
|
[ "$#" -ge 1 ] && [ "$1" = "--" ] && shift
|
|
|
|
if [ "$#" -lt 1 ]; then
|
|
_show_help
|
|
exit 1
|
|
fi
|
|
|
|
# Tools for the astronaut
|
|
_mksum() {
|
|
echo "$(md5sum "$@" 2> /dev/null | cut -d' ' -f1)"
|
|
}
|
|
|
|
safe_sed() {
|
|
echo "$1" | sed 's/[[&\.*^$/]/\\&/g'
|
|
}
|
|
|
|
download() {
|
|
mkdir -p "$dir_source/$name"
|
|
|
|
[ "$#" -ge 3 ] && local filename="$3" || local filename="$(basename $(echo "$1" | cut -d? -f1))"
|
|
local path="$dir_source/$name/$filename"
|
|
|
|
if [ ! -e "$path" ] || [ "$#" -ge 2 -a "$(_mksum "$path")" != "$2" ]; then
|
|
_astronaut_msg "Downloading $filename"
|
|
|
|
[ "$#" -ge 4 ] && local cmd="$4" || local cmd="$cmd_download"
|
|
eval $(echo "$cmd" | sed -e "s/{dst}/'$(safe_sed "$path")'/g" -e "s/{src}/'$(safe_sed "$1")'/g")
|
|
|
|
local checksum="$(_mksum "$path")"
|
|
if [ "$#" -ge 2 -a "$checksum" != "$2" ]; then
|
|
_astronaut_msg "Checksum: $checksum"
|
|
_astronaut_error 'Checksum failed'
|
|
fi
|
|
elif [ ! -f "$path" ]; then
|
|
_astronaut_error "'$path' exists but isn't a file?"
|
|
fi
|
|
}
|
|
|
|
extract() {
|
|
_astronaut_msg "Extracting $1"
|
|
[ "$#" -ge 2 ] && local dest="$2" || local dest='.'
|
|
[ "$#" -ge 3 ] && local cmd="$3" || local cmd="$cmd_extract"
|
|
eval $(echo "$cmd" | sed -e "s/{src}/'$(safe_sed "$dir_source/$name/$1")'/g" -e "s/{dst}/'$(safe_sed "$dest")'/g")
|
|
}
|
|
|
|
getfile() {
|
|
cp -a "$dir_source/$name/$1" "./$1"
|
|
}
|
|
|
|
extrafile() {
|
|
local dir="$(dirname "$_astronaut_satellite")"
|
|
[ -d "$dir/extrafiles" ] && local dir="$dir/extrafiles/$name" || true
|
|
|
|
cp -a "$dir/$1" "./$1"
|
|
}
|
|
|
|
dlextract() {
|
|
download "$1" "$2"
|
|
extract "$(basename "$(echo "$1" | cut -d? -f1)")"
|
|
}
|
|
|
|
dlfile() {
|
|
download "$1" "$2"
|
|
getfile "$(basename "$(echo "$1" | cut -d? -f1)")"
|
|
}
|
|
|
|
option() {
|
|
local check=$1
|
|
shift
|
|
|
|
local negate=false
|
|
local variable=false
|
|
case "$check" in
|
|
=*)
|
|
local variable=true
|
|
local check="$(echo "$check" | cut -c 2-)"
|
|
;;
|
|
!*)
|
|
local negate=true
|
|
local check="$(echo "$check" | cut -c 2-)"
|
|
;;
|
|
esac
|
|
|
|
local enabled=false
|
|
local found=false
|
|
local opt
|
|
local IFS=','
|
|
for option in $options; do
|
|
local option_negate=false
|
|
local option_variable=false
|
|
case "$option" in
|
|
*=*)
|
|
local value="$(echo "$option" | cut -d '=' -f 2)"
|
|
local option="$(echo "$option" | cut -d '=' -f 1)"
|
|
local option_variable=true
|
|
;;
|
|
!*)
|
|
local option="$(echo "$option" | cut -c 2-)"
|
|
local option_negate=true
|
|
;;
|
|
esac
|
|
|
|
if [ "$option" = "$check" ]; then
|
|
if [ "$variable" = true -a "$option_variable" = false ]; then
|
|
_astronaut_msg 'Tip: Define the option as option=value.' 1>&2
|
|
_astronaut_error "Satellite requested a variable option, but there was no value for option: '$option'."
|
|
fi
|
|
|
|
[ "$option_negate" = true ] && local enabled=false || local enabled=true
|
|
local found=true
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ "$found" = false ]; then
|
|
_astronaut_msg 'Tip: Make sure to define every option you use in the satellite.' 1>&2
|
|
_astronaut_error "Option '$check' was nowhere to be found."
|
|
fi
|
|
|
|
if [ "$variable" = true ]; then
|
|
echo "$value"
|
|
return
|
|
fi
|
|
|
|
if [ "$negate" = true ]; then
|
|
# Shitty way to do a simple "NOT" operation.
|
|
[ "$enabled" = true ] && local enabled=false || local enabled=true
|
|
fi
|
|
|
|
if [ "$#" -ge 1 ]; then
|
|
if [ "$enabled" = true ]; then
|
|
"$@"
|
|
fi
|
|
else
|
|
[ "$enabled" = true ]
|
|
fi
|
|
}
|
|
|
|
define_option() {
|
|
local option="$(echo "$1" | cut -d ':' -f 1)"
|
|
options="$options,$option"
|
|
}
|
|
|
|
import() {
|
|
. "$(dirname "$_astronaut_satellite")/functions/$1.sh"
|
|
}
|
|
|
|
# Set some functions in accordance to the different options.
|
|
_() { :; }
|
|
if [ "$_astronaut_vcs_only" = true ]; then
|
|
_() {
|
|
if [ "$vcs_compile" = false ]; then
|
|
exit
|
|
fi
|
|
}
|
|
fi
|
|
if [ "$download_only" = true ]; then
|
|
# Disable some functions
|
|
extract() { :; }
|
|
getfile() { :; }
|
|
extrafile() { :; }
|
|
|
|
# Exit at the end of the header
|
|
_() { exit; }
|
|
fi
|
|
|
|
# Create the directories
|
|
mkdir -p "$dir_source"
|
|
dir_source="$(realpath "$dir_source")"
|
|
|
|
if [ "$download_only" = false ]; then
|
|
mkdir -p "$dir_build"
|
|
mkdir -p "$dir_install"
|
|
dir_build="$(realpath "$dir_build")"
|
|
dir_install="$(realpath "$dir_install")"
|
|
fi
|
|
|
|
for _astronaut_satellite in "$@"; do
|
|
name_sat="$(basename "$_astronaut_satellite" .sat)"
|
|
name="$name_sat"
|
|
|
|
# Try to find the satellite file if it can't be found.
|
|
if [ ! -f "$_astronaut_satellite" ]; then
|
|
if [ -d "$dir_satellites" ]; then
|
|
file="$(find "$dir_satellites" -type f \( -name "$name_sat.sat" -o -name "$name_sat" \) -print -quit)"
|
|
if [ -f "$file" ]; then
|
|
_astronaut_satellite="$file"
|
|
name_sat="$(basename "$_astronaut_satellite" .sat)"
|
|
fi
|
|
fi
|
|
|
|
# If it still can't be found, exit.
|
|
if [ ! -f "$_astronaut_satellite" ]; then
|
|
_astronaut_error "Can't find satellite: $_astronaut_satellite"
|
|
fi
|
|
fi
|
|
|
|
_astronaut_satellite="$(realpath "$_astronaut_satellite")"
|
|
|
|
(
|
|
options="$_astronaut_options_user$(package_options "$name_sat"),$options"
|
|
|
|
if [ "$download_only" = true ]; then
|
|
# Just download it
|
|
. "$_astronaut_satellite"
|
|
else
|
|
_astronaut_wrapper_pre
|
|
|
|
# Remove install dir if appropriate
|
|
if [ "$_astronaut_nuke_install" = true -a ! -z "$dir_install" ]; then
|
|
rm -rf "$dir_install"
|
|
mkdir -p "$dir_install"
|
|
fi
|
|
|
|
rm -rf "$dir_build"
|
|
mkdir -p "$dir_build"
|
|
|
|
# Create the satellite
|
|
options="$_astronaut_options_user$(package_options "$name_sat"),$options"
|
|
cd "$dir_build"
|
|
. "$_astronaut_satellite"
|
|
|
|
_astronaut_wrapper_post
|
|
fi
|
|
)
|
|
done
|
|
|