diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 4 | ||||
-rwxr-xr-x | src/cpt | 6 | ||||
-rwxr-xr-x | src/cpt-build | 2 | ||||
-rwxr-xr-x | src/cpt-checksum | 3 | ||||
-rwxr-xr-x | src/cpt-install | 2 | ||||
-rw-r--r-- | src/cpt-lib.in (renamed from src/cpt-lib) | 189 | ||||
-rwxr-xr-x | src/cpt-list | 12 | ||||
-rwxr-xr-x | src/cpt-remove | 2 | ||||
-rw-r--r-- | src/test.do | 7 |
9 files changed, 189 insertions, 38 deletions
diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index aae4e59..0000000 --- a/src/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -test: - shellcheck -x -f gcc ./cpt* ../contrib/* - -.PHONY: test @@ -16,11 +16,9 @@ case "$arg" in done for path; do - # These are the files to be ignored. - contains "lib readlink stat" "$path" && continue - printf "%b->%b %-${max}s " "$colorb" "$colre" "${path#*/cpt-}" - sed -n 's/^# *//;2p' "$(command -v "cpt-$path")" + awk 'NR==2{if(/^# /){sub(/^# */,"");print}else print "";exit}' \ + "$(command -v "cpt-$path")" done | sort -uk1 >&2 exit ;; diff --git a/src/cpt-build b/src/cpt-build index d67f1a6..cb93949 100755 --- a/src/cpt-build +++ b/src/cpt-build @@ -10,7 +10,7 @@ parser_definition() { if [ -f ./cpt-lib ]; then . ./cpt-lib; else . cpt-lib; fi -[ "$1" ] || set -- "${PWD##*/}"; export CPT_PATH=${PWD%/*}:$CPT_PATH +[ "$1" ] || { set -- "${PWD##*/}"; export CPT_PATH=${PWD%/*}:$CPT_PATH ;} create_cache diff --git a/src/cpt-checksum b/src/cpt-checksum index 0a83ae0..cd1fa4e 100755 --- a/src/cpt-checksum +++ b/src/cpt-checksum @@ -22,8 +22,7 @@ for pkg; do tee "$repo_dir/checksums" else log "$pkg" "Need permissions to generate checksums" - - user=$(cpt-stat "$repo_dir") as_root tee "$repo_dir/checksums" + user=$(_stat "$repo_dir") as_root tee "$repo_dir/checksums" fi } diff --git a/src/cpt-install b/src/cpt-install index b046e02..aab70ea 100755 --- a/src/cpt-install +++ b/src/cpt-install @@ -10,7 +10,7 @@ parser_definition() { if [ -f ./cpt-lib ]; then . ./cpt-lib; else . cpt-lib; fi -[ "$1" ] || set -- "${PWD##*/}"; export CPT_PATH=${PWD%/*}:$CPT_PATH +[ "$1" ] || { set -- "${PWD##*/}"; export CPT_PATH=${PWD%/*}:$CPT_PATH ;} [ -w "$CPT_ROOT/" ] || [ "$uid" = 0 ] || { as_root "$0" "$@" diff --git a/src/cpt-lib b/src/cpt-lib.in index 6afd030..7728ae8 100644 --- a/src/cpt-lib +++ b/src/cpt-lib.in @@ -1,4 +1,5 @@ #!/bin/sh -ef +# @DOCSTRING@ # shellcheck source=/dev/null # # This is the Carbs Packaging Toolchain written for Carbs Linux. @@ -8,7 +9,7 @@ # Currently maintained by Cem Keylan. version() { - log "Carbs Packaging Tools" 5.1.1 + log "Carbs Packaging Tools" @VERSION@ exit 0 } @@ -44,6 +45,72 @@ trap_set() { esac } +sepchar() ( + # Seperate every character on the given string without resorting to external + # processes. + [ "$1" ] || return 0; str=$1; set -- + while [ "$str" ]; do + str_tmp=$str + for i in $(_seq $(( ${#str} - 1 ))); do + str_tmp=${str_tmp%?} + done + set -- "$@" "$str_tmp" + str=${str#$str_tmp} + done + printf '%s\n' "$@" +) + +_seq() ( + # Pure shell counter meant to be used in 'for' loops. + i=0 buf='' + while [ "$(( i += 1 ))" -le "$1" ]; do + buf="$buf $i " + done + printf '%s' "$buf" +) + +_stat() ( + _user=; eval set -- "$(ls -ld "$1")" + id -u "${_user:=$3}" >/dev/null 2>&1 || _user=root + printf '%s' "$_user" +) + +_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 +) + # This is the public domain getoptions shell library. It also forms a usage # function. # URL: https://github.com/ko1nksm/getoptions (v2.0.1) @@ -346,7 +413,7 @@ as_root() { "$@" case ${su##*/} in - sudo|doas) "$su" -u "$user" -- env "$@" ;; + sls|sudo|doas) "$su" -u "$user" -- env "$@" ;; su) su -c "env $* <&3" "$user" 3<&0 </dev/tty ;; *) die "Invalid CPT_SU value: $su" ;; esac @@ -706,16 +773,29 @@ pkg_depends() { (pkg_list "$1" >/dev/null) && return while read -r dep type || [ "$dep" ]; do + # Skip comments and empty lines. + [ "${dep##\#*}" ] || continue # Skip test dependencies unless $CPT_TEST is set to 1. - case $type in test) [ "$CPT_TEST" = 1 ] || continue; esac + # + # Skip make dependencies on the 'tree' operation for child packages + # or when the 'first-nomake' argument is given. + case $type in + test) [ "$CPT_TEST" = 1 ] || continue ;; + make) [ "$2" = tree ] && [ -z "${3#first-nomake}" ] && continue + esac - # Recurse through the dependencies of the child packages. - [ "${dep##\#*}" ] && pkg_depends "$dep" + # Recurse through the dependencies of the child packages. Forward + # the 'tree' operation. + if [ "$2" = tree ]; then + pkg_depends "$dep" tree + else + pkg_depends "$dep" + fi done 2>/dev/null < "$(pkg_find "$1")/depends" ||: # After child dependencies are added to the list, # add the package which depends on them. - [ "$2" = explicit ] || deps="$deps $1 " + [ "$2" = explicit ] || [ "$3" ] || deps="$deps $1 " } } @@ -1019,6 +1099,11 @@ pkg_build() { diff -U 3 "$pkg_build" .build.cpt > "$pkg_build.diff" && rm -f "$pkg_build.diff" + # We don't want the package manager to track 'dir' pages of the info + # directory. We don't want every single package to create their own dir + # files either. + rm -f "$pkg_dir/$pkg/usr/share/info/dir" + # We never ever want this. Let's end the endless conflicts # and remove it. find "$pkg_dir/$pkg" -name charset.alias -exec rm -f {} + @@ -1145,14 +1230,11 @@ pkg_conflicts() { # Use $CPT_ROOT in filename so that we follow its symlinks. file=$CPT_ROOT/${file#/} - # We will only follow the symlinks of the directories, so we - # reserve the directory name in this 'dirname' value. cpt-readlink - # functions in a similar fashion to 'readlink -f', it makes sure - # every component except for the first one to be available on - # the directory structure. If we cannot find it in the system, - # we don't need to make this much more complex by trying so - # hard to find it. Simply use the original directory name. - dirname="$(cpt-readlink "${file%/*}" 2>/dev/null)" || + # We will only follow the symlinks of the directories, so we reserve the + # directory name in this 'dirname' value. If we cannot find it in the + # system, we don't need to make this much more complex by trying so hard + # to find it. Simply use the original directory name. + dirname="$(_readlinkf "${file%/*}" 2>/dev/null)" || dirname="${file%/*}" @@ -1577,8 +1659,7 @@ pkg_fetch() { # ownership of files and directories in the rare # case that the repository is owned by a 3rd user. ( - user=$(cpt-stat "$PWD") || user=root - id -u "$user" >/dev/null 2>&1 || user=root + user=$(_stat "$PWD") [ "$user" = root ] || log "Dropping permissions to $user for pull" @@ -1614,8 +1695,7 @@ pkg_fetch() { # We are going to do the same operation as above, to # find the owner of the repository. ( - user=$(cpt-stat "$PWD") || user=root - id -u "$user" >/dev/null 2>&1 || user=root + user=$(_stat "$PWD") [ "$user" = root ] || log "Dropping permissions to $user for pull" @@ -1647,8 +1727,7 @@ pkg_fetch() { # Similar to the git update, we find the owner of # the repository and spawn rsync as that user. ( - user=$(cpt-stat "$PWD") || user=root - id -u "$user" >/dev/null 2>&1 || user=root + user=$(_stat "$PWD") [ "$user" = root ] || log "Dropping permissions to $user for pull" @@ -1743,6 +1822,48 @@ pkg_updates(){ log "Updated all packages" } +pkg_get_base() ( + # Print the packages defined in the /etc/cpt-base file. + # If an argument is given, it prints a space seperated list instead + # of a list seperated by newlines. + + # cpt-base is an optional file, return with success if it doesn't exist. + [ -f "$CPT_ROOT/etc/cpt-base" ] || return 0 + nonl=$1; set -- + + # Older versions of shellcheck warns us that the variable is changing on the + # subshell. That is our purpose here, thank you very much. + # shellcheck disable=SC2030 + while read -r pkgname _; do + [ "${pkgname##\#*}" ] || continue + set -- "$@" "$pkgname" + done < "$CPT_ROOT/etc/cpt-base" + if [ "$nonl" ]; then printf '%s ' "$@"; else printf '%s\n' "$@"; fi +) + +pkg_gentree() ( + # Generate an ordered dependency tree of a package. Useful for testing + # whether the generated dependency tree is enough to actually building a + # given package. A second argument can be given as a combination of + # characters (similar to 'tar(1)' keys) which will be used as an option + # parser. See the documentation for more information on the keys. + deps='' reverse='' nonl='' make_deps=first + for op in $(sepchar "$2"); do + case "$op" in + b) deps="$(pkg_get_base nonl)" ;; + x) make_deps=first-nomake ;; + r) reverse=1 ;; + n) nonl=1 ;; + *) return 1 + esac + done + pkg_depends "$1" tree "${make_deps:+first}" + eval set -- "$deps" + pkg_order "$@" + if [ "$reverse" ]; then eval set -- "$redro"; else eval set -- "$order"; fi + if [ "$nonl" ]; then printf '%s ' "$@"; else printf '%s\n' "$@"; fi +) + pkg_clean() { # Clean up on exit or error. This removes everything related # to the build. @@ -1763,10 +1884,14 @@ create_cache() { # # Create the required temporary directories and set the variables # which point to them. - mkdir -p "${CPT_TMPDIR:=$cac_dir/proc}" \ - "${mak_dir:=$CPT_TMPDIR/$pid/build}" \ - "${pkg_dir:=$CPT_TMPDIR/$pid/pkg}" \ - "${tar_dir:=$CPT_TMPDIR/$pid/export}" + mkdir -p "${tmp_dir:=${CPT_TMPDIR:=$cac_dir/proc}/$pid}" + + # If an argument is given, skip the creation of other cache directories. + # This here makes shellcheck extremely angry, so I am globally disabling + # SC2119. + [ "$1" ] || mkdir -p "${mak_dir:=$tmp_dir/build}" \ + "${pkg_dir:=$tmp_dir/pkg}" \ + "${tar_dir:=$tmp_dir/export}" } @@ -1821,7 +1946,9 @@ create_cache() { # 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 sudo || command -v doas)} || su=su + 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 uring builds. @@ -1872,3 +1999,15 @@ create_cache() { fi } + +# If the library is being called with its own name, run arguments. +if [ "${0##*/}" = cpt-lib ]; then + pd() { + setup REST help:usage -- "usage: ${0##*/} [funcall...]" + global_options + } + eval "$(getoptions pd parse "$0")" + parse "$@" + eval set -- "$REST" + "$@" +fi diff --git a/src/cpt-list b/src/cpt-list index a161abf..363e22f 100755 --- a/src/cpt-list +++ b/src/cpt-list @@ -5,11 +5,23 @@ parser_definition() { setup REST help:usage -- "usage: ${0##*/} [-c] [pkg...]" msg -- '' 'Options:' flag CURRENT -c --current -- "Use the current directory as a package" + param PKG --check label:" --check PKG TRUE FALSE" -- \ + "Check if PKG exists and return the string of TRUE if"\ + "it exists, and the string of FALSE if it doesn't." \ + "Useful for optional packaging." global_options } if [ -f ./cpt-lib ]; then . ./cpt-lib; else . cpt-lib; fi +if [ "$PKG" ]; then + if pkg_list "$PKG" >/dev/null 2>&1; then + printf %s "$1" + else + printf %s "$2" + fi +else [ "$CURRENT" ] && set -- "${PWD##*/}" pkg_list "$@" +fi diff --git a/src/cpt-remove b/src/cpt-remove index bcf5047..cce3739 100755 --- a/src/cpt-remove +++ b/src/cpt-remove @@ -10,7 +10,7 @@ parser_definition() { if [ -f ./cpt-lib ]; then . ./cpt-lib; else . cpt-lib; fi -[ "$1" ] || set -- "${PWD##*/}"; export CPT_PATH=${PWD%/*}:$CPT_PATH +[ "$1" ] || { set -- "${PWD##*/}"; export CPT_PATH=${PWD%/*}:$CPT_PATH ;} [ -w "$CPT_ROOT/" ] || [ "$uid" = 0 ] || { as_root "$0" "$@" diff --git a/src/test.do b/src/test.do new file mode 100644 index 0000000..159cece --- /dev/null +++ b/src/test.do @@ -0,0 +1,7 @@ +SRC_ROOT=.. +. ${SRC_ROOT}/config.rc + +redo-ifchange cpt-lib +exec >&2 +find . ../contrib -name 'cpt-*' ! -name '*.*' -exec shellcheck -e 2119 -x -f gcc {} + +PHONY |