aboutsummaryrefslogtreecommitdiff
path: root/lib/cpt.in
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cpt.in')
-rw-r--r--lib/cpt.in178
1 files changed, 178 insertions, 0 deletions
diff --git a/lib/cpt.in b/lib/cpt.in
new file mode 100644
index 0000000..a80a961
--- /dev/null
+++ b/lib/cpt.in
@@ -0,0 +1,178 @@
+#!/bin/sh -ef
+# shellcheck source=/dev/null
+
+log() {
+ # Print a message prettily.
+ #
+ # All messages are printed to stderr to allow the user to hide build
+ # output which is the only thing printed to stdout.
+ #
+ # '${3:-->}': If the 3rd argument is missing, set prefix to '->'.
+ # '${2:+colorb}': If the 2nd argument exists, set text style of '$1'.
+ printf '%b%s %b%b%s%b %s\n' \
+ "$colory" "${3:-->}" "$colre" "${2:+$colorb}" "$1" "$colre" "$2" >&2
+}
+
+version() {
+ log "Carbs Packaging Tools" @VERSION@
+ exit 0
+}
+
+trap_set() {
+ # Function to set the trap value.
+ case ${1:-cleanup} in
+ cleanup) trap pkg_clean EXIT INT ;;
+ block) trap '' INT ;;
+ unset) trap - EXIT INT ;;
+ esac
+}
+
+_readlinkf() {
+ # Public domain POSIX sh readlink function by Koichi Nakashima
+ [ "${1:-}" ] || return 1
+ max_symlinks=40
+ CDPATH='' # to avoid changing to an unexpected directory
+
+ target=$1
+ [ -e "${target%/}" ] || target=${1%"${1##*[!/]}"} # trim trailing slashes
+ [ -d "${target:-/}" ] && target="$target/"
+
+ cd -P . 2>/dev/null || return 1
+ while [ "$max_symlinks" -ge 0 ] && max_symlinks=$((max_symlinks - 1)); do
+ if [ ! "$target" = "${target%/*}" ]; then
+ case $target in
+ /*) cd -P "${target%/*}/" 2>/dev/null || break ;;
+ *) cd -P "./${target%/*}" 2>/dev/null || break ;;
+ esac
+ target=${target##*/}
+ fi
+
+ if [ ! -L "$target" ]; then
+ target="${PWD%/}${target:+/}${target}"
+ printf '%s\n' "${target:-/}"
+ return 0
+ fi
+
+ # `ls -dl` format: "%s %u %s %s %u %s %s -> %s\n",
+ # <file mode>, <number of links>, <owner name>, <group name>,
+ # <size>, <date and time>, <pathname of link>, <contents of link>
+ # https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html
+ link=$(ls -dl -- "$target" 2>/dev/null) || break
+ target=${link#*" $target -> "}
+ done
+ return 1
+}
+
+# CPT Library does "lazy loading" of its functions. Meaning that functions are
+# defined, but the libraries containing the functions aren't loaded until one of
+# those functions are called. This should theoretically decrease the time it
+# takes to execute some script that uses only minimal amount of library
+# functions. When a function listed below is called, its definition is replaced
+# by the one in the loaded library, and executed with the same arguments.
+# @AUTOLOADS@
+
+# main()
+{
+ set -ef
+
+ # Set the library directory if unset, assuming that it shares the same
+ # prefix with the tool.
+ [ "$CPT_LIBDIR" ] || CPT_LIBDIR=$(_readlinkf "${0%/*}/../lib/cpt/")
+
+ # If a parser definition exists, let's run it ourselves. This makes sure we
+ # get the variables as soon as possible.
+ command -v parser_definition >/dev/null && {
+ eval "$(getoptions parser_definition parse "$0")"
+ parse "$@"
+ eval set -- "$REST"
+ }
+
+ # Create the cache directories for CPT and set the variables which point
+ # to them. This is seperate from temporary directories created in
+ # create_cache(). That's because we need these variables set on most
+ # occasions.
+ mkdir -p "${cac_dir:=${CPT_CACHE:=${XDG_CACHE_HOME:-$HOME/.cache}/cpt}}" \
+ "${src_dir:=$cac_dir/sources}" \
+ "${log_dir:=$cac_dir/logs}" \
+ "${bin_dir:=$cac_dir/bin}"
+
+ # Set the location to the repository and package database.
+ pkg_db=var/db/cpt/installed
+
+ # The PID of the current shell process is used to isolate directories
+ # to each specific CPT instance. This allows multiple package manager
+ # instances to be run at once. Store the value in another variable so
+ # that it doesn't change beneath us.
+ pid=${CPT_PID:-$$}
+
+ # Force the C locale to speed up things like 'grep' which disable unicode
+ # etc when this is set. We don't need unicode and a speed up is always
+ # welcome.
+ export LC_ALL=C LANG=C
+
+ # Catch errors and ensure that build files and directories are cleaned
+ # up before we die. This occurs on 'Ctrl+C' as well as success and error.
+ trap_set cleanup
+
+ # Prefer GNU grep if installed as it is much much faster than busybox's
+ # implementation. Very much worth it if you value performance over
+ # POSIX correctness (grep quoted to avoid shellcheck false-positive).
+ grep=$(command -v ggrep) || grep='grep'
+
+ # Prefer libarchive tar or GNU tar if installed as they are much
+ # much faster than busybox's implementation. Very much worth it if
+ # you value performance.
+ tar=$(command -v bsdtar || command -v gtar) || tar=tar
+
+ # Figure out which 'sudo' command to use based on the user's choice or
+ # what is available on the system.
+ su=${CPT_SU:-$(command -v sls ||
+ command -v sudo ||
+ command -v doas)} || su=su
+
+ # Store the date and time of script invocation to be used as the name
+ # of the log files the package manager creates during builds.
+ time=$(date '+%Y-%m-%d-%H:%M')
+
+ # Use readelf for fixing dependencies if it is available, fallback to
+ # ldd. readelf shows only the actual dependencies and doesn't include
+ # the libraries required by the dependencies.
+ elf_prog=${CPT_ELF:="$(
+ command -v readelf ||
+ command -v llvm-readelf ||
+ command -v eu-readelf)"} || elf_prog=ldd
+
+ # Make note of the user's current ID to do root checks later on.
+ # This is used enough to warrant a place here.
+ uid=$(id -u)
+
+ # Save IFS, so we can restore it back to what it was before.
+ old_ifs=$IFS
+
+ # Make sure that the CPT_ROOT doesn't end with a '/'. This might
+ # break some operations.
+ CPT_ROOT=${CPT_ROOT%"${CPT_ROOT##*[!/]}"}
+
+ # Define an optional sys_arch variable in order to provide
+ # information to build files with architectural information.
+ sys_arch=$(uname -m 2>/dev/null) ||:
+
+ # Define this variable but don't create its directory structure from
+ # the get go. It will be created as needed by package installation.
+ sys_db=$CPT_ROOT/$pkg_db
+
+ # This allows for automatic setup of a CPT chroot and will
+ # do nothing on a normal system.
+ mkdir -p "$CPT_ROOT/" 2>/dev/null ||:
+
+ # Set a value for CPT_COMPRESS if it isn't set.
+ : "${CPT_COMPRESS:=gz}"
+
+ # Unless being piped or the user specifically doesn't want colors, set
+ # colors. This can of course be overriden if the user specifically want
+ # colors during piping.
+ if { [ "$CPT_COLOR" != 0 ] && [ -t 1 ] ;} || [ "$CPT_COLOR" = 1 ]; then
+ colory="\033[1;33m" colorb="\033[1;36m" colre="\033[m"
+ fi
+
+}