From a46b2d4fb7dee11fcc508c6871b86d9bff8d01ae Mon Sep 17 00:00:00 2001 From: Robin Candau Date: Sun, 28 Apr 2024 12:39:20 +0200 Subject: 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 --- src/lib/repo/clean.sh | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/lib/repo/clean.sh (limited to 'src/lib/repo/clean.sh') 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 +} -- cgit v1.2.3-70-g09d2