#! /bin/bash # Copyright (C) 2026 Danilo M. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. See the LICENSE file for details. # sbshadow: reconcile upstream shadowing against personal/ and pentesting/. # # Shadow: upstream package whose name matches a personal/pentesting package is # git rm'd. Unshadow: upstream package no longer carried there is restored from # the pristine $UPSTREAM branch that danix-current was cut from. Then regenerates # phantom-dep hintfiles with mkhint -F. # # Called by slackrepo_setup_SBo-danix.sh and by sbpull after a subtree pull. # # Usage: sbshadow [--yes|--no] # no flag show the plan and ask before changing anything # --yes apply the plan without asking # --no show the plan only, tree unchanged (preview) # SBO_REPO overrides the repo path (used to test against a throwaway repo). set -euo pipefail answer="" case "${1:-}" in --yes) answer=y ;; --no) answer=n ;; "") ;; *) echo "usage: sbshadow [--yes|--no]" >&2; exit 2 ;; esac REPO="${SBO_REPO:-/var/lib/sbopkg/SBo-danix}" UPSTREAM="current" cd "$REPO" # packages carried in the overlays declare -A mine=() for d in personal/*/ pentesting/*/; do p=$(basename "$d") [[ -f "$d$p.SlackBuild" ]] && mine[$p]=1 done # category/pkg for every real package in pristine upstream to_rm=() to_restore=() while IFS= read -r path; do if [[ -n "${mine[${path#*/}]:-}" ]]; then [[ -d "$path" ]] && to_rm+=("$path") else [[ -d "$path" ]] || to_restore+=("$path") fi done < <(git ls-tree -r --name-only "$UPSTREAM" \ | grep -E '^[^/]+/([^/]+)/\1\.SlackBuild$' | xargs -r -n1 dirname) if (( ${#to_rm[@]} + ${#to_restore[@]} == 0 )); then echo "sbshadow: nothing to shadow or unshadow." else echo (( ${#to_rm[@]} )) && printf 'shadow: %s\n' "${to_rm[@]}" (( ${#to_restore[@]} )) && printf 'unshadow: %s\n' "${to_restore[@]}" echo if [[ -n $answer ]]; then confirm=$answer else read -rp "Proceed? [y/N] " confirm fi if [[ ! "$confirm" =~ ^[Yy]$ ]]; then echo "sbshadow: aborted, tree unchanged." else (( ${#to_rm[@]} )) && git rm -rq -- "${to_rm[@]}" (( ${#to_restore[@]} )) && git checkout "$UPSTREAM" -- "${to_restore[@]}" git commit -qm "shadow: reconcile upstream against personal/pentesting" echo "sbshadow: shadowed ${#to_rm[@]}, unshadowed ${#to_restore[@]}." fi fi # ── regenerate phantom-dep hintfiles (mkhint owns them) ─────────────────────── # Runs even with nothing to shadow (a subtree pull can change REQUIRES), but # not on --no: a preview leaves the hints alone too. # mkhint reads ~/.config/mkhint/phantom-deps; missing tool = harmless skip. if [[ $answer == n ]]; then echo echo "sbshadow: preview, phantom-dep hintfiles not regenerated." elif command -v mkhint >/dev/null 2>&1; then echo echo "Regenerating phantom-dep hintfiles (mkhint -F)..." mkhint -F else echo "NOTE: mkhint not found; skipping hintfile regen. Run 'mkhint -F' manually." >&2 fi