forked from kiss-community/kiss
Compare commits
103 Commits
Author | SHA1 | Date |
---|---|---|
wael | b9a8f9fc28 | |
phoebos | 7740c929a3 | |
phoebos | 9f88746487 | |
phoebos | 584b905d17 | |
phoebos | 37e6a59ed3 | |
phoebos | a6bb1c5a26 | |
phoebos | 1492cfa0a7 | |
phoebos | 4e809ddf6b | |
phoebos | 5e338034ec | |
phoebos | 9e1394c897 | |
phoebos | 61b24f4d7b | |
phoebos | b66a2c4203 | |
phoebos | 4f739a6589 | |
Vouivre | 38b71d01b2 | |
sewn | 6a41ce4f7e | |
illiliti | b04a707130 | |
sdsddsd1 | ed4b6b7534 | |
sdsddsd1 | cbbfd857f0 | |
phoebos | d240830906 | |
phoebos | 65b5140de5 | |
git-bruh | b71f27c891 | |
phoebos | fabe05b37d | |
Pratham | 8caca48504 | |
illiliti | 3309146e61 | |
phoebos | a27fcec564 | |
Pratham | 8a1a88e0d3 | |
phoebos | 58475f7f29 | |
Pratham | 74f78a8529 | |
phoebos | 9c72484a62 | |
git-bruh | b748b87148 | |
Pratham | 2f4fc41582 | |
Pratham | cb9fe25776 | |
Pratham | e9c72295d6 | |
Pratham | 2b84ea4563 | |
phoebos | 967f62b3be | |
phoebos | 7de9d70fe4 | |
git-bruh | f50ea0caa5 | |
ioraff | 51768ad4c3 | |
phoebos | d31dcf585e | |
ehawkvu | 5f9c2c70fa | |
ehawkvu | 74313a873c | |
aabacchus | b815b07b7a | |
aabacchus | 154dada0df | |
git-bruh | 875a574eb7 | |
git-bruh | 909ef5ac74 | |
Wolf Gupta | 15c89f6423 | |
Wolf Gupta | 36df1ae0e5 | |
Wolf Gupta | af2335c55e | |
git-bruh | 031179e1b1 | |
git-bruh | fd3fe16812 | |
git-bruh | 2afac4e981 | |
Owen Rafferty | 2e7e04a537 | |
aabacchus | 96bb00372c | |
jellybean | d47508c04d | |
Owen Rafferty | 6887884127 | |
aabacchus | c6c851b645 | |
illiliti | 363fcaf71c | |
aabacchus | 800d3ac854 | |
aabacchus | a973491b0e | |
dylan | 990eba374e | |
jgart | 8e304105b7 | |
Dylan Araps | 54a8fab2f2 | |
Dylan Araps | ff86512d3a | |
Dylan Araps | d21b33742d | |
Dylan Araps | 70bd51f46b | |
Dylan Araps | 9f31e3db97 | |
dylan | 69b8c9ac1e | |
Arthur Williams | 11e28a4c9b | |
Dylan Araps | 1c743cea46 | |
Dylan Araps | 0fd043a4c1 | |
dylan | 898fa5ac3a | |
Ethan | c3e9bf86b4 | |
Dylan Araps | 228075aab1 | |
Dylan Araps | 764acdcde7 | |
Dylan Araps | 7cb70f67ec | |
Dylan Araps | e58c74eb1f | |
Dylan Araps | ef8ef9986b | |
Dylan Araps | 993f4ee9b1 | |
Dylan Araps | eed63b0d81 | |
Dylan Araps | 12646e4009 | |
Dylan Araps | a4f7765f94 | |
Dylan Araps | 60c32c5fa2 | |
Dylan Araps | fd8cfe1c69 | |
Dylan Araps | 5d55bef961 | |
Dylan Araps | 2d084c5e27 | |
Dylan Araps | cade52d1cc | |
Dylan Araps | 9ab1f9f5e0 | |
Dylan Araps | 252df82806 | |
Dylan Araps | d58eb983bf | |
Dylan Araps | 7a53298241 | |
Dylan Araps | 98097feec5 | |
Dylan Araps | 02cec7a879 | |
Dylan Araps | 6a00546b3b | |
Dylan Araps | 993bea5ba0 | |
Dylan Araps | 6eb382f400 | |
dylan | 88b5989da4 | |
Dylan Araps | ea9d8e7ad5 | |
Dylan Araps | 4de7a6ffb4 | |
Dylan Araps | 29c57a0115 | |
Dylan Araps | 47a4b2b769 | |
Dylan Araps | e58a0f4f0b | |
Dylan Araps | c84775c152 | |
Dylan Araps | 755838425f |
|
@ -0,0 +1,9 @@
|
|||
steps:
|
||||
build:
|
||||
image: alpine
|
||||
when:
|
||||
branch: [ master ]
|
||||
commands: |
|
||||
apk add --no-cache shellcheck
|
||||
|
||||
shellcheck kiss contrib/*
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh -e
|
||||
#!/bin/sh
|
||||
# Enter a kiss chroot
|
||||
|
||||
log() {
|
||||
|
@ -16,8 +16,8 @@ run() {
|
|||
}
|
||||
|
||||
clean() {
|
||||
log Unmounting host filesystems; {
|
||||
run umount "$1/dev/shm"
|
||||
log Unmounting host paths; {
|
||||
run umount "$1/dev/shm" 2>/dev/null
|
||||
run umount "$1/dev/pts"
|
||||
run umount "$1/dev"
|
||||
run umount "$1/proc"
|
||||
|
@ -25,10 +25,7 @@ clean() {
|
|||
run umount "$1/sys/firmware/efi/efivars" 2>/dev/null
|
||||
run umount "$1/sys"
|
||||
run umount "$1/tmp"
|
||||
}
|
||||
|
||||
log Cleaning leftover host files; {
|
||||
run rm -f "$1/etc/resolv.conf"
|
||||
run umount "$1/etc/resolv.conf"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,21 +57,22 @@ main() {
|
|||
[ -d "$1" ] || die Given path does not exist
|
||||
[ "$(id -u)" = 0 ] || die Script needs to be run as root
|
||||
|
||||
trap 'clean "${1%"${1##*[!/]}"}"' EXIT INT
|
||||
# Intended behaviour.
|
||||
# shellcheck disable=SC2064
|
||||
trap "clean ${1%"${1##*[!/]}"}" EXIT INT
|
||||
|
||||
log Mounting host filesystems; {
|
||||
mmount "$1/dev" -o bind /dev
|
||||
log Mounting host paths; {
|
||||
mmount "$1/dev" -o bind /dev
|
||||
mmount "$1/dev/pts" -o bind /dev/pts
|
||||
mmount "$1/dev/shm" -t tmpfs shmfs
|
||||
mmount "$1/dev/shm" -t tmpfs shmfs 2>/dev/null
|
||||
mmount "$1/proc" -t proc proc
|
||||
mmount "$1/run" -t tmpfs tmpfs
|
||||
mmount "$1/sys" -t sysfs sys
|
||||
mmount "$1/sys/firmware/efi/efivars" -t efivarfs efivarfs 2>/dev/null
|
||||
mmount "$1/tmp" -o mode=1777,nosuid,nodev -t tmpfs tmpfs
|
||||
}
|
||||
|
||||
log Copying /etc/resolv.conf from host; {
|
||||
run cp -f /etc/resolv.conf "$1/etc"
|
||||
touch "$1/etc/resolv.conf"
|
||||
mmount "$1/etc/resolv.conf" -o bind /etc/resolv.conf
|
||||
}
|
||||
|
||||
log Entering chroot; {
|
||||
|
@ -90,7 +88,7 @@ main() {
|
|||
CXXFLAGS="${CXXFLAGS:--march=x86-64 -mtune=generic -pipe -O2}" \
|
||||
MAKEFLAGS="${MAKEFLAGS:--j$(nproc 2>/dev/null || echo 1)}" \
|
||||
/bin/sh -l
|
||||
}
|
||||
} || die chroot failed
|
||||
}
|
||||
|
||||
main "$1"
|
||||
|
|
|
@ -6,23 +6,35 @@ cd "$KISS_ROOT/usr/share/doc/kiss" 2>/dev/null || {
|
|||
exit 1
|
||||
}
|
||||
|
||||
! [ -f "${1:-.}/index.txt" ] || file=./${1:-.}/index.txt
|
||||
! [ -f "${1:-.}.txt" ] || file=./${1:-.}.txt
|
||||
! [ -f "${1:-:}" ] || file=./${1:-.}
|
||||
_q=$1
|
||||
|
||||
! [ -f "${_q:-.}/index.txt" ] || file=./${_q:-.}/index.txt
|
||||
! [ -f "${_q:-.}.txt" ] || file=./${_q:-.}.txt
|
||||
! [ -f "${_q:-:}" ] || file=./${_q:-.}
|
||||
|
||||
# Fallback to package READMEs.
|
||||
# False positive, intended behavior.
|
||||
# shellcheck disable=2046
|
||||
[ "$file" ] || {
|
||||
set -f
|
||||
set +f -- $(kiss s "${_q##*/}")
|
||||
file=${1:+"$1/README"}
|
||||
}
|
||||
|
||||
# Fallback to search (allows 'kiss help firefox' to work).
|
||||
# False positive, intended behavior.
|
||||
# shellcheck disable=2046
|
||||
[ "$file" ] || {
|
||||
set -f
|
||||
set +f -- $(find . -name "${1##*/}.txt")
|
||||
set +f -- $(find . -name "${_q##*/}.txt")
|
||||
file=$1
|
||||
}
|
||||
|
||||
: "${file:=404.txt}"
|
||||
|
||||
cat <<EOF - "$file" | "${PAGER:-less}"
|
||||
Reading $PWD/${file#./}
|
||||
Reading ${file#./}
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
EOF
|
||||
|
|
|
@ -3,16 +3,14 @@
|
|||
|
||||
# Use the current directory as the package name if no package is given.
|
||||
[ "$1" ] || {
|
||||
export KISS_PATH=${PWD%/*}:$KISS_PATH
|
||||
export KISS_PATH="${PWD%/*}:$KISS_PATH"
|
||||
set -- "${PWD##*/}"
|
||||
}
|
||||
|
||||
kiss search "$@" | uniq -u | while read -r repo; do cd "$repo"
|
||||
m=$(git log -1 version 2>/dev/null) ||:
|
||||
m=${m##*Author: }
|
||||
m=${m%%>*}
|
||||
kiss search "$@" | sort -u | while read -r repo; do cd "$repo"
|
||||
m=$(git log -1 --format='%an <%ae>' -- version 2>/dev/null) ||:
|
||||
|
||||
[ "$m" ] || continue
|
||||
|
||||
printf '=> %s\n%s>\n' "$PWD" "$m"
|
||||
printf '=> %s\n%s\n' "$PWD" "$m"
|
||||
done
|
||||
|
|
|
@ -1,16 +1,41 @@
|
|||
#!/bin/sh -e
|
||||
# List orphaned packages
|
||||
|
||||
cd "$KISS_ROOT/var/db/kiss/installed/"
|
||||
n='
|
||||
'
|
||||
|
||||
for pkg in *; do
|
||||
case $pkg in
|
||||
# Exemptions for orphans which aren't really
|
||||
# orphans. Exclude them from the list.
|
||||
baseinit|baselayout|gcc|e2fsprogs|musl|\
|
||||
make|busybox|bzip2|grub|kiss|git)
|
||||
continue
|
||||
cd "$KISS_ROOT/var/db/kiss/installed"
|
||||
set -- *
|
||||
|
||||
l=$n$(
|
||||
for pkg do shift
|
||||
set -- "$@" -e "$pkg"
|
||||
done
|
||||
|
||||
# Get a list of non-orphans.
|
||||
grep -Fx "$@" -- */depends |
|
||||
|
||||
{
|
||||
# Strip filename.
|
||||
sed s,.\*/depends:,,
|
||||
|
||||
# Exclude packages which are not really orphans.
|
||||
printf '%s\n' baseinit baselayout busybox bzip2 e2fsprogs gcc \
|
||||
git grub kiss make musl
|
||||
} |
|
||||
|
||||
# Remove duplicates.
|
||||
sort -u
|
||||
)$n
|
||||
|
||||
# Generate the list of orphans by finding the inverse of the non-orphan list.
|
||||
for pkg do shift
|
||||
case $l in (*"$n$pkg$n"*)
|
||||
continue
|
||||
esac
|
||||
|
||||
grep -q "^$pkg$" ./*/depends || printf '%s\n' "$pkg"
|
||||
set -- "$@" "$pkg"
|
||||
done
|
||||
|
||||
printf '%s\n' "$@"
|
||||
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
#!/bin/sh
|
||||
# Check repository for outdated packages
|
||||
|
||||
repology_version() {
|
||||
# Grab the package's version as known by repology.org by downloading the
|
||||
# svg latest-version badge and extracting the version from the xml.
|
||||
repology_name "$1"
|
||||
die() {
|
||||
printf '%s\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
r=$(curl -Ss "https://repology.org/badge/latest-versions/$remote.svg") && {
|
||||
remote_ver=${r%</text>*}
|
||||
remote_ver=${remote_ver##*>}
|
||||
}
|
||||
mkcd() {
|
||||
mkdir -p "$1" && cd "$1"
|
||||
}
|
||||
|
||||
repology_name() {
|
||||
|
@ -19,24 +17,36 @@ repology_name() {
|
|||
remote=${1%%-bin}
|
||||
remote=${remote%%-git}
|
||||
|
||||
printf %s "$remote" |
|
||||
|
||||
# Remote names are all lowercase.
|
||||
tr '[:upper:]' '[:lower:]' |
|
||||
|
||||
tr '[:upper:]' '[:lower:]' <<EOF |
|
||||
$remote
|
||||
EOF
|
||||
# Remote always uses -.
|
||||
tr _ -
|
||||
)
|
||||
|
||||
case $remote in
|
||||
age)
|
||||
remote=age-encryption
|
||||
;;
|
||||
|
||||
baseinit|baselayout|kiss)
|
||||
remote=-
|
||||
;;
|
||||
|
||||
|
||||
bat)
|
||||
remote=bat-cat
|
||||
;;
|
||||
|
||||
clang)
|
||||
remote=llvm
|
||||
;;
|
||||
|
||||
ctags)
|
||||
remote=exuberant-ctags
|
||||
;;
|
||||
|
||||
dash)
|
||||
remote=dash-shell
|
||||
;;
|
||||
|
@ -49,15 +59,27 @@ repology_name() {
|
|||
remote=dsp-audio-processing
|
||||
;;
|
||||
|
||||
dust)
|
||||
remote=du-dust
|
||||
;;
|
||||
|
||||
emacs-nox)
|
||||
# TODO [community]: Make default emacs no x11?
|
||||
remote=emacs
|
||||
;;
|
||||
|
||||
go-ipfs)
|
||||
remote=ipfs
|
||||
;;
|
||||
|
||||
fd)
|
||||
remote=fd-find
|
||||
;;
|
||||
|
||||
fdm)
|
||||
remote=fdm-email-fetcher
|
||||
;;
|
||||
|
||||
fetsh)
|
||||
# TODO [community]: Rename package?
|
||||
remote=fet.sh
|
||||
|
@ -71,6 +93,10 @@ repology_name() {
|
|||
remote=fonts:fontawesome
|
||||
;;
|
||||
|
||||
foot-pgo)
|
||||
remote=foot
|
||||
;;
|
||||
|
||||
gc)
|
||||
remote=boehm-gc
|
||||
;;
|
||||
|
@ -87,7 +113,7 @@ repology_name() {
|
|||
;;
|
||||
|
||||
gtk+3)
|
||||
remote=gtk3+classic
|
||||
remote=gtk3-classic
|
||||
;;
|
||||
|
||||
gst-*)
|
||||
|
@ -123,11 +149,31 @@ repology_name() {
|
|||
remote=fonts:liberation
|
||||
;;
|
||||
|
||||
libjpeg)
|
||||
remote=ijg-libjpeg
|
||||
;;
|
||||
|
||||
libmupdf | libxaw3d)
|
||||
# TODO [community]: Rename packages?
|
||||
remote=${remote##lib}
|
||||
;;
|
||||
|
||||
libnghttp2)
|
||||
remote=nghttp2
|
||||
;;
|
||||
|
||||
libportaudio2)
|
||||
remote=portaudio
|
||||
;;
|
||||
|
||||
libseat)
|
||||
remote=seatd
|
||||
;;
|
||||
|
||||
libzmq)
|
||||
remote=zeromq
|
||||
;;
|
||||
|
||||
links2)
|
||||
# TODO [community]: Rename package?
|
||||
remote=links
|
||||
|
@ -137,6 +183,10 @@ repology_name() {
|
|||
remote=linux
|
||||
;;
|
||||
|
||||
lpeg)
|
||||
remote=lua:lpeg
|
||||
;;
|
||||
|
||||
lux)
|
||||
remote=lux-brightness-ventto
|
||||
;;
|
||||
|
@ -152,6 +202,10 @@ repology_name() {
|
|||
remote=netsurf
|
||||
;;
|
||||
|
||||
noto-emoji)
|
||||
remote=fonts:noto-emoji
|
||||
;;
|
||||
|
||||
openjpeg2)
|
||||
# TODO [community]: Rename package?
|
||||
remote=openjpeg
|
||||
|
@ -161,10 +215,22 @@ repology_name() {
|
|||
remote=oil-shell
|
||||
;;
|
||||
|
||||
pass)
|
||||
remote=password-store
|
||||
;;
|
||||
|
||||
pinentry-dmenu)
|
||||
remote=pinentry-dmenu-cemkeylan
|
||||
;;
|
||||
|
||||
pybind11)
|
||||
remote=python:pybind11
|
||||
;;
|
||||
|
||||
python-psutil)
|
||||
remote=python:psutil
|
||||
;;
|
||||
|
||||
pyqt5)
|
||||
# TODO [community]: Rename package?
|
||||
remote=python-qt
|
||||
|
@ -174,12 +240,24 @@ repology_name() {
|
|||
remote=python
|
||||
;;
|
||||
|
||||
python-docutils)
|
||||
remote=python:docutils
|
||||
;;
|
||||
|
||||
python-mako)
|
||||
remote=python:mako
|
||||
;;
|
||||
|
||||
python-markupsafe)
|
||||
remote=python:markupsafe
|
||||
;;
|
||||
|
||||
qt5*)
|
||||
remote=qt
|
||||
;;
|
||||
|
||||
rage)
|
||||
remote=rage-encryption-tool
|
||||
remote=rage-encryption
|
||||
;;
|
||||
|
||||
sane)
|
||||
|
@ -194,6 +272,10 @@ repology_name() {
|
|||
remote=fusefs:sshfs
|
||||
;;
|
||||
|
||||
slides)
|
||||
remote=slides-presentation-tool
|
||||
;;
|
||||
|
||||
surf)
|
||||
remote=surf-browser
|
||||
;;
|
||||
|
@ -202,18 +284,38 @@ repology_name() {
|
|||
remote=st-term
|
||||
;;
|
||||
|
||||
sway-no-seat | sway-tiny)
|
||||
remote=sway
|
||||
;;
|
||||
|
||||
tea)
|
||||
remote=gitea-tea
|
||||
;;
|
||||
|
||||
terminus-font)
|
||||
remote=fonts:terminus
|
||||
;;
|
||||
|
||||
tiv)
|
||||
remote=tiv-unclassified
|
||||
remote=tiv-terminalimageviewer
|
||||
;;
|
||||
|
||||
tree)
|
||||
remote=tree-steve-baker
|
||||
;;
|
||||
|
||||
ttf-font-awesome)
|
||||
remote=font-awesome6
|
||||
;;
|
||||
|
||||
unifont)
|
||||
remote=fonts:unifont
|
||||
;;
|
||||
|
||||
vis)
|
||||
remote=vis-editor
|
||||
;;
|
||||
|
||||
webkit2gtk)
|
||||
# TODO [community]: Rename package?
|
||||
remote=webkitgtk
|
||||
|
@ -230,60 +332,70 @@ repology_name() {
|
|||
esac
|
||||
}
|
||||
|
||||
main() {
|
||||
printf '\n[Checking Repology for outdated packages in %s]\n\n' "${1%%/}" >&2
|
||||
repology_version() {
|
||||
[ -f "$1.svg" ] || return 1
|
||||
read -r remote_ver < "$1.svg" || :
|
||||
remote_ver=${remote_ver%</text>*}
|
||||
remote_ver=${remote_ver##*>}
|
||||
}
|
||||
|
||||
repo_version() {
|
||||
read -r ver _ 2>/dev/null < "$2/version" || {
|
||||
printf '%-30s local version not found\n' "$1" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
[ "$ver" != git ]
|
||||
}
|
||||
|
||||
get_outdated() {
|
||||
repo=${PWD%%/}
|
||||
printf '\n[Checking Repology for outdated packages in %s]\n\n' "$repo" >&2
|
||||
|
||||
for pkg in */; do
|
||||
pkg=${pkg%%/}
|
||||
repology_name "${pkg##*/}"
|
||||
|
||||
read -r ver _ 2>/dev/null < "$pkg/version" || {
|
||||
printf '%-30s local version not found\n' "$pkg" >&2
|
||||
continue
|
||||
}
|
||||
[ "$remote" = - ] ||
|
||||
set -- "$@" -z "$remote.svg" \
|
||||
"https://repology.org/badge/latest-versions/$remote.svg"
|
||||
done
|
||||
|
||||
[ "$ver" = git ] &&
|
||||
continue
|
||||
mkcd "$tmp/${repo##*/}"
|
||||
|
||||
repology_version "$pkg" || {
|
||||
printf '%-30s network error\n' "$pkg" >&2
|
||||
continue
|
||||
}
|
||||
curl -SsZ --parallel-max 16 --remote-name-all "$@" ||
|
||||
die 'fatal: network error'
|
||||
|
||||
for _pkg in "$OLDPWD"/*/; do
|
||||
pkg=${_pkg%%/}
|
||||
pkg=${pkg##*/}
|
||||
|
||||
repo_version "$pkg" "$_pkg" || continue
|
||||
repology_name "$pkg"
|
||||
repology_version "$remote" || continue
|
||||
|
||||
case $remote_ver in
|
||||
*", $ver"* | *"$ver,"* | "$ver")
|
||||
# Package up-to-date, do nothing.
|
||||
;;
|
||||
|
||||
'' | ' ')
|
||||
printf '\n%s: empty response\n' "$pkg" >&2
|
||||
printf 'possible causes:\n' >&2
|
||||
printf ' package name differs from repology name,\n' >&2
|
||||
printf ' package not tracked by repology,\n' >&2
|
||||
printf ' network error\n\n' >&2
|
||||
;;
|
||||
|
||||
'-')
|
||||
# No version scheme, do nothing.
|
||||
;;
|
||||
|
||||
*)
|
||||
printf '%-30s %s -> %s\n' "$pkg" "$ver" "$remote_ver"
|
||||
;;
|
||||
*", $ver"* | *"$ver,"* | "$ver" | '') continue ;;
|
||||
-) printf '%-30s no remote version found\n' "$pkg" >&2; continue ;;
|
||||
esac
|
||||
|
||||
printf '%-30s %s -> %s\n' "$pkg" "$ver" "$remote_ver"
|
||||
done
|
||||
}
|
||||
|
||||
for repo do
|
||||
[ "$repo" ] || {
|
||||
printf 'usage: kiss outdated /path/to/repo\n' >&2
|
||||
exit 1
|
||||
}
|
||||
main() {
|
||||
set -e
|
||||
|
||||
cd "$repo" 2>/dev/null || {
|
||||
printf 'repository %s is inaccessible\n' "$repo" >&2
|
||||
exit 1
|
||||
}
|
||||
[ "$1" ] || set -- "$PWD"
|
||||
|
||||
main "$repo"
|
||||
cd "$OLDPWD" || exit 1
|
||||
done
|
||||
mkdir -p "${tmp:=${XDG_CACHE_HOME:-"$HOME/.cache"}/kiss/repology}"
|
||||
|
||||
for repo do
|
||||
old_pwd=$PWD
|
||||
cd "$repo"
|
||||
get_outdated
|
||||
cd "$old_pwd"
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
# Follow symlinks to any paths.
|
||||
case $1 in
|
||||
/*)
|
||||
cd -P "$KISS_ROOT${1%/*}"
|
||||
cd -P "${KISS_ROOT:-/}${1%/*}"
|
||||
[ "$PWD" = / ] && KISS_ROOT=
|
||||
;;
|
||||
|
||||
*/*)
|
||||
|
@ -24,7 +25,7 @@ esac
|
|||
# Print the full path to the manifest file which contains
|
||||
# the match to our search.
|
||||
pkg_owns=$(grep -lFx \
|
||||
"$PWD/${1##*/}" \
|
||||
"${PWD#"$KISS_ROOT"}/${1##*/}" \
|
||||
"$KISS_ROOT/var/db/kiss/installed/"*/manifest)
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#!/bin/sh -e
|
||||
# Lists the owners of all files with conflicts
|
||||
|
||||
kiss a | while read -r _ path; do
|
||||
if owner=$(kiss owns "$path" 2>/dev/null) && [ "$owner" ]; then
|
||||
printf '%s %s\n' "$owner" "$path"
|
||||
|
||||
else
|
||||
printf 'warning: %s has no owner\n' "$path" >&2
|
||||
fi
|
||||
done
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh -ef
|
||||
# Display a package's dependencies in repositories
|
||||
|
||||
pkg=${1:-"${PWD##*/}"}
|
||||
|
||||
kiss search "$pkg" >/dev/null || {
|
||||
printf 'usage: kiss-depends [pkg]\n' >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
kiss search "$pkg" | while read -r pkgpath; do
|
||||
printf '=> %s\n' "$pkgpath"
|
||||
while read -r dep mak || [ "$dep" ]; do
|
||||
printf '%s%s\n' "$dep" "${mak:+ "$mak"}"
|
||||
done 2>/dev/null < "$pkgpath/depends"
|
||||
done
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/sh
|
||||
# Display packages in all repositories which depend on a package
|
||||
|
||||
[ "$1" ] || set -- "${PWD##*/}"
|
||||
|
||||
suffix () {
|
||||
case "$1" in *"$2") return 0; esac; return 1
|
||||
}
|
||||
|
||||
IFS=:
|
||||
for repo in $KISS_PATH; do
|
||||
# remove trailing slashes
|
||||
while suffix "$repo" /; do repo="${repo%/}"; done
|
||||
gitdir="$(git -C "$repo" rev-parse --show-toplevel 2>/dev/null || echo "$repo")"
|
||||
case "$gitdir" in "$repo") unset prefix ;; *) prefix="${repo##*/}/" ;; esac
|
||||
|
||||
cd "$gitdir/.." || continue
|
||||
grep -E "^$1([[:space:]]|$)" -- "${gitdir##*/}/$prefix"*/depends 2>/dev/null ||:
|
||||
done
|
|
@ -5,4 +5,5 @@
|
|||
|
||||
cd "$KISS_ROOT/var/db/kiss/installed"
|
||||
|
||||
grep "^$1" -- */depends
|
||||
grep -E "^$1( |$)" -- */depends
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ kiss list "${1:-null}" >/dev/null || {
|
|||
# Directories in the manifest end in a trailing '/'.
|
||||
# Send the file list to 'xargs' to run through 'du',
|
||||
# this prevents du from exiting due to too many arguments
|
||||
sed -e "s|^|$KISS_ROOT|" -e 's|.*/$||' \
|
||||
sed -e "s|^|$KISS_ROOT|" -e '/.*\/$/d' -e 's/[^[:alnum:]]/\\&/g' \
|
||||
"$KISS_ROOT/var/db/kiss/installed/$1/manifest" \
|
||||
| xargs du -sk -- 2>/dev/null |
|
||||
|
||||
|
|
|
@ -1,245 +0,0 @@
|
|||
KISS PACKAGE MANAGER
|
||||
________________________________________________________________________________
|
||||
|
||||
The KISS package manager is a small, self-contained POSIX shell script with an
|
||||
emphasis on portability.
|
||||
|
||||
Source: $/kisslinux/kiss
|
||||
|
||||
|
||||
[0.0] Index
|
||||
________________________________________________________________________________
|
||||
|
||||
* Usage [1.0]
|
||||
* Dependencies [2.0]
|
||||
* Configuration [3.0]
|
||||
* Package Manager Hooks [4.0]
|
||||
* Package Manager Extensions [5.0]
|
||||
|
||||
|
||||
[1.0] Usage
|
||||
________________________________________________________________________________
|
||||
|
||||
+------------------------------------------------------------------------------+
|
||||
| kiss |
|
||||
+------------------------------------------------------------------------------+
|
||||
| |
|
||||
| -> kiss [a|b|c|d|i|l|r|s|u|v] [pkg]... |
|
||||
| -> alternatives List and swap alternatives |
|
||||
| -> build Build packages |
|
||||
| -> checksum Generate checksums |
|
||||
| -> download Download sources |
|
||||
| -> install Install packages |
|
||||
| -> list List installed packages |
|
||||
| -> remove Remove packages |
|
||||
| -> search Search for packages |
|
||||
| -> update Update the system |
|
||||
| -> version Package manager version |
|
||||
| |
|
||||
+------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
[2.0] Dependencies
|
||||
________________________________________________________________________________
|
||||
|
||||
+-----------------------+-------------------------------------------+----------+
|
||||
| Dependency | Reason for use | Required |
|
||||
+-----------------------+-------------------------------------------+----------|
|
||||
| | | |
|
||||
| POSIX utilities | N/A | Yes |
|
||||
| git | Remote repositories and git sources | Yes [1] |
|
||||
| curl | Source downloads | Yes |
|
||||
| gnupg1 or gnupg2 | Repository signing | No |
|
||||
| openssl | Checksums | Yes [2] |
|
||||
| tar | Sources, packages, etc | Yes [3] |
|
||||
| gzip, bzip2, xz, zstd | Tarball compression | Yes [4] |
|
||||
| su, sudo, doas, ssu | Privilege escalation | No [5] |
|
||||
| ldd | Dependency Fixer | No [6] |
|
||||
| readelf | Dependency Fixer (better edition) | No [6] |
|
||||
| strip | Binary Stripping | No [6] |
|
||||
| | | |
|
||||
+-----------------------+-------------------------------------------+----------+
|
||||
|
||||
[1] Git is also required for contribution to the distribution itself. Strictly
|
||||
speaking, nothing forces you to use git. Remote repositories and git based
|
||||
sources will simply become unusable.
|
||||
|
||||
[2] There is no standard utility for the generation of sha256 checksums. While
|
||||
openssl is listed above, the package manager also supports sha256sum,
|
||||
sha256, shasum, and digest as fallbacks.
|
||||
|
||||
[3] The tar command has no standard! The POSIX equivalent is "pax" though this
|
||||
has its own issues (-s is unclear about links). Our usage of tar is merely,
|
||||
cf, xf and tf. Our usage of tar cannot become any more basic than it is now.
|
||||
|
||||
Portability should not be a concern.
|
||||
|
||||
Tested tar implementations include: busybox, toybox, sbase, OpenBSD, GNU
|
||||
and libarchive (though all tar implementations should work in theory).
|
||||
|
||||
[4] The first three compression methods are required as 99% of package sources
|
||||
use them as the tarball compression method. Nothing as of yet uses zstd in
|
||||
the official repositories.
|
||||
|
||||
[5] A privilege escalation utility is only needed when installing packages to
|
||||
a directory owned by another user (user -> root) or (root -> user).
|
||||
|
||||
[6] If missing, binary stripping and/or the dependency fixer will be disabled.
|
||||
|
||||
|
||||
[3.0] Configuration
|
||||
________________________________________________________________________________
|
||||
|
||||
The package manager has no configuration file and no changes need to be made to
|
||||
the system prior to its use. While there is no configuration file, this does not
|
||||
mean that there is no possibility for configuration.
|
||||
|
||||
The package manager can be configured via the use of environment variables.
|
||||
|
||||
+----------------+-------------------------------------------------------------+
|
||||
| Variable | Description |
|
||||
+----------------+-------------------------------------------------------------+
|
||||
| | |
|
||||
| KISS_CHK | Which utility to use when checksumming sources. |
|
||||
| | Valid: openssl, sha256sum, sha256, shasum, digest. |
|
||||
| | |
|
||||
| KISS_CHOICE | Set to '0' to disable the alternatives system and error on |
|
||||
| | any detected file conflicts. |
|
||||
| | |
|
||||
| KISS_COLOR | Enable/Disable colors. Set to '0' to disable colors. |
|
||||
| | Color is otherwise disabled when output is not a terminal. |
|
||||
| | |
|
||||
| KISS_COMPRESS | Compression method to use for built package tarballs. |
|
||||
| | Valid: gz (default), bz2, lzma, lz, xz, zst. |
|
||||
| | |
|
||||
| KISS_DEBUG | Keep temporary directories around for debugging purposes. |
|
||||
| | Set to '1' to enable. |
|
||||
| | |
|
||||
| KISS_ELF | Which readelf command to use. |
|
||||
| | Valid: readelf (default), readelf-*, ldd. |
|
||||
| | |
|
||||
| KISS_FORCE | Force installation/removal of packages by bypassing |
|
||||
| | dependency checks, etc. Set to '1' to enable. |
|
||||
| | |
|
||||
| KISS_GET | Which utility to use when downloading sources. |
|
||||
| | Valid: aria2c, axel, curl, wget, wget2. |
|
||||
| | |
|
||||
| KISS_HOOK | Hook into the package manager. A colon separated list of |
|
||||
| | absolute paths to executable files. |
|
||||
| | |
|
||||
| KISS_KEEPLOG | Keep build logs around for successful builds and not just |
|
||||
| | failing ones. Set to '1' to enable. |
|
||||
| | |
|
||||
| KISS_PATH | List of repositories. This works exactly like '$PATH' |
|
||||
| | (a colon separated list of absolute paths). |
|
||||
| | |
|
||||
| KISS_PROMPT | Skip all prompts. Set to '0' to say 'yes' to all prompts |
|
||||
| | from the package manager. |
|
||||
| | |
|
||||
| KISS_ROOT | Where installed packages will go. Can be used to install |
|
||||
| | packages to somewhere other than '/'. |
|
||||
| | |
|
||||
| KISS_STRIP | Enable/Disable package stripping globally. |
|
||||
| | Set to '0' to disable. |
|
||||
| | |
|
||||
| KISS_SU | Force usage of a different sudo tool. |
|
||||
| | NOTE: Tool must support sudo-like arguments. |
|
||||
| | |
|
||||
| KISS_TMPDIR | Temporary directory for builds. Can be set to a tmpfs so |
|
||||
| | builds happen in memory. |
|
||||
| | |
|
||||
+----------------+-------------------------------------------------------------+
|
||||
|
||||
|
||||
[4.0] Package Manager Hooks
|
||||
________________________________________________________________________________
|
||||
|
||||
KISS' package manager is extensible via hooks which fire at various different
|
||||
places inside the utility. Hooks allow the user to modify behavior, add new
|
||||
features or conditionally do things on a per-package basis.
|
||||
|
||||
|
||||
[4.1] Usage
|
||||
____________________________________________________________________________
|
||||
|
||||
This setting is controlled by the '$KISS_HOOK' environment variable which
|
||||
takes a colon separated list of absolute file paths to executables.
|
||||
|
||||
+--------------------------------------------------------------------------+
|
||||
| |
|
||||
| export KISS_HOOK=$HOME/.local/bin/kiss-hook:/path/to/other/hook |
|
||||
| |
|
||||
+--------------------------------------------------------------------------+
|
||||
|
||||
|
||||
[4.2] List of hooks
|
||||
____________________________________________________________________________
|
||||
|
||||
Each hook is executed in the order it appears in KISS_HOOK and is given its
|
||||
own environment/arguments accordingly. The hooks are documented as follows.
|
||||
|
||||
+---------------+--------+----------+--------------------+-----------------+
|
||||
| hook | arg1 | arg2 | arg3 | arg4 |
|
||||
+---------------+--------+----------+--------------------+-----------------+
|
||||
| | | | | |
|
||||
| build-fail | type | package | Build directory | |
|
||||
| post-build | type | package | DESTDIR | |
|
||||
| post-install | Type | Package | Installed database | |
|
||||
| post-package | Type | Package | Tarball | |
|
||||
| post-source | Type | Package | Verbatim source | Resolved source |
|
||||
| post-update | Type | [7] | | |
|
||||
| pre-build | Type | Package | Build directory | |
|
||||
| pre-extract | Type | Package | DESTDIR | |
|
||||
| pre-install | Type | Package | Extracted package | |
|
||||
| pre-remove | Type | Package | Installed database | |
|
||||
| pre-source | Type | Package | Verbatim source | Resolved source |
|
||||
| pre-update | Type | [7] [8] | | |
|
||||
| queue-status | Type | Package | Number in queue | Total in queue |
|
||||
| | | | | |
|
||||
+---------------+--------+----------+--------------------+-----------------+
|
||||
|
||||
[7] The -update hooks start in the current repository. In other words, you
|
||||
can operate on the repository directly or grab the value from '$PWD'.
|
||||
|
||||
[8] The second argument of pre-update is '0' if the current user owns the
|
||||
repository and '1' if they do not. In the latter case, privilege
|
||||
escalation is required to preserve ownership.
|
||||
|
||||
|
||||
[5.0] Package Manager Extensions
|
||||
________________________________________________________________________________
|
||||
|
||||
Anything in the user's '$PATH' which matches the glob 'kiss-*' will be directly
|
||||
usable via the package manager. For example, 'kiss-size' is also usable as
|
||||
'kiss size' (and even 'kiss si') (the shortest available alias).
|
||||
|
||||
The detected 'kiss-*' utilities will appear in the package manager's help-ext
|
||||
output with the second line in the script acting as a doc-string.
|
||||
|
||||
Example help output:
|
||||
|
||||
+------------------------------------------------------------------------------+
|
||||
| kiss help-ext |
|
||||
+------------------------------------------------------------------------------+
|
||||
| |
|
||||
| -> Installed extensions (kiss-* in $PATH) |
|
||||
| -> chroot Enter a kiss chroot |
|
||||
| -> depends Display a package's dependencies |
|
||||
| -> export Installed package to tarball |
|
||||
| -> fork Fork a package into the current directory |
|
||||
| -> help Read KISS documentation |
|
||||
| -> link Link a repo file to another repo |
|
||||
| -> maintainer Find the maintainer of a package |
|
||||
| -> manifest Display all files owned by a package |
|
||||
| -> new Create a boilerplate package |
|
||||
| -> orphans List orphaned packages |
|
||||
| -> outdated Check repository packages for updates |
|
||||
| -> owns Check which package owns a file |
|
||||
| -> preferred Lists the owners of all files with conflicts |
|
||||
| -> revdepends Packages which depend on package |
|
||||
| -> repo-orphans List packages which aren't present in any repository |
|
||||
| -> size Show the size on disk for a package |
|
||||
| |
|
||||
+------------------------------------------------------------------------------+
|
||||
|
||||
|
|
@ -1,226 +0,0 @@
|
|||
KISS PACKAGE SYSTEM
|
||||
________________________________________________________________________________
|
||||
|
||||
Packages are comprised of a directory and the series of files contained within.
|
||||
The name of the package is derived from its directory name. The files which
|
||||
comprise the system are as follows.
|
||||
|
||||
+------------------+----------+------------+----------+-------------+----------+
|
||||
| File | Language | Executable | Comments | Blank lines | Required |
|
||||
+------------------+----------+------------+----------+-------------+----------+
|
||||
| | | | | | |
|
||||
| build | Any | Yes [2] | N/A | N/A | Yes |
|
||||
| checksums | DSL [3] | No | No | No | No [1] |
|
||||
| depends | DSL [3] | No | Yes | Yes | No |
|
||||
| sources | DSL [3] | No | Yes | Yes | No |
|
||||
| version | DSL [3] | No | [4] | [4] | Yes |
|
||||
| | | | | | |
|
||||
| pre-remove | Any | Yes [2] | N/A | N/A | No |
|
||||
| post-install | Any | Yes [2] | N/A | N/A | No |
|
||||
| | | | | | |
|
||||
+------------------+----------+------------+----------+-------------+----------+
|
||||
|
||||
Unless stated otherwise, all files marked DSL are a grid of cells split into
|
||||
rows by newline and columns by whitespace.
|
||||
|
||||
[1] The checksums file is only required if the sources file contains sources
|
||||
which exist as files on disk (directories, git repositories need not apply).
|
||||
|
||||
[2] The only requirement is that the file be executable. The file itself can be
|
||||
written in any programming language.
|
||||
|
||||
[3] The file's format is a domain specific language with its own rules.
|
||||
https://en.wikipedia.org/wiki/Domain-specific_language
|
||||
|
||||
[4] Tooling should only read the first line of the version file. Any lines
|
||||
following should be ignored (allowing one to store arbitrary information).
|
||||
|
||||
|
||||
[0.0] Index
|
||||
________________________________________________________________________________
|
||||
|
||||
* build [1.0]
|
||||
* checksums [2.0]
|
||||
* depends [3.0]
|
||||
* sources [4.0]
|
||||
* version [5.0]
|
||||
* pre-remove [6.0]
|
||||
* post-install [7.0]
|
||||
* Further reading [8.0]
|
||||
|
||||
|
||||
[1.0] build
|
||||
________________________________________________________________________________
|
||||
|
||||
The build file is executed in the directory containing the package's extracted
|
||||
sources. Unlike other distributions, a 'cd' is not needed as sources have their
|
||||
top-level directory components stripped away.
|
||||
|
||||
The build file is given two arguments. The destination directory (where
|
||||
artifacts should be installed) and the first field of the package's version
|
||||
file (verbatim).
|
||||
|
||||
The build file is given a modified environment containing DESTDIR, KISS_ROOT,
|
||||
GOPATH and generic defaults for toolchain variables (if unset by the user). The
|
||||
toolchain defaults are as follows: AR=ar, CC=cc, CXX=c++, NM=nm, RANLIB=ranlib
|
||||
|
||||
+------------------------------------------------------------------------------+
|
||||
| Example shell-based build file |
|
||||
+------------------------------------------------------------------------------+
|
||||
| |
|
||||
| 1 #!/bin/sh -e |
|
||||
| 2 |
|
||||
| 3 # Disable stripping (use if needed). |
|
||||
| 4 :> nostrip |
|
||||
| 5 |
|
||||
| 6 ./configure \ |
|
||||
| 7 --prefix=/usr |
|
||||
| 8 |
|
||||
| 9 make |
|
||||
| 10 make install |
|
||||
| |
|
||||
+------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
[2.0] checksums
|
||||
________________________________________________________________________________
|
||||
|
||||
The checksums file is generated by the package manager (kiss c pkg) and is
|
||||
derived from files listed in the package's sources file. Directories and Git
|
||||
repositories are excluded.
|
||||
|
||||
Checksum verification can be disabled for a source by replacing its checksum
|
||||
with 'SKIP' in the checksums file. The package manager will notify you when
|
||||
this occurs.
|
||||
|
||||
+------------------------------------------------------------------------------+
|
||||
| |
|
||||
| 1 892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5 |
|
||||
| 2 8a5b38a76b778da8d6f4236f1ea89e680daea971be6ee3a57e4e7ae99a883aa2 |
|
||||
| 3 SKIP |
|
||||
| |
|
||||
+------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
[3.0] depends
|
||||
________________________________________________________________________________
|
||||
|
||||
The depends file contains the package's dependencies listed one per line in
|
||||
alphabetical order. Duplicate entries are not supported. The second optional
|
||||
field denotes the dependency type (unset for runtime, 'make' for compile-time).
|
||||
|
||||
+------------------------------------------------------------------------------+
|
||||
| |
|
||||
| 1 alsa-lib |
|
||||
| 2 meson make |
|
||||
| 3 |
|
||||
| 4 # This is a comment. |
|
||||
| 5 wayland |
|
||||
| 6 wayland-protocols make |
|
||||
| |
|
||||
+------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
[4.0] sources
|
||||
________________________________________________________________________________
|
||||
|
||||
The sources file contains the package's sources one per line. A valid source is
|
||||
a URL to a file, relative path, absolute path or Git repository. The optional
|
||||
second field denotes the relative destination directory.
|
||||
|
||||
Git repositories must be prefixed with git+. An optional suffix is supported to
|
||||
checkout a specific branch (@BRANCH) or commit (#COMMIT). All clones are shallow
|
||||
where supported by the remote server. If no suffix is used, master is cloned.
|
||||
|
||||
+------------------------------------------------------------------------------+
|
||||
| |
|
||||
| 1 # This is a comment. |
|
||||
| 2 https://www.openssl.org/source/openssl-VERSION.tar.gz |
|
||||
| 3 https://causal.agency/libretls/libretls-3.3.3p1.tar.gz libretls |
|
||||
| 4 |
|
||||
| 5 files/update-certdata.sh |
|
||||
| 6 git+https://github.com/kisslinux/kiss@dev |
|
||||
| |
|
||||
+------------------------------------------------------------------------------+
|
||||
|
||||
The following MARKERS can be used to substitute version information. These are
|
||||
replaced at runtime with their respective values. Literal MARKERS can be escaped
|
||||
by prepending a backslash.
|
||||
|
||||
+------------------------------------------------------------------------------+
|
||||
| |
|
||||
| VERSION The first field of the version file verbatim. |
|
||||
| RELEASE The second field of the version file verbatim. |
|
||||
| MAJOR The first component of VERSION split on .-_+ |
|
||||
| MINOR The second component of VERSION split on .-_+ |
|
||||
| PATCH The third component of VERSION split on .-_+ |
|
||||
| IDENT All other components. |
|
||||
| PACKAGE The name of the package. |
|
||||
| |
|
||||
+------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
[5.0] version
|
||||
________________________________________________________________________________
|
||||
|
||||
The version file is a single line split into two mandatory fields. The first
|
||||
field is the package's version and the second field the version of the
|
||||
repository files themselves.
|
||||
|
||||
If the package follows its upstream release schedule, the first field should
|
||||
match the upstream version number. If the source is a Git repository, the
|
||||
version should be set to 'git'. If a specific git commit is used, the version
|
||||
number should match accordingly.
|
||||
|
||||
+------------------------------------------------------------------------------+
|
||||
| |
|
||||
| 1 1.2.11 1 |
|
||||
| |
|
||||
+------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
[6.0] pre-remove
|
||||
________________________________________________________________________________
|
||||
|
||||
The pre-remove file is executed before removal of the package. This file should
|
||||
be used to perform any required pre-removal steps or to display notices.
|
||||
|
||||
+------------------------------------------------------------------------------+
|
||||
| Example shell-based pre-remove file |
|
||||
+------------------------------------------------------------------------------+
|
||||
| |
|
||||
| TODO: Example |
|
||||
| |
|
||||
+------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
[7.0] post-install
|
||||
________________________________________________________________________________
|
||||
|
||||
The post-install file is executed after installation of the package. This file
|
||||
should be used to perform any required post-install steps or to display notices.
|
||||
|
||||
+------------------------------------------------------------------------------+
|
||||
| Example shell-based post-install file |
|
||||
+------------------------------------------------------------------------------+
|
||||
| |
|
||||
| 1 #!/bin/sh -e |
|
||||
| 2 |
|
||||
| 3 cat <<EOF |
|
||||
| 4 |
|
||||
| 5 The commands zcat, unpigz and gunzip were merely symbolic |
|
||||
| 6 links to the pigz binary. They have been removed. To gain |
|
||||
| 7 them back, create the symlinks (or use an alias or shell |
|
||||
| 8 function). |
|
||||
| 9 |
|
||||
| 10 EOF |
|
||||
| |
|
||||
+------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
[8.0] Further reading
|
||||
________________________________________________________________________________
|
||||
|
||||
- @/package-manager
|
||||
- $/kisslinux/kiss
|
||||
|
560
kiss
560
kiss
|
@ -94,9 +94,7 @@ prompt() {
|
|||
null "$1" || log "$1"
|
||||
|
||||
log "Continue?: Press Enter to continue or Ctrl+C to abort"
|
||||
|
||||
# korn-shell does not exit on interrupt of read.
|
||||
equ "$KISS_PROMPT" 0 || read -r _ || exit 1
|
||||
equ "$KISS_PROMPT" 0 || dd bs=1 count=1 >/dev/null 2>&1 || exit 1
|
||||
}
|
||||
|
||||
mkcd() {
|
||||
|
@ -153,15 +151,14 @@ pkg_owner() {
|
|||
resolve_path() {
|
||||
_rpath=$KISS_ROOT/${1#/}
|
||||
|
||||
# Attempt to resolve symlinks by using 'cd'.
|
||||
# If this fails, fallback to the file's parent
|
||||
# directory.
|
||||
cd -P "${_rpath%/*}" 2>/dev/null || PWD=${_rpath%/*}
|
||||
if cd -P "${_rpath%/*}" 2>/dev/null; then
|
||||
_parent=$PWD
|
||||
cd "$OLDPWD"
|
||||
else
|
||||
_parent=${_rpath%/*}
|
||||
fi
|
||||
|
||||
# Final resolved path.
|
||||
_rpath=${PWD#"$KISS_ROOT"}/${_rpath##*/}
|
||||
|
||||
cd "$OLDPWD"
|
||||
_rpath=${_parent#"$KISS_ROOT"}/${_rpath##*/}
|
||||
}
|
||||
|
||||
run_hook() {
|
||||
|
@ -178,27 +175,81 @@ run_hook() {
|
|||
|
||||
run_hook_pkg() {
|
||||
# Run a hook from the package's database files.
|
||||
if [ -x "$sys_db/$2/$1" ]; then
|
||||
hook_path="$sys_db/$2/$1"
|
||||
if [ -x "$hook_path" ]; then
|
||||
log "$2" "Running $1 hook"
|
||||
"$sys_db/$2/$1"
|
||||
|
||||
elif [ -f "$sys_db/$2/$1" ]; then
|
||||
user=root
|
||||
|
||||
set --
|
||||
equ "$LOGNAME" "$user" || set -- as_user
|
||||
|
||||
"$@" env KISS_ROOT='' \
|
||||
chroot "${KISS_ROOT:-/}" "${hook_path#"$KISS_ROOT"}"
|
||||
|
||||
elif [ -f "$hook_path" ]; then
|
||||
war "$2" "skipping $1 hook: not executable"
|
||||
fi
|
||||
}
|
||||
|
||||
compress() {
|
||||
case $KISS_COMPRESS in
|
||||
bz2) bzip2 -c ;;
|
||||
gz) gzip -c ;;
|
||||
lz) lzip -c ;;
|
||||
lzma) lzma -cT0 ;;
|
||||
xz) xz -cT0 ;;
|
||||
zst) zstd -cT0 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
decompress() {
|
||||
case $1 in
|
||||
*.tbz|*.bz2) bzip2 -d ;;
|
||||
*.lzma) lzma -dc ;;
|
||||
*.lz) lzip -dc ;;
|
||||
*.tar) cat ;;
|
||||
*.tgz|*.gz) gzip -d ;;
|
||||
*.xz|*.txz) xz -dcT0 ;;
|
||||
*.zst) zstd -dc ;;
|
||||
*.tar) cat ;;
|
||||
*.tbz|*.bz2) bzip2 -dc ;;
|
||||
*.lz) lzip -dc ;;
|
||||
*.tgz|*.gz) gzip -dc ;;
|
||||
*.lzma) lzma -dcT0 ;;
|
||||
*.xz|*.txz) xz -dcT0 ;;
|
||||
*.zst) zstd -dcT0 ;;
|
||||
esac < "$1"
|
||||
}
|
||||
|
||||
b3() {
|
||||
# Higher level blake3 function which filters out non-existent
|
||||
# files (and also directories).
|
||||
for f do shift
|
||||
[ -d "$f" ] || [ ! -e "$f" ] || set -- "$@" "$f"
|
||||
done
|
||||
|
||||
_b3 "$@"
|
||||
}
|
||||
|
||||
_b3() {
|
||||
unset hash
|
||||
|
||||
# Skip generation if no arguments.
|
||||
! equ "$#" 0 || return 0
|
||||
|
||||
IFS=$newline
|
||||
|
||||
# Generate checksums for all input files. This is a single
|
||||
# call to the utility rather than one per file.
|
||||
#
|
||||
# The length of the checksum is set to 33 bytes to
|
||||
# differentiate it from sha256 checksums.
|
||||
_hash=$("$cmd_b3" -l 33 "$@") || die "Failed to generate checksums"
|
||||
|
||||
# Strip the filename from each element.
|
||||
# '<checksum> ?<file>' -> '<checksum>'
|
||||
for sum in $_hash; do
|
||||
hash=$hash${hash:+"$newline"}${sum%% *}
|
||||
done
|
||||
|
||||
printf '%s\n' "$hash"
|
||||
unset IFS
|
||||
}
|
||||
|
||||
sh256() {
|
||||
# Higher level sh256 function which filters out non-existent
|
||||
# files (and also directories).
|
||||
|
@ -263,15 +314,6 @@ pkg_find_version() {
|
|||
die "$pkg" "Build file not found or not executable"
|
||||
}
|
||||
|
||||
pkg_find_version_split() {
|
||||
pkg_find_version "$@"
|
||||
|
||||
# Split the version on '.+-_' to obtain individual components.
|
||||
IFS=.+-_ read -r repo_major repo_minor repo_patch repo_ident <<EOF
|
||||
$repo_ver
|
||||
EOF
|
||||
}
|
||||
|
||||
pkg_find() {
|
||||
_pkg_find "$@" || die "'$1' not found"
|
||||
}
|
||||
|
@ -286,6 +328,7 @@ _pkg_find() {
|
|||
# Intentional.
|
||||
# shellcheck disable=2086
|
||||
for _find_path in $4 "${3:-$sys_db}"; do set +f
|
||||
ok "$_find_path" || continue
|
||||
for _find_pkg in "$_find_path/"$1; do
|
||||
test "${3:--d}" "$_find_pkg" && set -f -- "$@" "$_find_pkg"
|
||||
done
|
||||
|
@ -336,37 +379,30 @@ pkg_cache() {
|
|||
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.
|
||||
unset _res _des _fnr
|
||||
unset _res _des
|
||||
|
||||
ok "${2##\#*}" || return 0
|
||||
|
||||
# Surround each replacement with substitutions to handled escaped markers.
|
||||
# First substitution turns '\MARKER' into ' ' (can't appear in sources as
|
||||
# they're already split on whitespace), second replaces 'MARKER' with its
|
||||
# value and the third, turns ' ' into 'MARKER' (dropping \\).
|
||||
fnr "${2%"${2##*[!/]}"}" \
|
||||
\\VERSION \ VERSION "$repo_ver" \ VERSION \
|
||||
\\RELEASE \ RELEASE "$repo_rel" \ RELEASE \
|
||||
\\MAJOR \ MAJOR "$repo_major" \ MAJOR \
|
||||
\\MINOR \ MINOR "$repo_minor" \ MINOR \
|
||||
\\PATCH \ PATCH "$repo_patch" \ PATCH \
|
||||
\\IDENT \ IDENT "$repo_ident" \ IDENT \
|
||||
\\PACKAGE \ PACKAGE "$repo_name" \ PACKAGE
|
||||
|
||||
set -- "$1" "$_fnr" "${3%"${3##*[!/]}"}" "$4"
|
||||
set -- "$1" "$2" "${3%"${3##*[!/]}"}" "$4"
|
||||
|
||||
# Git repository.
|
||||
if null "${2##git+*}"; then
|
||||
_res=$2
|
||||
|
||||
# Remote source (cached).
|
||||
elif [ -f "$src_dir/$1/${3:+"$3/"}${2##*/}" ]; then
|
||||
_res=$src_dir/$1/${3:+"$3/"}${2##*/}
|
||||
_des=$src_dir/$1/${3:+"$3/"}${2##*/}
|
||||
_des=${_des%[@#]*}/
|
||||
|
||||
# Remote source.
|
||||
elif null "${2##*://*}"; then
|
||||
_res=url+$2
|
||||
_des=$src_dir/$1/${3:+"$3/"}${2##*/}
|
||||
# Remote source (cached).
|
||||
# Only check if we detect a remote source to avoid
|
||||
# masking local paths like 'files/test' as cached
|
||||
# if '$src_dir/$1/test' is present
|
||||
if [ -f "$src_dir/$1/${3:+"$3/"}${2##*/}" ]; then
|
||||
_res=$src_dir/$1/${3:+"$3/"}${2##*/}
|
||||
else
|
||||
_res=url+$2
|
||||
_des=$src_dir/$1/${3:+"$3/"}${2##*/}
|
||||
fi
|
||||
|
||||
# Local relative dir.
|
||||
elif [ -d "$repo_dir/$2" ]; then
|
||||
|
@ -394,7 +430,7 @@ pkg_source_resolve() {
|
|||
pkg_source() {
|
||||
# Download any remote package sources. The existence of local files is
|
||||
# also checked.
|
||||
pkg_find_version_split "$1"
|
||||
pkg_find_version "$1"
|
||||
|
||||
# Support packages without sources. Simply do nothing.
|
||||
[ -f "$repo_dir/sources" ] || return 0
|
||||
|
@ -406,57 +442,67 @@ pkg_source() {
|
|||
|
||||
# arg1: pre-source
|
||||
# arg2: package name
|
||||
# arg3: verbatim source
|
||||
# arg4: resolved source
|
||||
run_hook pre-source "$1" "$src" "$_fnr"
|
||||
# arg3: source
|
||||
run_hook pre-source "$1" "$src"
|
||||
|
||||
case $_res in url+*)
|
||||
# Create directory structure in source cache. This prevents cache
|
||||
# conflicts between identical sources with differing dests.
|
||||
# '$2' is set when this function is called from 'kiss c' and it is used
|
||||
# here to skip calling the Git code.
|
||||
case $2$_res in "$2url+"*|git+*)
|
||||
mkcd "${_des%/*}"
|
||||
|
||||
pkg_source_get "$_des" "${_res##url+}"
|
||||
"pkg_source_${_res%%+*}" "$_des" "${_res##"${_res%%+*}+"}"
|
||||
esac
|
||||
|
||||
# arg1: post-source
|
||||
# arg2: package name
|
||||
# arg3: verbatim source
|
||||
# arg4: resolved source
|
||||
# arg3: source
|
||||
# arg4: destination
|
||||
run_hook post-source "$1" "$src" "${_des:-"$_res"}"
|
||||
done < "$repo_dir/sources"
|
||||
}
|
||||
|
||||
pkg_source_get() {
|
||||
pkg_source_url() {
|
||||
log "$repo_name" "Downloading $2"
|
||||
|
||||
# Download to a temporary file and only move it to the destination if
|
||||
# everything completed successfully, to avoid leaving incomplete downloads
|
||||
# in the cache if it is interrupted.
|
||||
download_source=$2
|
||||
download_dest=$1
|
||||
tmp_file "${1##*/}" download
|
||||
shift
|
||||
|
||||
set -- "$_tmp_file" "$@"
|
||||
rm -f "$_tmp_file"
|
||||
|
||||
# Set the arguments based on found download utility.
|
||||
case ${cmd_get##*/} in
|
||||
aria2c|axel) set -- -o "$@" ;;
|
||||
curl) set -- -fLo "$@" ;;
|
||||
wget|wget2) set -- -O "$@" ;;
|
||||
aria2c) set -- -d / -o "$@" ;;
|
||||
axel) set -- -o "$@" ;;
|
||||
curl) set -- -fLo "$@" ;;
|
||||
wget|wget2) set -- -O "$@" ;;
|
||||
esac
|
||||
|
||||
"$cmd_get" "$@" || {
|
||||
rm -f "$2"
|
||||
die "$repo_name" "Failed to download $3"
|
||||
rm -f "$_tmp_file"
|
||||
die "$repo_name" "Failed to download $download_source"
|
||||
}
|
||||
|
||||
mv "$_tmp_file" "$download_dest"
|
||||
}
|
||||
|
||||
pkg_source_git() {
|
||||
# This magic will shallow clone branches, commits or the
|
||||
# regular repository. It correctly handles cases where a
|
||||
# shallow clone is not possible.
|
||||
log "$repo_name" "Cloning $1"
|
||||
com=${2##*[@#]}
|
||||
com=${com#"${2%[#@]*}"}
|
||||
|
||||
# Split the source into URL + OBJECT (branch or commit).
|
||||
url=$1
|
||||
com=${url##*[@#]}
|
||||
com=${com#${url%[#@]*}}
|
||||
log "$repo_name" "Checking out ${com:-FETCH_HEAD}"
|
||||
|
||||
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}"
|
||||
[ -d .git ] || git init
|
||||
|
||||
git remote set-url origin "${2%[#@]*}" 2>/dev/null ||
|
||||
git remote add origin "${2%[#@]*}"
|
||||
|
||||
git fetch --depth=1 origin "$com"
|
||||
git reset --hard FETCH_HEAD
|
||||
}
|
||||
|
||||
pkg_source_tar() {
|
||||
|
@ -481,6 +527,9 @@ pkg_source_tar() {
|
|||
# Iterate over all directories in the first level of the
|
||||
# tarball's manifest. Each directory is moved up a level.
|
||||
while IFS=/ read -r dir _; do case ${dir#.} in *?*)
|
||||
# Skip entries which aren't directories.
|
||||
[ -d "$dir" ] || continue
|
||||
|
||||
# Move the parent directory to prevent naming conflicts
|
||||
# with the to-be-moved children.
|
||||
mv -f "$dir" "$KISS_PID-$dir"
|
||||
|
@ -495,7 +544,7 @@ pkg_source_tar() {
|
|||
-exec sh -c 'mv -f "$0" "$@" .' {} + 2>/dev/null ||
|
||||
|
||||
find "$KISS_PID-$dir/." ! -name . -prune \
|
||||
-exec sh -c 'cp -fRp "$0" "$@" .' {} +
|
||||
-exec sh -c 'cp -fRPp "$0" "$@" .' {} +
|
||||
|
||||
# Remove the directory now that all files have been
|
||||
# transferred out of it. This can't be a simple 'rmdir'
|
||||
|
@ -527,7 +576,7 @@ pkg_extract() {
|
|||
|
||||
case $_res in
|
||||
git+*)
|
||||
pkg_source_git "${_res##git+}"
|
||||
cp -PRf "$_des/." .
|
||||
;;
|
||||
|
||||
*.tar|*.tar.??|*.tar.???|*.tar.????|*.t?z)
|
||||
|
@ -535,7 +584,7 @@ pkg_extract() {
|
|||
;;
|
||||
|
||||
*?*)
|
||||
cp -LRf "$_res" .
|
||||
cp -PRf "$_res" .
|
||||
;;
|
||||
esac
|
||||
done < "$repo_dir/sources" || die "$1" "Failed to extract $_res"
|
||||
|
@ -645,6 +694,25 @@ pkg_strip() {
|
|||
esac done < "$pkg_dir/$1/$pkg_db/$1/manifest" || :
|
||||
}
|
||||
|
||||
should_ignore_rpath() {
|
||||
# Intentional, globbing disabled.
|
||||
# shellcheck disable=2086
|
||||
{ IFS=:; set -- $1; unset IFS; }
|
||||
|
||||
for path do
|
||||
# TODO maybe check if the RPATH is set to a redundant value
|
||||
# like /lib or /usr/lib ?
|
||||
# ORIGIN is relative - no need to ignore it.
|
||||
# Library rpath: [$ORIGIN/../lib]
|
||||
# shellcheck disable=2016
|
||||
case $path in '$ORIGIN'*|'${ORIGIN}'*) continue; esac
|
||||
# Non-relative path, should be ignored.
|
||||
return 0
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
pkg_fix_deps() {
|
||||
# Dynamically look for missing runtime dependencies by checking each
|
||||
# binary and library with 'ldd'. This catches any extra libraries and or
|
||||
|
@ -668,28 +736,71 @@ pkg_fix_deps() {
|
|||
*/sbin/?*[!/]|*/bin/?*[!/]|*/lib/?*[!/]|\
|
||||
*/lib??/?*[!/]|*/lib???/?*[!/]|*/lib????/?*[!/])
|
||||
|
||||
# The readelf mode requires ldd's output to resolve the library
|
||||
# path for a given file. If ldd fails, silently skip the file.
|
||||
ldd=$(ldd -- "$pkg_dir/$repo_name$_file" 2>/dev/null) || continue
|
||||
unset elf
|
||||
|
||||
# Attempt to get information from readelf. If this fails (or we
|
||||
# are in ldd mode), do full ldd mode (which has the downside of
|
||||
# listing dependencies of dependencies (and so on)).
|
||||
elf=$("$cmd_elf" -d "$pkg_dir/$repo_name$_file" 2>/dev/null) || elf=$ldd
|
||||
case $cmd_elf in *readelf)
|
||||
elf=$("$cmd_elf" -d "$pkg_dir/$repo_name$_file" 2>/dev/null) ||:
|
||||
esac
|
||||
|
||||
# RPATH/RUNPATH allows the binary to set a relative path for the
|
||||
# dynamic loader that might not be present on the rootfs at the time
|
||||
# of installation. So, ignoring it can cause the dependency detector to
|
||||
# wrongly add packages. The problem also exists in reverse when the
|
||||
# package links to a library bundled inside it and present in system paths
|
||||
# aswell, and a package update unbundles it - the package gets a dependency
|
||||
# on itself due to RPATH causing ldd to find the bundled lib.
|
||||
# Example: libnss3.so exists in /usr/lib at the time of installation
|
||||
# But the package links to libnss3 in /usr/lib/PKG/libnss3.so, which is
|
||||
# present only in the build dir. So, KISS wrongly adds the installed nss
|
||||
# as a dependency.
|
||||
# To avoid dealing with this, we just ignore any libraries with RPATH set.
|
||||
# A solution to this could be to just get the NEEDED libs and RPATH with
|
||||
# readelf and resolve the paths ourselves - with adhoc logic for RPATH and
|
||||
# the build dir.
|
||||
# Another solution could be to resolve the dependencies after installation,
|
||||
# but that can cause issues with reinstalling that tarball later on.
|
||||
# https://github.com/kiss-community/kiss/issues/64
|
||||
# https://github.com/kiss-community/repo/issues/97
|
||||
while read -r _ entry_type value; do
|
||||
# Technically RUNPATH is supposed to have a higher priority
|
||||
# than RPATH but a binary that has both RPATH and RUNPATH set,
|
||||
# each with unique values is probably broken...
|
||||
case $entry_type in '(RPATH)'|'(RUNPATH)')
|
||||
value=${value##*\[}
|
||||
value=${value%%\]*}
|
||||
|
||||
should_ignore_rpath "$value" && continue 2
|
||||
# Found RPATH which shouldn't be ignored
|
||||
break
|
||||
esac
|
||||
done <<EOF
|
||||
$elf
|
||||
EOF
|
||||
|
||||
# The readelf mode requires ldd's output to resolve the library
|
||||
# path for a given file. If ldd fails, silently skip the file.
|
||||
ldd=$(ldd -- "$pkg_dir/$repo_name$_file" 2>/dev/null) || continue
|
||||
ok "$elf" || elf=$ldd
|
||||
|
||||
# Iterate over the output of readelf or ldd, extract file names,
|
||||
# resolve their paths and finally, figure out their owner.
|
||||
while read -r lib; do case $lib in *NEEDED*\[*\]|*'=>'*)
|
||||
while read -r _ entry_type lib; do case $entry_type in '(NEEDED)'|'=>')
|
||||
# readelf: 0x0000 (NEEDED) Shared library: [libjson-c.so.5]
|
||||
lib=${lib##*\[}
|
||||
lib=${lib%%\]*}
|
||||
|
||||
# Resolve library path.
|
||||
# Resolve library path. It is already resolved for ldd in the 'lib' field
|
||||
# ldd: libjson-c.so.5 => /lib/libjson-c.so.5 ...
|
||||
case $cmd_elf in
|
||||
*readelf) lib=${ldd#*" $lib => "} ;;
|
||||
*) lib=${lib##*=> } ;;
|
||||
case $cmd_elf in *readelf)
|
||||
lib=${ldd#*" $lib => "}
|
||||
# Remove prefix, else the file will not be owned by any
|
||||
# package in the pkg_owner check below
|
||||
lib=${lib#"$pkg_dir/$repo_name"}
|
||||
esac
|
||||
|
||||
lib=${lib%% *}
|
||||
|
||||
# Skip files owned by libc, libc++ and POSIX.
|
||||
|
@ -787,16 +898,17 @@ pkg_manifest_validate() {
|
|||
# NOTE: _pkg comes from caller.
|
||||
log "$_pkg" "Checking if manifest valid"
|
||||
|
||||
cnt=0
|
||||
|
||||
while read -r line; do
|
||||
[ -e "$tar_dir/$_pkg$line" ] || [ -h "$tar_dir/$_pkg$line" ] || {
|
||||
printf '%s\n' "$line"
|
||||
set -- "$@" "$line"
|
||||
: $((cnt += 1))
|
||||
}
|
||||
done < "$pkg_db/$_pkg/manifest"
|
||||
|
||||
for f do
|
||||
die "$_pkg" "manifest contains $# non-existent files"
|
||||
done
|
||||
equ "$cnt" 0 ||
|
||||
die "$_pkg" "manifest contains $cnt non-existent files"
|
||||
}
|
||||
|
||||
pkg_manifest_replace() {
|
||||
|
@ -823,12 +935,19 @@ pkg_etcsums() {
|
|||
# Minor optimization - skip packages without /etc/.
|
||||
[ -d "$pkg_dir/$repo_name/etc" ] || return 0
|
||||
|
||||
# Create a list of all files in etc but do it in reverse.
|
||||
while read -r etc; do case $etc in /etc/*[!/])
|
||||
set -- "$pkg_dir/$repo_name/$etc" "$@"
|
||||
etc="$pkg_dir/$repo_name/$etc"
|
||||
# Always use hash of /dev/null as the hash for symlinks as it's
|
||||
# possible that they can never be resolved/hashed
|
||||
# (eg. directory, non-existent path, ...)
|
||||
# So they leave missing lines in etcsums which breaks removal of all
|
||||
# other unmodified files in /etc aswell
|
||||
[ -h "$etc" ] && etc=/dev/null
|
||||
|
||||
set -- "$@" "$etc"
|
||||
esac done < manifest
|
||||
|
||||
sh256 "$@" > etcsums
|
||||
b3 "$@" > etcsums
|
||||
}
|
||||
|
||||
pkg_tar() {
|
||||
|
@ -845,14 +964,7 @@ pkg_tar() {
|
|||
cd "$pkg_dir/$1"
|
||||
|
||||
# Create a tarball from the contents of the built package.
|
||||
tar cf - . | case $KISS_COMPRESS in
|
||||
bz2) bzip2 -z ;;
|
||||
gz) gzip -6 ;;
|
||||
lzma) lzma -z ;;
|
||||
lz) lzip -z ;;
|
||||
xz) xz -zT0 ;;
|
||||
zst) zstd -z ;;
|
||||
esac > "$_tar_file"
|
||||
tar cf - . | compress > "$_tar_file"
|
||||
|
||||
cd "$OLDPWD"
|
||||
|
||||
|
@ -871,13 +983,13 @@ pkg_build_all() {
|
|||
# Mark packages passed on the command-line explicit.
|
||||
# Also resolve dependencies for all explicit packages.
|
||||
for pkg do
|
||||
pkg_depends "$pkg" expl filter
|
||||
equ "$KISS_FORCE" 1 || pkg_depends "$pkg" expl filter
|
||||
explicit="$explicit $pkg "
|
||||
done
|
||||
|
||||
# If this is an update, don't always build explicitly passsed packages
|
||||
# and instead install pre-built binaries if they exist.
|
||||
ok "$pkg_update" || explicit_build=$explicit
|
||||
ok "$prefer_cache" || explicit_build=$explicit
|
||||
|
||||
set --
|
||||
|
||||
|
@ -927,7 +1039,7 @@ pkg_build_all() {
|
|||
for pkg do
|
||||
log "$pkg" "Building package ($((_build_cur+=1))/$#)"
|
||||
|
||||
pkg_find_version_split "$pkg"
|
||||
pkg_find_version "$pkg"
|
||||
|
||||
# arg1: queue-status
|
||||
# arg2: package name
|
||||
|
@ -947,7 +1059,7 @@ pkg_build_all() {
|
|||
pkg_etcsums
|
||||
pkg_tar "$pkg"
|
||||
|
||||
if ok "$pkg_update" || ! contains "$explicit" "$pkg"; then
|
||||
if equ "${prefer_cache:=0}" 1 || ! contains "$explicit" "$pkg"; then
|
||||
log "$pkg" "Needed as a dependency or has an update, installing"
|
||||
|
||||
# Intended behavior.
|
||||
|
@ -956,11 +1068,10 @@ pkg_build_all() {
|
|||
fi
|
||||
done
|
||||
|
||||
case $pkg_update in '')
|
||||
# Intentional, globbing disabled.
|
||||
# shellcheck disable=2046,2086
|
||||
# Intentional, globbing disabled.
|
||||
# shellcheck disable=2046,2086
|
||||
! equ "${build_install:=1}" 1 || ! equ "${KISS_PROMPT:=1}" 1 ||
|
||||
! prompt "Install built packages? [$explicit]" || (args i $explicit)
|
||||
esac
|
||||
}
|
||||
|
||||
pkg_build() {
|
||||
|
@ -986,17 +1097,16 @@ pkg_build() {
|
|||
# Give the script a modified environment. Define toolchain program
|
||||
# environment variables assuming a generic environment by default.
|
||||
#
|
||||
# Define DESTDIR, PREFIX and GOPATH to sane defaults as their use is
|
||||
# mandatory in anything using autotools, meson, cmake, etc.
|
||||
#
|
||||
# Define KISS_ROOT as the sanitized value used internally by the
|
||||
# package manager. This is safe to join with other paths.
|
||||
# Define GOPATH to sane defaults as its use is mandatory for Go projects.
|
||||
# Define KISS_ROOT as the sanitized value used internally by the package
|
||||
# manager. This is safe to join with other paths.
|
||||
AR="${AR:-ar}" \
|
||||
CC="${CC:-cc}" \
|
||||
CXX="${CXX:-c++}" \
|
||||
NM="${NM:-nm}" \
|
||||
RANLIB="${RANLIB:-ranlib}" \
|
||||
DESTDIR="$pkg_dir/$1" \
|
||||
RUSTFLAGS="--remap-path-prefix=$PWD=. $RUSTFLAGS" \
|
||||
GOFLAGS="-trimpath -modcacherw $GOFLAGS" \
|
||||
GOPATH="$PWD/go" \
|
||||
KISS_ROOT="$KISS_ROOT" \
|
||||
\
|
||||
|
@ -1057,7 +1167,7 @@ pkg_checksum_gen() {
|
|||
esac
|
||||
done < "$repo_dir/sources"
|
||||
|
||||
_sh256 "$@"
|
||||
_b3 "$@"
|
||||
}
|
||||
|
||||
pkg_verify() {
|
||||
|
@ -1074,23 +1184,21 @@ pkg_verify() {
|
|||
# shellcheck disable=2038,2086
|
||||
set -- $hash
|
||||
|
||||
# Only read checksums if we generated some.
|
||||
null "$1" ||
|
||||
|
||||
# Check that the first column (separated by whitespace) match in both
|
||||
# checksum files. If any part of either file differs, mismatch. Abort.
|
||||
while read -r chk _ || ok "$1"; do
|
||||
null "$1" || while read -r chk _ || ok "$1"; do
|
||||
equ "${#chk}" 64 && {
|
||||
log "$repo_name" "Detected sha256 checksums." ERROR
|
||||
log "blake3 is the new checksum provider for kiss. Please run"
|
||||
log "'kiss checksum $repo_name' to regenerate the checksums file."
|
||||
return 1
|
||||
}
|
||||
|
||||
printf '%s\n%s\n' "- ${chk:-missing}" "+ ${1:-no source}"
|
||||
|
||||
case $1-${chk:-null} in
|
||||
"$chk-$1"|"$1-SKIP")
|
||||
# We have a match.
|
||||
;;
|
||||
|
||||
"$hash"-*|*)
|
||||
die "$repo_name" "Checksum mismatch"
|
||||
;;
|
||||
esac
|
||||
equ "$1-${chk:-null}" "$chk-$1" ||
|
||||
equ "$1-${chk:-null}" "$1-SKIP" ||
|
||||
die "$repo_name" "Checksum mismatch"
|
||||
|
||||
shift "$(($# != 0))"
|
||||
done < "$repo_dir/checksums"
|
||||
|
@ -1117,7 +1225,7 @@ pkg_conflicts() {
|
|||
set -f "$sys_db"/*/manifest
|
||||
|
||||
# Remove the current package from the manifest list.
|
||||
fnr " $* " " $sys_db/$_pkg/manifest " ""
|
||||
fnr " $* " " $sys_db/$_pkg/manifest " " "
|
||||
|
||||
# Intentional, globbing disabled.
|
||||
# shellcheck disable=2046,2086
|
||||
|
@ -1210,6 +1318,27 @@ pkg_alternatives() {
|
|||
fi
|
||||
}
|
||||
|
||||
pkg_preferred() {
|
||||
cd "$sys_db"
|
||||
|
||||
# We only respect first argument
|
||||
if ok "$1"; then
|
||||
[ -d "$1" ] || die "'$1' not found"
|
||||
set -- "$1/manifest"
|
||||
else
|
||||
set +f; set -f -- */manifest
|
||||
fi
|
||||
|
||||
# Pass /dev/null to grep to always ensure that the file name
|
||||
# is printed even if we have a single file
|
||||
pkg_alternatives |
|
||||
cut -d' ' -f2- |
|
||||
grep -Fxf - "$@" /dev/null |
|
||||
sed 's/\/manifest:/ /'
|
||||
|
||||
cd "$OLDPWD"
|
||||
}
|
||||
|
||||
pkg_swap() {
|
||||
# Swap between package alternatives.
|
||||
[ -d "$sys_db/$1" ] || die "'$1' not found"
|
||||
|
@ -1255,6 +1384,10 @@ file_rwx() {
|
|||
[st]*) o=$((o + 1)) ;;
|
||||
esac
|
||||
|
||||
case $rwx in
|
||||
[tT]*) oct=1$oct
|
||||
esac
|
||||
|
||||
case $((${c%?} % 3)) in 0)
|
||||
oct=$oct$o
|
||||
o=0
|
||||
|
@ -1319,10 +1452,13 @@ pkg_remove_files() {
|
|||
# functions allows us to stop duplicating code.
|
||||
while read -r file; do
|
||||
case $file in /etc/?*[!/])
|
||||
sh256 "$KISS_ROOT/$file" >/dev/null
|
||||
|
||||
read -r sum_pkg <&3 ||:
|
||||
|
||||
case "${#sum_pkg}" in
|
||||
64) sh256 "$KISS_ROOT/$file" >/dev/null ;;
|
||||
*) b3 "$KISS_ROOT/$file" >/dev/null ;;
|
||||
esac
|
||||
|
||||
equ "$hash" "$sum_pkg" || {
|
||||
printf 'Skipping %s (modified)\n' "$file"
|
||||
continue
|
||||
|
@ -1354,13 +1490,16 @@ pkg_remove_files() {
|
|||
}
|
||||
|
||||
pkg_etc() {
|
||||
sh256 "$tar_dir/$_pkg$file" "$KISS_ROOT$file" >/dev/null
|
||||
read -r sum_old <&3 2>/dev/null ||:
|
||||
|
||||
case "${#sum_old}" in
|
||||
64) sh256 "$tar_dir/$_pkg$file" "$KISS_ROOT$file" >/dev/null ;;
|
||||
*) b3 "$tar_dir/$_pkg$file" "$KISS_ROOT$file" >/dev/null ;;
|
||||
esac
|
||||
|
||||
sum_new=${hash%%"$newline"*}
|
||||
sum_sys=${hash#*"$newline"}
|
||||
|
||||
read -r sum_old <&3 2>/dev/null ||:
|
||||
|
||||
# Compare the three checksums to determine what to do.
|
||||
case ${sum_old:-null}${sum_sys:-null}${sum_new} in
|
||||
# old = Y, sys = X, new = Y
|
||||
|
@ -1398,6 +1537,14 @@ pkg_removable() {
|
|||
|
||||
set -f
|
||||
cd "$OLDPWD"
|
||||
|
||||
# Check if a package would leave dangling "orphaned" alternatives.
|
||||
tmp_file "$1" owned-conflicts
|
||||
pkg_preferred "$1" | tee "$_tmp_file"
|
||||
|
||||
cnt=$(wc -l < "$_tmp_file")
|
||||
equ "$cnt" 0 ||
|
||||
die "$1" "Not removable, package leaves behind $cnt orphaned alternatives"
|
||||
}
|
||||
|
||||
pkg_remove() {
|
||||
|
@ -1405,15 +1552,12 @@ pkg_remove() {
|
|||
# differently and configuration files are *not* overwritten.
|
||||
[ -d "$sys_db/$1" ] || die "'$1' not installed"
|
||||
|
||||
trap_off
|
||||
|
||||
# Intended behavior.
|
||||
# shellcheck disable=2030,2031
|
||||
equ "$KISS_FORCE" 1 || pkg_removable "$1"
|
||||
|
||||
# Block being able to abort the script with 'Ctrl+C' during removal.
|
||||
# Removes all risk of the user aborting a package removal leaving an
|
||||
# incomplete package installed.
|
||||
trap '' INT
|
||||
|
||||
# arg1: pre-remove
|
||||
# arg2: package name
|
||||
# arg3: path to installed database
|
||||
|
@ -1426,10 +1570,7 @@ pkg_remove() {
|
|||
log "$1" "Removing package"
|
||||
pkg_remove_files < "$sys_db/$1/manifest" 3< "$_tmp_file"
|
||||
|
||||
# Reset 'trap' to its original value. Removal is done so
|
||||
# we no longer need to block 'Ctrl+C'.
|
||||
trap pkg_clean EXIT INT
|
||||
|
||||
trap_on
|
||||
log "$1" "Removed successfully"
|
||||
}
|
||||
|
||||
|
@ -1502,6 +1643,7 @@ pkg_install() {
|
|||
;;
|
||||
esac
|
||||
|
||||
trap_off
|
||||
mkcd "$tar_dir/$_pkg"
|
||||
|
||||
# The tarball is extracted to a temporary directory where its contents are
|
||||
|
@ -1549,11 +1691,6 @@ pkg_install() {
|
|||
tmp_file "$_pkg" manifest-reverse
|
||||
sort "$tar_man" > "$_tmp_file"
|
||||
|
||||
# Block being able to abort the script with Ctrl+C during installation.
|
||||
# Removes all risk of the user aborting a package installation leaving
|
||||
# an incomplete package installed.
|
||||
trap '' INT
|
||||
|
||||
if
|
||||
# Install the package's files by iterating over its manifest.
|
||||
pkg_install_files -z "$PWD" < "$_tmp_file" 3< "$_tmp_file_pre_pre" &&
|
||||
|
@ -1568,9 +1705,7 @@ pkg_install() {
|
|||
pkg_install_files -e "$PWD" < "$_tmp_file" 3< "$_tmp_file_pre_pre"
|
||||
|
||||
then
|
||||
# Reset 'trap' to its original value. Installation is done so we no longer
|
||||
# need to block 'Ctrl+C'.
|
||||
trap pkg_clean EXIT INT
|
||||
trap_on
|
||||
|
||||
# arg1: post-install
|
||||
# arg2: package name
|
||||
|
@ -1597,7 +1732,8 @@ pkg_update() {
|
|||
|
||||
# Update each repository in '$KISS_PATH'.
|
||||
for repo do
|
||||
if git -C "$repo" remote >/dev/null 2>&1; then
|
||||
ok "$repo" || continue
|
||||
if git -C "$repo" rev-parse 'HEAD@{upstream}' >/dev/null; then
|
||||
repo_type=git
|
||||
|
||||
# Get the Git repository root directory.
|
||||
|
@ -1614,7 +1750,7 @@ pkg_update() {
|
|||
pkg_update_repo
|
||||
done
|
||||
|
||||
pkg_upgrade
|
||||
log "Run 'kiss U' to upgrade packages"
|
||||
}
|
||||
|
||||
pkg_update_repo() {
|
||||
|
@ -1643,6 +1779,11 @@ pkg_update_repo() {
|
|||
# arg1: post-update
|
||||
# env: PWD is path to repository
|
||||
run_hook post-update
|
||||
|
||||
[ ! -r MOTD ] || {
|
||||
log "$PWD" "Printing MOTD"
|
||||
cat MOTD
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1683,7 +1824,8 @@ pkg_upgrade() {
|
|||
war "Packages without repository$_repo_orp"
|
||||
esac
|
||||
|
||||
pkg_update=1
|
||||
build_install=0
|
||||
prefer_cache=1
|
||||
|
||||
! contains "$*" kiss || {
|
||||
log "Detected package manager update"
|
||||
|
@ -1704,8 +1846,7 @@ pkg_upgrade() {
|
|||
# shellcheck disable=2046,2086
|
||||
set -- $order
|
||||
|
||||
log "Packages to update ($#): $*"
|
||||
prompt
|
||||
prompt "Packages to update ($#): $*"
|
||||
pkg_build_all "$@"
|
||||
log "Updated all packages"
|
||||
return 0
|
||||
|
@ -1737,20 +1878,17 @@ pkg_help_ext() {
|
|||
#
|
||||
# This also removes any duplicates found in '$PATH', picking the
|
||||
# first match.
|
||||
for path do p=${path#*/kiss-}
|
||||
case " $seen " in
|
||||
*" $p "*)
|
||||
shift
|
||||
;;
|
||||
for path do
|
||||
p=${path#*/kiss-}
|
||||
|
||||
*)
|
||||
seen=" $seen $p "
|
||||
max=$((${#p} > max ? ${#p}+1 : max))
|
||||
;;
|
||||
case " $seen " in *" $p "*)
|
||||
shift
|
||||
continue
|
||||
esac
|
||||
done
|
||||
|
||||
IFS=\#$IFS
|
||||
seen=" $seen $p "
|
||||
max=$((${#p} > max ? ${#p}+1 : max))
|
||||
done
|
||||
|
||||
# Print each extension, grab its description from the second line
|
||||
# in the file and align the output based on the above max.
|
||||
|
@ -1759,13 +1897,37 @@ pkg_help_ext() {
|
|||
exec 3< "$path"
|
||||
|
||||
# Grab the second line in the extension.
|
||||
{ read -r _ && read -r _ cmt; } <&3
|
||||
{ read -r _ && IFS=\#$IFS read -r _ cmt; } <&3
|
||||
|
||||
printf "%b->%b %-${max}s %s\\n" \
|
||||
"$c1" "$c3" "${path#*/kiss-}" "$cmt"
|
||||
done >&2
|
||||
}
|
||||
|
||||
trap_on() {
|
||||
# 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 trap_INT INT
|
||||
trap trap_EXIT EXIT
|
||||
}
|
||||
|
||||
trap_INT() {
|
||||
run_hook SIGINT
|
||||
exit 1
|
||||
}
|
||||
|
||||
trap_EXIT() {
|
||||
pkg_clean
|
||||
run_hook SIGEXIT
|
||||
}
|
||||
|
||||
trap_off() {
|
||||
# Block being able to abort the script with 'Ctrl+C'. Removes all risk of
|
||||
# the user aborting a package install/removal leaving an incomplete package
|
||||
# installed.
|
||||
trap "" INT EXIT
|
||||
}
|
||||
|
||||
args() {
|
||||
# Parse script arguments manually. This is rather easy to do in our case
|
||||
# since the first argument is always an "action" and the arguments that
|
||||
|
@ -1776,7 +1938,7 @@ args() {
|
|||
# Ensure that arguments do not contain invalid characters. Wildcards can
|
||||
# not be used here as they would conflict with kiss extensions.
|
||||
case $action in
|
||||
a|alternatives)
|
||||
a|alternatives|p|preferred)
|
||||
case $1 in *\**|*\!*|*\[*|*\ *|*\]*|*/*|*"$newline"*)
|
||||
die "Invalid argument: '!*[ ]/\\n' ($1)"
|
||||
esac
|
||||
|
@ -1798,7 +1960,7 @@ args() {
|
|||
# of the current directory as the package name and add the parent
|
||||
# directory to the running process' KISS_PATH.
|
||||
case ${action%%"${action#?}"}-$# in [!l]-0)
|
||||
export KISS_PATH=${PWD%/*}:$KISS_PATH
|
||||
export KISS_PATH="${PWD%/*}:$KISS_PATH"
|
||||
set -- "${PWD##*/}"
|
||||
esac
|
||||
|
||||
|
@ -1806,7 +1968,7 @@ args() {
|
|||
# files may differ when repositories change. Removal is not dependent on
|
||||
# the state of the repository.
|
||||
case $action in r|remove)
|
||||
export KISS_PATH=$sys_db:$KISS_PATH
|
||||
export KISS_PATH="$sys_db:$KISS_PATH"
|
||||
esac
|
||||
|
||||
# Order the argument list based on dependence.
|
||||
|
@ -1829,20 +1991,27 @@ args() {
|
|||
# shellcheck disable=2030,2031
|
||||
case $action in a|alternatives|i|install|r|remove)
|
||||
if ok "$1" && ! am_owner "$KISS_ROOT/"; then
|
||||
trap_off
|
||||
|
||||
cd "$ppwd"
|
||||
as_user env \
|
||||
LOGNAME="$user" \
|
||||
HOME="$HOME" \
|
||||
XDG_CACHE_HOME="$XDG_CACHE_HOME" \
|
||||
KISS_COMPRESS="$KISS_COMPRESS" \
|
||||
KISS_PATH="$KISS_PATH" \
|
||||
KISS_FORCE="$KISS_FORCE" \
|
||||
KISS_ROOT="$KISS_ROOT" \
|
||||
KISS_CHOICE="$KISS_CHOICE" \
|
||||
KISS_COLOR="$KISS_COLOR" \
|
||||
KISS_TMPDIR="$KISS_TMPDIR" \
|
||||
KISS_COMPRESS="$KISS_COMPRESS" \
|
||||
KISS_FORCE="$KISS_FORCE" \
|
||||
KISS_HOOK="$KISS_HOOK" \
|
||||
KISS_PATH="$KISS_PATH" \
|
||||
KISS_PID="$KISS_PID" \
|
||||
KISS_ROOT="$KISS_ROOT" \
|
||||
KISS_TMPDIR="$KISS_TMPDIR" \
|
||||
_KISS_DATE="$time" \
|
||||
_KISS_LVL="$_KISS_LVL" \
|
||||
"$0" "$action" "$@"
|
||||
|
||||
trap_on
|
||||
return
|
||||
fi
|
||||
esac
|
||||
|
@ -1857,23 +2026,25 @@ args() {
|
|||
H|help-ext) pkg_help_ext "$@" ;;
|
||||
i|install) for pkg do pkg_install "$pkg"; done ;;
|
||||
l|list) pkg_list_version "$@" ;;
|
||||
p|preferred) pkg_preferred "$@" ;;
|
||||
r|remove) for pkg in $redro; do pkg_remove "$pkg"; done ;;
|
||||
s|search) for pkg do pkg_find "$pkg" all; done ;;
|
||||
u|update) pkg_update ;;
|
||||
U|upgrade) pkg_upgrade ;;
|
||||
v|version) printf '5.5.27\n' ;;
|
||||
v|version) printf '5.6.4\n' ;;
|
||||
|
||||
'')
|
||||
log 'kiss [a|b|c|d|i|l|r|s|u|U|v] [pkg]...'
|
||||
log 'kiss [a|b|c|d|i|l|p|r|s|u|U|v] [pkg]...'
|
||||
log 'alternatives List and swap alternatives'
|
||||
log 'build Build packages'
|
||||
log 'checksum Generate checksums'
|
||||
log 'download Download sources'
|
||||
log 'install Install packages'
|
||||
log 'list List installed packages'
|
||||
log 'preferred List owners of files with alternatives'
|
||||
log 'remove Remove packages'
|
||||
log 'search Search for packages'
|
||||
log 'update Update the system and repositories'
|
||||
log 'update Update the repositories'
|
||||
log 'upgrade Update the system'
|
||||
log 'version Package manager version'
|
||||
|
||||
|
@ -1967,6 +2138,9 @@ main() {
|
|||
command -v llvm-readelf
|
||||
)"} || cmd_elf=ldd
|
||||
|
||||
# b3sum is, for now, the only supported blake3 digest utility.
|
||||
cmd_b3=b3sum
|
||||
|
||||
# Figure out which sha256 utility is available.
|
||||
cmd_sha=${KISS_CHK:-"$(
|
||||
command -v openssl ||
|
||||
|
@ -1974,7 +2148,7 @@ main() {
|
|||
command -v sha256 ||
|
||||
command -v shasum ||
|
||||
command -v digest
|
||||
)"} || die "No sha256 utility found"
|
||||
)"} || war "No sha256 utility found"
|
||||
|
||||
# Figure out which download utility is available.
|
||||
cmd_get=${KISS_GET:-"$(
|
||||
|
@ -1986,14 +2160,14 @@ main() {
|
|||
)"} || die "No download utility found (aria2c, axel, curl, wget, wget2)"
|
||||
|
||||
# Store the date and time of script invocation to be used as the name of
|
||||
# the log files the package manager creates uring builds.
|
||||
time=$(date +%Y-%m-%d-%H:%M)
|
||||
# the log files the package manager creates during builds.
|
||||
# Accept _KISS_DATE in case this process has been called by a kiss process
|
||||
# started on a different day, which could cause permission issues if we
|
||||
# create log_dir as root.
|
||||
time=${_KISS_DATE:-"$(date +%Y-%m-%d-%H:%M)"}
|
||||
|
||||
create_tmp_dirs
|
||||
|
||||
# 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 pkg_clean EXIT INT
|
||||
trap_on
|
||||
|
||||
args "$@"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue