aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile4
-rwxr-xr-xsrc/cpt6
-rwxr-xr-xsrc/cpt-build2
-rwxr-xr-xsrc/cpt-checksum3
-rwxr-xr-xsrc/cpt-install2
-rw-r--r--src/cpt-lib.in (renamed from src/cpt-lib)189
-rwxr-xr-xsrc/cpt-list12
-rwxr-xr-xsrc/cpt-remove2
-rw-r--r--src/test.do7
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
diff --git a/src/cpt b/src/cpt
index ce4c70f..ee4a328 100755
--- a/src/cpt
+++ b/src/cpt
@@ -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