#!/bin/sh # shellcheck disable=2094,2103,SC2181 source=/dev/null # # puke - package manager for kiss linux. die() { printf '\033[31mERROR>\033[m %s\n' "$@" >&2 exit 1 } log() { printf '\033[32m=>\033[m %s\n' "$@" } clean() { rm -rf -- "$mak_dir" "$pkg_dir" [ -n "$name" ] && rm "$old_pwd/repo/$name/.checksums" 2>/dev/null } pkg_info() { [ -z "$1" ] && die "No package specified." cd "./repo/$1" || die "Package '$1' not in repository." [ -f version ] || die "Version file not found." [ -f sources ] || die "Sources file not found." [ -f build ] || die "Build file not found." read -r version release < version name=$1 pkg=$name\#$version-$release } pkg_depends() { [ -f depends ] && while read -r dependency; do pkg_list "$dependency" || missing="$missing $dependency" done < depends [ -n "$missing" ] && die "Missing dependencies:$missing" } pkg_sources() { while read -r src; do src_name=${src##*/} if [ -f "$src" ] || [ -f "$src_dir/$src_name" ]; then log "Found local $src_name." elif [ -z "${src##git:*}" ]; then git clone "${src##git:}" "$mak_dir" elif [ -z "${src##*://*}" ]; then log "Downloading '$src'." wget -P "$src_dir" "$src" || die "Failed to download $src." else die "Source file '$src' not found." fi done < sources } pkg_checksum() { while read -r src; do src_name=${src##*/} if [ -z "${src##git:*}" ]; then continue elif [ -f "$src" ]; then src_path=$src elif [ -f "$src_dir/$src_name" ]; then src_path=$src_dir/$src_name fi cd "${src_path%/*}" sha256sum -- "$src_name" || die "Failed to generate checksums." cd - >/dev/null done < sources > "${1-checksums}" } pkg_verify() { pkg_checksum .checksums diff .checksums checksums || die "checksum of sources does not match checksum of package" \ "run '$0 checksum $name' to update checksums" log "Checksums verified." rm .checksums } pkg_extract() { while read -r src; do src_name=${src##*/} if [ -z "${src##git:*}" ]; then continue elif [ -f "$src" ]; then cp -f "$src" "$mak_dir" elif [ ! -f "$src_dir/$src_name" ]; then die "$src_name not found." else case $src_dir/$src_name in *.tar|*.tar.??|*.tar.???|*.tar.????|*.tgz) tar xf "$src_dir/$src_name" -C "$mak_dir" \ --strip-components 1 || die "Couldn't extract $src_name" ;; esac fi done < sources } pkg_build() { log "Building $pkg." cd "$mak_dir" set -e . "$OLDPWD/build" set +e cd - cp -R "$old_pwd/repo/$name" "$old_pwd/pkg/var/db/puke" log "Sucessfully built $pkg." } pkg_manifest() { cd "$pkg_dir" _() { find . -mindepth 1 "$@" | sed 's/^\.//'; } _ -not -type d > "$OLDPWD/manifest" _ -type d | sort -r >> "$OLDPWD/manifest" cd - >/dev/null } pkg_tar() { cd "$bin_dir" tar pcvf "$pkg.tar.gz" -C "$pkg_dir" . || die "Failed to create package." log "Package is at $bin_dir/$pkg.tar.gz." } pkg_install() { pkg_remove "$name" tar pxvf "$bin_dir/$pkg.tar.gz" -k -C "$sys_dir/" || die "Failed to install $pkg" log "Installed $pkg" } pkg_remove() { pkg_list "$name" || return 1 while read -r file; do [ "${file%/*}" = "/etc" ] && continue path="${sys_dir}${file}" if [ -d "$path" ]; then rmdir "$path" 2>/dev/null else rm -- "$path" || log "Failed to remove $file." fi [ "$?" = 0 ] && log "Removed $file" done < "$sys_dir/var/db/puke/$name/manifest" return 0 } pkg_list() { [ "$1" ] && { [ -d "$sys_dir/var/db/puke/$1" ] || return 1 && return 0 } for pkg in "$sys_dir/var/db/puke/"*; do [ -d "$pkg" ] || continue read -r version release < "$pkg/version" log "${pkg##*/} $version-$release" done } args() { [ -n "${1#l*}" ] && { mkdir -p sources build pkg/var/db/puke sys bin || die "Couldn't create directories at '$PWD'". pkg_info "$2" } case $1 in b*) [ -f checksums ] || die "Checksums missing, run '$0 checksum $name'" pkg_depends pkg_sources pkg_verify pkg_extract pkg_build pkg_manifest pkg_tar ;; c*) pkg_sources pkg_checksum log "Generated checksums." ;; i*) pkg_install ;; l*) pkg_list "$2" ;; r*) pkg_remove || die "Package '$name' not installed" ;; *) log "$0 [build|checksum|install|list|remove] [pkg]" ;; esac } main() { trap clean EXIT INT clean old_pwd=$PWD src_dir=$PWD/sources # Contains the downloaded sources. mak_dir=$PWD/build # Contains the current build. pkg_dir=$PWD/pkg # Contains the built package's files. sys_dir=$PWD/sys # Fake root (testing, temporary). bin_dir=$PWD/bin # Contains the final tarballed packages. args "$@" } main "$@"