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