Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/src/lib/repo
diff options
context:
space:
mode:
authorRobin Candau <robincandau@protonmail.com>2024-04-28 12:39:20 +0200
committerLevente Polyak <anthraxx@archlinux.org>2024-04-28 19:42:02 +0200
commita46b2d4fb7dee11fcc508c6871b86d9bff8d01ae (patch)
treea5b86f282648ae333aafd985ef9395546694648f /src/lib/repo
parente828111ff7094354da6d55e1bc19d2d8decf3d6d (diff)
feat(repo): add repo clean command to remove untracked files
This introduces the `pkgctl repo clean` command which removes every untracked files from local package repositories (via `git clean`). The usage is as simple as `pkgctl repo clean [OPTION] [PATH]` (where "[PATH]" can be equal to a wildcard "*"). Component: pkgctl repo clean
Diffstat (limited to 'src/lib/repo')
-rw-r--r--src/lib/repo/clean.sh114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/lib/repo/clean.sh b/src/lib/repo/clean.sh
new file mode 100644
index 0000000..bb8980e
--- /dev/null
+++ b/src/lib/repo/clean.sh
@@ -0,0 +1,114 @@
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[[ -z ${DEVTOOLS_INCLUDE_REPO_CLEAN_SH:-} ]] || return 0
+DEVTOOLS_INCLUDE_REPO_CLEAN_SH=1
+
+_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
+# shellcheck source=src/lib/common.sh
+source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
+
+source /usr/share/makepkg/util/message.sh
+
+set -eo pipefail
+
+
+pkgctl_repo_clean_usage() {
+ local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
+ cat <<- _EOF_
+ Usage: ${COMMAND} [OPTION] [PATH]...
+
+ Cleans the working tree by recursively removing files that are not under
+ version control, starting from the current directory.
+
+ Files unknown to Git as well as ignored files are removed. This can, for
+ example, be useful to remove all build products.
+
+ OPTIONS
+ -i, --interactive Show what would be done and clean files interactively
+ -n, --dry-run Don't remove anything, just show what would be done
+ -h, --help Show this help text
+
+ EXAMPLES
+ $ ${COMMAND} libfoo linux libbar
+ $ ${COMMAND} --interactive libfoo linux libbar
+ $ ${COMMAND} --dry-run *
+_EOF_
+}
+
+pkgctl_repo_clean() {
+ # options
+ local git_clean_options=()
+ local paths
+
+ local path pkgbase
+
+ while (( $# )); do
+ case $1 in
+ -i|--interactive)
+ git_clean_options+=("$1")
+ shift
+ ;;
+ -n|--dry-run)
+ git_clean_options+=("$1")
+ shift
+ ;;
+ -h|--help)
+ pkgctl_repo_clean_usage
+ exit 0
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -*)
+ die "invalid argument: %s" "$1"
+ ;;
+ *)
+ paths=("$@")
+ break
+ ;;
+ esac
+ done
+
+ # check if invoked without any path from within a packaging repo
+ if (( ${#paths[@]} == 0 )); then
+ paths=(".")
+ fi
+
+ # print message about the work chunk
+ printf "🗑️ Removing untracked files from %s working trees\n" "${BOLD}${#paths[@]}${ALL_OFF}"
+
+ for path in "${paths[@]}"; do
+ # skip paths that are not directories
+ if [[ ! -d "${path}" ]]; then
+ continue
+ fi
+
+ if [[ ! -f "${path}/PKGBUILD" ]]; then
+ msg_error "Not a package repository: ${path}"
+ continue
+ fi
+
+ if [[ ! -d "${path}/.git" ]]; then
+ msg_error "Not a Git repository: ${path}"
+ continue
+ fi
+
+ pkgbase=$(basename "$(realpath "${path}")")
+ pkgbase=${pkgbase%.git}
+
+ # run dry mode to see if git would clean any files
+ if [[ ! $(git -C "${path}" clean -x -d --dry-run 2>&1) ]]; then
+ continue
+ fi
+
+ # git clean untracked files
+ msg_success "Cleaning ${BOLD}${pkgbase}${ALL_OFF}"
+ if ! git -C "${path}" clean -x -d --force "${git_clean_options[@]}"; then
+ msg_error "Failed to remove untracked files"
+ fi
+ echo
+ done
+}