kiss: rewrite source handling

- Adds function to resolve sources.
- Tarball extraction now works with local files.
- Zip extraction now works with local files.
- Fixes internal path joining issues.
This commit is contained in:
Dylan Araps 2021-07-04 11:12:56 +00:00
parent 58e90fa779
commit 2d70c5aeac
No known key found for this signature in database
GPG Key ID: 13295DAC2CF13B5C

156
kiss
View File

@ -220,7 +220,51 @@ pkg_cache() {
[ -f "$1" ]
}
pkg_sources() {
pkg_source_resolve() {
# Given a line of input from the sources file, return an absolute
# path to the source if it already exists, error if not.
set -- "$1" "${2%"${2##*[!/]}"}" "${3%"${3##*[!/]}"}" "$4"
if [ -z "${2##\#*}" ]; then
_res=
# Git repository.
elif [ -z "${2##git+*}" ]; then
_res=$2
# Remote source (cached).
elif [ -f "$src_dir/$1/${3:+"$3/"}${2##*/}" ]; then
_res=$src_dir/$1/${3:+"$3/"}${2##*/}
# Remote source.
elif [ -z "${2##*://*}" ]; then
_res=url+$2
_des=$src_dir/$1/${3:+"$3/"}${2##*/}
# Local relative dir.
elif [ -d "$repo_dir/$2" ]; then
_res=$repo_dir/$2/.
# Local absolute dir.
elif [ -d "/${2##/}" ]; then
_res=/${2##/}/.
# Local relative file.
elif [ -f "$repo_dir/$2" ]; then
_res=$repo_dir/$2
# Local absolute file.
elif [ -f "/${2##/}" ]; then
_res=/${2##/}
else
return 1
fi
[ "$4" ] || printf 'found %s\n' "$_res"
}
pkg_source() {
# Download any remote package sources. The existence of local files is
# also checked.
pkg_find "$1"
@ -228,35 +272,22 @@ pkg_sources() {
# Support packages without sources. Simply do nothing.
[ -f "$repo_dir/sources" ] || return 0
log "$1" "Downloading sources"
log "$1" "Checking sources"
mkdir -p "$src_dir/$1" && cd "$src_dir/$1"
while read -r src dest || [ "$src" ]; do
if [ -z "${src##\#*}" ] || [ -z "${src##git+*}" ]; then
# Remote git repository or comment.
:
pkg_source_resolve "$1" "$src" "$dest" "$2" ||
die "$1" "No local file '$src'"
elif [ -f "./${dest:-.}/${src##*/}" ]; then
log "$1" "Found cached remote source '${src##*/}'"
elif [ -z "${src##*://*}" ]; then
case $_res in url+*)
log "$1" "Downloading $src"
mkdir -p "$PWD/$dest"
curl "$src" -fLo "./${dest:-.}/${src##*/}" || {
rm -f "./${dest:-.}/${src##*/}"
curl "$src" -fLo "$_des" || {
rm -f "$_des"
die "$1" "Failed to download $src"
}
elif [ -e "$repo_dir/$src" ]; then
log "$1" "Found local relative source '$src'"
elif [ -e "/$src" ]; then
log "$1" "Found local absolute source '$src'"
else
die "$1" "No local file '$src'"
fi
esac
done < "$repo_dir/sources"
}
@ -273,7 +304,10 @@ pkg_extract() {
while read -r src dest || [ "$src" ]; do
mkdir -p "$mak_dir/$1/$dest" && cd "$mak_dir/$1/$dest"
case $src in \#*|'') ;;
pkg_source_resolve "$1" "$src" "$dest" >/dev/null ||
die "$1" "No local file '$src'"
case $_res in
git+*)
# Split the source into URL + OBJECT (branch or commit).
url=${src##git+} com=${url##*[@#]} com=${com#${url%[#@]*}}
@ -281,22 +315,20 @@ pkg_extract() {
# This magic will shallow clone branches, commits or the
# regular repository. It correctly handles cases where a
# shallow clone is not possible.
log "$1" "Cloning ${url%[#@]*}"; {
git init
git remote add origin "${url%[#@]*}"
git fetch -t --filter=tree:0 origin "$com" || git fetch -t
git -c advice.detachedHead=0 checkout "${com:-FETCH_HEAD}"
} || die "$1" "Failed to clone $src"
log "$1" "Cloning ${url%[#@]*}"
git init
git remote add origin "${url%[#@]*}"
git fetch -t --filter=tree:0 origin "$com" || git fetch -t
git -c advice.detachedHead=0 checkout "${com:-FETCH_HEAD}"
;;
*://*.tar|*://*.tar.??|*://*.tar.???|*://*.tar.????|*://*.t?z)
*.tar|*.tar.??|*.tar.???|*.tar.????|*.t?z)
# This is a portable shell implementation of GNU tar's
# '--strip-components 1'.
decompress "$src_dir/$1/${dest:-.}/${src##*/}" > .ktar
decompress "$_res" > .ktar
# Extract the tar archive to the current directory.
tar xf .ktar || die "$1" "Couldn't extract ${src##*/}"
tar xf .ktar
# Iterate over all directories in the first level of the
# tarball's manifest.
@ -339,38 +371,15 @@ pkg_extract() {
rm -f .ktar
;;
*://*.zip)
unzip "$src_dir/$1/${dest:-.}/${src##*/}" ||
die "$1" "Couldn't extract ${src##*/}"
*.zip)
unzip "$_res"
;;
*)
# Local directory (relative).
if [ -d "$repo_dir/$src" ]; then
cp -Rf "$repo_dir/$src/." .
# Local directory (absolute).
elif [ -d "/$src" ]; then
cp -Rf "/$src/." .
# Local file (relative).
elif [ -f "$repo_dir/$src" ]; then
cp -f "$repo_dir/$src" .
# Local file (absolute).
elif [ -f "/$src" ]; then
cp -f "/$src" .
# Remote file.
elif [ -f "$src_dir/$1/${dest:-.}/${src##*/}" ]; then
cp -f "$src_dir/$1/${dest:-.}/${src##*/}" .
else
die "$1" "Local file $src not found"
fi
cp -Rf "$_res" .
;;
esac
done < "$repo_dir/sources"
done < "$repo_dir/sources" || die "$1" "Failed to extract $_res"
}
pkg_depends() {
@ -702,7 +711,7 @@ pkg_build() {
done
for pkg do
pkg_sources "$pkg"
pkg_source "$pkg"
pkg_verify "$pkg"
done
@ -790,23 +799,12 @@ pkg_checksums() {
pkg_find "$1"
while read -r src dest || [ "$src" ]; do
# Skip directories, comments, blank lines and git sources.
if [ -z "${src##\#*}" ] || [ -z "${src##git+*}" ] ||
[ -d "$repo_dir/$src" ] || [ -d "/$src" ]; then
:
pkg_source_resolve "$1" "$src" "$dest" >/dev/null ||
die "$1" "No local file '$src'"
# Remote source.
elif [ -z "${src##*://*}" ]; then
sh256 "$src_dir/$1/${dest:-.}/${src##*/}"
# Local file (relative).
elif [ -f "$repo_dir/$src" ]; then
sh256 "$repo_dir/$src"
# Local file (absolute).
elif [ -f "/$src" ]; then
sh256 "/$src"
fi
case $_res in */*[!.])
sh256 "$_res"
esac
done < "$repo_dir/sources" || die "$1" "Failed to generate checksums"
}
@ -1563,8 +1561,8 @@ args() {
;;
c|checksum)
for pkg do pkg_lint "$pkg"; done
for pkg do pkg_sources "$pkg" c; done
for pkg do pkg_lint "$pkg"; done
for pkg do pkg_source "$pkg" c; done
for pkg do
pkg_find "$pkg"
@ -1596,7 +1594,7 @@ args() {
;;
b|build) pkg_build "${@:?No packages installed}" ;;
d|download) for pkg do pkg_sources "$pkg"; done ;;
d|download) for pkg do pkg_source "$pkg"; done ;;
l|list) pkg_list "$@" ;;
u|update) pkg_updates ;;
s|search) for pkg do pkg_find "$pkg" all; done ;;