Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
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
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
-rw-r--r--contrib/completion/bash/devtools.in7
-rw-r--r--contrib/completion/zsh/_devtools.in8
-rw-r--r--doc/man/pkgctl-repo-clean.1.asciidoc40
-rw-r--r--doc/man/pkgctl-repo.1.asciidoc4
-rw-r--r--src/lib/repo.sh10
-rw-r--r--src/lib/repo/clean.sh114
6 files changed, 183 insertions, 0 deletions
diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in
index 5125ceb..136beef 100644
--- a/contrib/completion/bash/devtools.in
+++ b/contrib/completion/bash/devtools.in
@@ -292,6 +292,7 @@ _pkgctl_aur_drop_from_repo_opts() { _filedir -d; }
_pkgctl_repo_cmds=(
+ clean
clone
configure
create
@@ -317,6 +318,12 @@ _pkgctl_repo_clone_args__jobs_opts() { :; }
_pkgctl_repo_clone_args_j_opts() { _pkgctl_repo_clone_args__jobs_opts; }
_pkgctl_repo_clone_opts() { _devtools_completions_all_packages; }
+_pkgctl_repo_clean_args=(
+ -i --interactive
+ -n --dry-run
+ -h --help
+)
+_pkgctl_repo_clean_opts() { _filedir -d; }
_pkgctl_repo_configure_args=(
--protocol
diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in
index 48ff373..65d7895 100644
--- a/contrib/completion/zsh/_devtools.in
+++ b/contrib/completion/zsh/_devtools.in
@@ -114,6 +114,7 @@ _pkgctl_aur_drop_from_repo_args=(
_pkgctl_repo_cmds=(
"pkgctl repo command"
+ "clean[Remove untracked files from the working tree]"
"clone[Clone a package repository]"
"configure[Configure a clone according to distro specs]"
"create[Create a new GitLab package repository]"
@@ -128,6 +129,13 @@ _pkgctl_repo_switch_args=(
'*:git_dir:_files -/'
)
+_pkgctl_repo_clean_args=(
+ '(-i --interactive)'{-i,--interactive}'[Show what would be done and clean files interactively]'
+ '(-n --dry-run)'{-n,--dry-run}"[Don't remove anything, just show what would be done]"
+ '(-h --help)'{-h,--help}'[Display usage]'
+ '*:git_dir:_files -/'
+)
+
_pkgctl_repo_clone_args=(
'(-m --maintainer=)'{-m,--maintainer=}'[Clone all packages of the named maintainer]:maintainer:'
'--protocol[Clone the repository over https]:proto:(https)'
diff --git a/doc/man/pkgctl-repo-clean.1.asciidoc b/doc/man/pkgctl-repo-clean.1.asciidoc
new file mode 100644
index 0000000..b39693c
--- /dev/null
+++ b/doc/man/pkgctl-repo-clean.1.asciidoc
@@ -0,0 +1,40 @@
+pkgctl-repo-clean(1)
+====================
+
+Name
+----
+
+pkgctl-repo-clean - Remove untracked files from the working tree
+
+Synopsis
+--------
+
+pkgctl repo clean [OPTION] [PATH]...
+
+Description
+-----------
+
+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 actually remove anything, just show what would be done
+
+*-h, --help*::
+ Show a help text
+
+See Also
+--------
+
+git-clean(1)
+
+include::include/footer.asciidoc[]
diff --git a/doc/man/pkgctl-repo.1.asciidoc b/doc/man/pkgctl-repo.1.asciidoc
index 3d0f3f1..c1fd298 100644
--- a/doc/man/pkgctl-repo.1.asciidoc
+++ b/doc/man/pkgctl-repo.1.asciidoc
@@ -32,6 +32,9 @@ Options
Subcommands
-----------
+pkgctl repo clean::
+ Remove untracked files from the working tree
+
pkgctl repo clone::
Clone a package repository
@@ -50,6 +53,7 @@ pkgctl repo web::
See Also
--------
+pkgctl-repo-clean(1)
pkgctl-repo-clone(1)
pkgctl-repo-configure(1)
pkgctl-repo-create(1)
diff --git a/src/lib/repo.sh b/src/lib/repo.sh
index 9f545e9..8f8dd0a 100644
--- a/src/lib/repo.sh
+++ b/src/lib/repo.sh
@@ -27,6 +27,7 @@ pkgctl_repo_usage() {
without SSH access using read-only HTTPS.
COMMANDS
+ clean Remove untracked files from the working tree
clone Clone a package repository
configure Configure a clone according to distro specs
create Create a new GitLab package repository
@@ -37,6 +38,7 @@ pkgctl_repo_usage() {
-h, --help Show this help text
EXAMPLES
+ $ ${COMMAND} clean --interactive *
$ ${COMMAND} clone libfoo linux libbar
$ ${COMMAND} clone --maintainer mynickname
$ ${COMMAND} configure *
@@ -59,6 +61,14 @@ pkgctl_repo() {
pkgctl_repo_usage
exit 0
;;
+ clean)
+ _DEVTOOLS_COMMAND+=" $1"
+ shift
+ # shellcheck source=src/lib/repo/clean.sh
+ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/clean.sh
+ pkgctl_repo_clean "$@"
+ exit 0
+ ;;
clone)
_DEVTOOLS_COMMAND+=" $1"
shift
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
+}