Skip to content

Instantly share code, notes, and snippets.

@bartoszek
Created March 3, 2021 09:19
Show Gist options
  • Save bartoszek/e7aea27e50b7650e18cfa2747c241521 to your computer and use it in GitHub Desktop.
Save bartoszek/e7aea27e50b7650e18cfa2747c241521 to your computer and use it in GitHub Desktop.
aurutils: clean local repo from cached remote packages.
#!/bin/bash
#todo:
# * fix remove redundant packages in multiple local repo
# * handle broken db (when new package is present in repo path but not added to repo db, e.g. after no space left on device error)
# * duplicated pacakges: fix remove from package originated in if multiple local repos.
# * package not referenced in db: add tag showing in which repository the package is present.
# * add info about which repo owns the redundant file (pacrep "${pkgname}")
# * add fileter to remove local repo packages from pacman cache (when local package is not present in pacman.conf CACHE_DIR / check aur(1) )
# * filter out old versions of package, or remove them before precede.
# * automatically remove file that already are in pacman cache.
db_compression="zst"
# Sync db before clean
sudo pacman -Sy || exit 1
mapfile -t remote_repos < <(pacconf --repo-list|xargs -I{} sh -c "pacconf --repo={} Server|grep -vq ^file && echo {}")
mapfile -t local_repos < <(pacconf --repo-list|xargs -I{} sh -c "pacconf --repo={} Server|grep -q ^file && echo {}")
mapfile -t local_repos_path < <(IFS=$'\n'; xargs -I{} sh -c "pacconf --repo={} Server|grep -oP 'file://\K.*'" <<<"${local_repos[*]}")
cachedir=$(pacconf CacheDir|grep -vFf <(IFS=$'\n'; echo "${local_repos_path[*]}"))
mapfile -t remote_pkgs < <(pacman -Sql "${remote_repos[@]}")
mapfile -t local_pkgs < <(pacman -Sql "${local_repos[@]}")
mapfile -t duplicated_pkgs < <(comm -12 <(IFS=$'\n'; sort <<<"${local_pkgs[*]}") <(IFS=$'\n'; sort <<<"${remote_pkgs[*]}"))
mapfile -t pkgs_to_remove < <(
#shellcheck disable=SC2030
for pkg in "${duplicated_pkgs[@]}"; do
#shellcheck disable=SC2183,SC2046
printf "%15s\t%15s\t%15s\t%15s\t%30s\n" $(expac -S "%r %v" "$pkg") "$pkg"|tee /dev/stderr
done|vipe|rev|cut -f1|rev|tr -d ' ')
[[ -v pkgs_to_remove[@] ]] && {
for i in $(seq 0 "$((${#local_repos[@]}-1))"); do
echo repo-remove "${local_repos_path[$i]}"/"${local_repos[$i]}".db.tar."${db_compression}" "${pkgs_to_remove[@]}"
repo-remove "${local_repos_path[$i]}"/"${local_repos[$i]}".db.tar."${db_compression}" "${pkgs_to_remove[@]}"
for pkg in "${pkgs_to_remove[@]}"; do
pkg_file=$(pacman -Sp "${local_repos[$i]}/${pkg}"|grep -oP 'file://\K.*')
echo "remove file: $pkg_file"
rm "$pkg_file"
done
done
# Sync db after remove duplicated packages
sudo pacman -Sy
}
mapfile -t pkgs_not_referenced_in_db < <(
for i in $(seq 0 "$((${#local_repos[@]}-1))"); do
#comm -13 <(pacman -Slq "${local_repos[$i]}"|xargs -I{} pacman -Spdd "${local_repos[$i]}"/{}|grep -oP 'file://\K.*'|sort) <(ls "${local_repos_path[$i]}"/*pkg.tar.*)
comm -13 <(pacman -Slq "${local_repos[$i]}"|sed "s/^/${local_repos[$i]}\//g"|xargs pacman -Spdd|grep -oP 'file://\K.*'|sort) <(ls "${local_repos_path[$i]}"/*pkg.tar.*)
done)
mapfile -t pkgs_missing_from_db < <(
for i in $(seq 0 "$((${#local_repos[@]}-1))"); do
comm -23 <(pacman -Slq "${local_repos[$i]}"|sed "s/^/${local_repos[$i]}\//g"|xargs pacman -Spdd|grep -oP 'file://\K.*'|sort) <(ls "${local_repos_path[$i]}"/*pkg.tar.*)
done)
[[ -v pkgs_not_referenced_in_db[@] ]] && (
IFS=$'\n'
echo -e "pkgs not referenced in local db:\n${pkgs_not_referenced_in_db[*]}" >&2
[[ ${#pkgs_not_referenced_in_db[@]} -gt 0 ]] && {
read -r -p "move unreferenced files to pacman cache? [yes|no|vipe|remove]" ans
[[ "$ans" == "vipe" ]] && {
preamble=$'#m - move file to pacman cache\n#r - remove file\n## - remove or comment line to preserve file\n#\n'
mapfile -t pkgs_not_referenced_in_db < <(vipe<<<"${preamble}${pkgs_not_referenced_in_db[*]/#/m }"|grep -v "^#")
sudo mv -t "$cachedir" $(grep -oP "^m\s\K.*$"<<<"${pkgs_not_referenced_in_db[*]}")
rm $(grep -oP "^r\s\K.*$"<<<"${pkgs_not_referenced_in_db[*]}") 2>&-
}
[[ "$ans" == yes ]] && sudo mv -t "$cachedir" "${pkgs_not_referenced_in_db[@]}"
[[ "$ans" == "remove" ]] && rm "${pkgs_not_referenced_in_db[@]}"
}
)
[[ -v pkgs_missing_from_db[@] ]] && (
IFS=$'\n'
echo -e "pkgs missing form local db:\n${pkgs_missing_from_db[*]}" >&2
)
exit 0
#create copy of remote repo
for repo in "${remote_repos[@]}"; do
pacman -Slq "$repo"|xargs -I{} sudo pacman --noconfirm --config pacman.conf -Swdd "$repo"/{}
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment