From 0669315821ea0af00fcc2c6271eb474174173e0a Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Fri, 21 Jul 2023 11:04:13 +0200 Subject: chore: refactor variable names in valid-{tags,repos}.sh Even though the variables in these files are globablly used they have a weirdly local sounding name. This commit fixes this by refactoring all usages throughout our codebase. Signed-off-by: Christian Heusel --- contrib/completion/bash/devtools.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'contrib/completion/bash/devtools.in') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index 3faad27..b28258f 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -8,7 +8,7 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh # shellcheck source=src/lib/valid-repos.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh -_binary_arch=${_arch[*]:0:-1} +_binary_arch=${DEVTOOLS_VALID_ARCHES[*]:0:-1} _colors=(never always auto) @@ -355,14 +355,14 @@ _devtools_completions_color() { mapfile -t COMPREPLY < <(compgen -W "${_colors[*]}" -- "$cur") } _devtools_completions_arch() { - mapfile -t COMPREPLY < <(compgen -W "${_arch[*]}" -- "$cur") + mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_ARCHES[*]}" -- "$cur") } _devtools_completions_repo() { local optional=${1:-} - mapfile -t COMPREPLY < <(compgen -W "${optional} ${_repos[*]}" -- "$cur") + mapfile -t COMPREPLY < <(compgen -W "${optional} ${DEVTOOLS_VALID_REPOS[*]}" -- "$cur") } _devtools_completions_build_repo() { - mapfile -t COMPREPLY < <(compgen -W "${_build_repos[*]}" -- "$cur") + mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_BUILDREPOS[*]}" -- "$cur") } _devtools_completions_all_packages() { mapfile -t COMPREPLY < <(compgen -W "$(pacman -Sql)" -- "$cur") -- cgit v1.2.3-70-g09d2 From e7b82f36ef586127453e8c68660e0ef7826d0127 Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Tue, 25 Jul 2023 11:19:11 +0200 Subject: feat(build): add --updpkgsums option This is useful so people who update patches etc. can update their checksums on building. The functionality itself was already implemented for --pkgver, but was not available separately. Fixes #168 Component: pkgctl build Signed-off-by: Christian Heusel --- contrib/completion/bash/devtools.in | 1 + contrib/completion/zsh/_devtools.in | 1 + doc/man/pkgctl-build.1.asciidoc | 3 +++ src/lib/build/build.sh | 5 +++++ 4 files changed, 10 insertions(+) (limited to 'contrib/completion/bash/devtools.in') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index b28258f..e0fca51 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -173,6 +173,7 @@ _pkgctl_build_args=( --pkgver --pkgrel --rebuild + --updpkgsums -e --edit -r --release diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 49c4113..d3d6df0 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -47,6 +47,7 @@ _pkgctl_build_args=( '--pkgver=[Set pkgver, reset pkgrel and update checksums]:pkgver:' '--pkgrel=[Set pkgrel to a given value]:pkgrel:' '--rebuild[Increment the pkgrel variable]' + '--updpkgsums[Regenerate the checksums]' '(-e --edit)'{-e,--edit}'[Edit the PKGBUILD before building]' '(-r --release)'{-r,--release}'[Automatically commit, tag and release after building]' '(-m --message=)'{-m,--message=}"[Use the given as the commit message]:message:" diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc index f68e7cf..2637ebc 100644 --- a/doc/man/pkgctl-build.1.asciidoc +++ b/doc/man/pkgctl-build.1.asciidoc @@ -59,6 +59,9 @@ PKGBUILD Options *--rebuild*:: Increment the current pkgrel variable +*--updpkgsums*:: + Regenerate the checksums + *-e, --edit*:: Edit the PKGBUILD before building diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index 455f38a..8d58b63 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -55,6 +55,7 @@ pkgctl_build_usage() { --pkgver=PKGVER Set pkgver, reset pkgrel and update checksums --pkgrel=PKGREL Set pkgrel to a given value --rebuild Increment the current pkgrel variable + --updpkgsums Regenerate the checksums -e, --edit Edit the PKGBUILD before building RELEASE OPTIONS @@ -169,6 +170,10 @@ pkgctl_build() { PKGREL="${1#*=}" shift ;; + --updpkgsums) + UPDPKGSUMS=1 + shift + ;; --rebuild) # shellcheck source=src/lib/util/git.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/git.sh -- cgit v1.2.3-70-g09d2 From cc369e86d2e060d8b65c7dbbb0c933d18f8aa6b0 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Thu, 23 Mar 2023 23:38:29 +0100 Subject: feat(makechrootpkg): add option to interactively inspect the chroot Implement the -x option for makechrootpkg which allows to get an interactive shell in the chroot after building the package. Useful to ease the debugging of a package build. Depending on the argument, the interactive shell is either always spawned or only when an error occurred during build. This option is also forwarded from `pkgctl build` via the `--inspect` flag. Component: pkgctl build Component: makechrootpkg Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 9 +++++++++ contrib/completion/zsh/_devtools.in | 4 ++++ doc/man/makechrootpkg.1.asciidoc | 4 ++++ doc/man/pkgctl-build.1.asciidoc | 4 ++++ src/lib/build/build.sh | 11 +++++++++++ src/lib/valid-inspect.sh | 10 ++++++++++ src/makechrootpkg.in | 38 ++++++++++++++++++++++++++++++++----- 7 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 src/lib/valid-inspect.sh (limited to 'contrib/completion/bash/devtools.in') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index e0fca51..b347b31 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -7,6 +7,8 @@ _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh # shellcheck source=src/lib/valid-repos.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh +# shellcheck source=src/lib/valid-inspect.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh _binary_arch=${DEVTOOLS_VALID_ARCHES[*]:0:-1} _colors=(never always auto) @@ -24,6 +26,7 @@ _makechrootpkg_args=( -n -T -U + -x ) _makechrootpkg_args_d_opts() { _filedir -d; } _makechrootpkg_args_D_opts() { _filedir -d; } @@ -31,6 +34,7 @@ _makechrootpkg_args_r_opts() { _filedir -d; } _makechrootpkg_args_I_opts() { _filedir '*.pkg.tar.*'; } _makechrootpkg_args_l_opts() { _filedir -d; } _makechrootpkg_args_U_opts() { :; } +_makechrootpkg_args_x_opts() { _devtools_completions_inspect; } _makechrootpkg() { __devtools_complete _makechrootpkg; } complete -F _makechrootpkg makechrootpkg @@ -169,6 +173,7 @@ _pkgctl_build_args=( -o --offload -c --clean -w --worker + --inspect --pkgver --pkgrel @@ -186,6 +191,7 @@ _pkgctl_build_args__arch_opts() { _devtools_completions_arch; } _pkgctl_build_args__repo_opts() { _devtools_completions_repo; } _pkgctl_build_args__worker_opts() { :; } _pkgctl_build_args_w_opts() { _pkgctl_build_args__worker_opts; } +_pkgctl_build_args__inspect_opts() { _devtools_completions_inspect; } _pkgctl_build_args__pkgver_opts() { :; } _pkgctl_build_args__pkgrel_opts() { :; } _pkgctl_build_args__message_opts() { :; } @@ -371,6 +377,9 @@ _devtools_completions_all_packages() { _devtools_completions_protocol() { mapfile -t COMPREPLY < <(compgen -W "https" -- "$cur") } +_devtools_completions_inspect() { + mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_INSPECT_MODES[*]}" -- "$cur") +} __devtools_complete() { local service=$1 diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index d3d6df0..feeb2c2 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -7,6 +7,8 @@ _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh # shellcheck source=src/lib/valid-repos.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh +# shellcheck source=src/lib/valid-inspect.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh _binary_arch=${DEVTOOLS_VALID_ARCHES[*]:0:-1} _colors=(never always auto) @@ -42,6 +44,7 @@ _pkgctl_build_args=( '(-o --offload)'{-o,--offload}'[Build on a remote server and transfer artifacts afterwards]' '(-c --clean)'{-c,--clean}'[Recreate the chroot before building]' '(-I --install)'{-I,--install}'[Install a package into the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"' + "--inspect[Spawn an interactive shell to inspect the chroot (never, always, failure)]:inspect:($DEVTOOLS_VALID_INSPECT_MODES[*])" '(-w --worker)'{-w,--worker}'[Name of the worker slot, useful for concurrent builds (disables auto-detection)]:slot:' '--nocheck[Do not run the check() function in the PKGBUILD]' '--pkgver=[Set pkgver, reset pkgrel and update checksums]:pkgver:' @@ -190,6 +193,7 @@ _makechrootpkg_args=( '-n[Run namcap on the package]' '-T[Build in a temporary directory]' '-U[Run makepkg as a specified user]:makepkg_user' + "-x[Spawn an interactive shell to inspect the chroot (never, always, failure)]:inspect:($DEVTOOLS_VALID_INSPECT_MODES[*])" ) _mkarchroot_args=( diff --git a/doc/man/makechrootpkg.1.asciidoc b/doc/man/makechrootpkg.1.asciidoc index 12d32f1..3aa1be5 100644 --- a/doc/man/makechrootpkg.1.asciidoc +++ b/doc/man/makechrootpkg.1.asciidoc @@ -73,4 +73,8 @@ Options *-U*:: Run makepkg as a specified user +*-x* :: + Inspect chroot after build, possible modes are 'never' (default), 'always' or 'failure' + + include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc index 2637ebc..3f2d44e 100644 --- a/doc/man/pkgctl-build.1.asciidoc +++ b/doc/man/pkgctl-build.1.asciidoc @@ -38,6 +38,10 @@ Build Options *-I, --install* 'FILE':: Install a package into the working copy of the chroot +*--inspect* 'WHEN':: + Spawn an interactive shell to inspect the chroot after building. Useful to ease the debugging of a package build. + + Possible values for 'WHEN' are `'never'`, `'always'` or `'failure'` + *-w, --worker* 'SLOT':: Name of the worker slot, useful for concurrent builds. By default the slot is automatically assigned to the current tty pts number. In case the caller diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index 8d58b63..2b9d4cf 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -20,6 +20,8 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh # shellcheck source=src/lib/valid-tags.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh +# shellcheck source=src/lib/valid-inspect.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh source /usr/share/makepkg/util/config.sh source /usr/share/makepkg/util/message.sh @@ -48,6 +50,7 @@ pkgctl_build_usage() { -o, --offload Build on a remote server and transfer artifacts afterwards -c, --clean Recreate the chroot before building -I, --install FILE Install a package into the working copy of the chroot + --inspect WHEN Spawn an interactive shell to inspect the chroot (never, always, failure) -w, --worker SLOT Name of the worker slot, useful for concurrent builds (disables automatic names) --nocheck Do not run the check() function in the PKGBUILD @@ -218,6 +221,14 @@ pkgctl_build() { warning 'not running checks is disallowed for official packages, except for bootstrapping. Please rebuild after bootstrapping is completed!' shift ;; + --inspect) + (( $# <= 1 )) && die "missing argument for %s" "$1" + if ! in_array "${2}" "${DEVTOOLS_VALID_INSPECT_MODES[@]}"; then + die "Invalid inspect mode: %s" "${2}" + fi + MAKECHROOT_OPTIONS+=("-x" "${2}") + shift 2 + ;; -r|--release) # shellcheck source=src/lib/release.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh diff --git a/src/lib/valid-inspect.sh b/src/lib/valid-inspect.sh new file mode 100644 index 0000000..3b5dcad --- /dev/null +++ b/src/lib/valid-inspect.sh @@ -0,0 +1,10 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +# shellcheck disable=2034 +DEVTOOLS_VALID_INSPECT_MODES=( + never + always + failure +) diff --git a/src/makechrootpkg.in b/src/makechrootpkg.in index 2cfd849..14b8f11 100644 --- a/src/makechrootpkg.in +++ b/src/makechrootpkg.in @@ -8,9 +8,12 @@ _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh # shellcheck source=src/lib/archroot.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/archroot.sh +# shellcheck source=src/lib/valid-inspect.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh source /usr/share/makepkg/util/config.sh +source /usr/share/makepkg/util/util.sh shopt -s nullglob @@ -31,6 +34,8 @@ run_checkpkg=0 temp_chroot=0 tmp_opts="nosuid,nodev,size=50%,nr_inodes=2m" +inspect=never + bindmounts_ro=() bindmounts_rw=() @@ -76,6 +81,7 @@ usage() { echo '-C Run checkpkg on the package' echo '-T Build in a temporary directory' echo '-U Run makepkg as a specified user' + echo '-x Inspect chroot after build (never, always, failure)' exit 1 } @@ -280,7 +286,7 @@ move_products() { } # }}} -while getopts 'hcur:I:l:nCTD:d:U:' arg; do +while getopts 'hcur:I:l:nCTD:d:U:x:' arg; do case "$arg" in c) clean_first=1 ;; D) bindmounts_ro+=("--bind-ro=$OPTARG") ;; @@ -293,6 +299,7 @@ while getopts 'hcur:I:l:nCTD:d:U:' arg; do C) run_checkpkg=1 ;; T) temp_chroot=1; copy+="-$$" ;; U) makepkg_user="$OPTARG" ;; + x) inspect="$OPTARG" ;; h|*) usage ;; esac done @@ -314,6 +321,10 @@ else copydir="$chrootdir/$copy" fi +if ! in_array "${inspect}" "${DEVTOOLS_VALID_INSPECT_MODES[@]}"; then + die "Invalid inspect mode: %s" "${inspect}" +fi + # Pass all arguments after -- right to makepkg makepkg_args+=("${@:$OPTIND}") @@ -368,11 +379,16 @@ download_sources prepare_chroot +nspawn_build_args=( + --bind="${PWD//:/\\:}:/startdir" + --bind="${SRCDEST//:/\\:}:/srcdest" + --tmpfs="/tmp:${tmp_opts}" + "${bindmounts_ro[@]}" + "${bindmounts_rw[@]}" +) + if arch-nspawn "$copydir" \ - --bind="${PWD//:/\\:}:/startdir" \ - --bind="${SRCDEST//:/\\:}:/srcdest" \ - --tmpfs="/tmp:${tmp_opts}" \ - "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \ + "${nspawn_build_args[@]}" \ /chrootbuild "${makepkg_args[@]}" then mapfile -t pkgnames < <(sudo -u "$makepkg_user" bash -c 'source PKGBUILD; printf "%s\n" "${pkgname[@]}"') @@ -382,6 +398,18 @@ else move_logfiles fi +if [[ $inspect == always ]] || ( [[ $inspect == failure ]] && (( ret != 0 )) ); then + if (( ret == 0 )); then + msg "Build succeeded, inspecting %s" "$copydir" + else + error "Build failed, inspecting %s" "$copydir" + fi + arch-nspawn "$copydir" \ + "${nspawn_build_args[@]}" \ + --user=builduser \ + --chdir=/build +fi + (( temp_chroot )) && delete_chroot "$copydir" "$copy" if (( ret != 0 )); then -- cgit v1.2.3-70-g09d2 From ae14c246b800139e3a8f5589fb8fe12aaeab6a76 Mon Sep 17 00:00:00 2001 From: kpcyrd Date: Fri, 25 Aug 2023 04:02:56 +0200 Subject: feat(makerepropkg): Add option to skip running check for speedup Add -n to allow running makepkg with --nocheck. This is useful to reduce the time required to reproduce a package, as they should not depend on running the check function for being reproducible. Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 1 + contrib/completion/zsh/_devtools.in | 1 + doc/man/makerepropkg.1.asciidoc | 3 +++ src/makerepropkg.in | 7 +++++-- 4 files changed, 10 insertions(+), 2 deletions(-) (limited to 'contrib/completion/bash/devtools.in') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index b347b31..78f0741 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -42,6 +42,7 @@ complete -F _makechrootpkg makechrootpkg _makerepropkg_args=( -h -d + -n -c -M ) diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index feeb2c2..372f07b 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -230,6 +230,7 @@ _offload_build_args=( _makerepropkg_args=( '-d[Run diffoscope if the package is unreproducible]' + '-n[Do not run the check() function in the PKGBUILD]' '-c[Set pacman cache]:pacman_cache:_files -/' '-M[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"' '-h[Display usage]' diff --git a/doc/man/makerepropkg.1.asciidoc b/doc/man/makerepropkg.1.asciidoc index 6044d7c..51a81ff 100644 --- a/doc/man/makerepropkg.1.asciidoc +++ b/doc/man/makerepropkg.1.asciidoc @@ -42,6 +42,9 @@ Options *-d*:: If packages are not reproducible, compare them using diffoscope. +*-n*:: + Do not run the check() function in the PKGBUILD. + *-c*:: Set the pacman cache directory. diff --git a/src/makerepropkg.in b/src/makerepropkg.in index 398d4af..a31f8d5 100644 --- a/src/makerepropkg.in +++ b/src/makerepropkg.in @@ -22,6 +22,7 @@ declare -a buildenv buildopts installed installpkgs archiveurl='https://archive.archlinux.org/packages' buildroot=/var/lib/archbuild/reproducible diffoscope=0 +makepkg_options=() chroot=$USER [[ -n ${SUDO_USER:-} ]] && chroot=$SUDO_USER @@ -116,6 +117,7 @@ For more details see https://reproducible-builds.org/ OPTIONS -d Run diffoscope if the package is unreproducible + -n Do not run the check() function in the PKGBUILD -c Set pacman cache -M Location of a makepkg config file -l The directory name to use as the chroot namespace @@ -128,9 +130,10 @@ __EOF__ # save all args for check_root orig_args=("$@") -while getopts 'dM:c:l:h' arg; do +while getopts 'dnM:c:l:h' arg; do case "$arg" in d) diffoscope=1 ;; + n) makepkg_options+=(--nocheck) ;; M) archroot_args+=(-M "$OPTARG") ;; c) cache_dirs+=("$OPTARG") ;; l) chroot="$OPTARG" ;; @@ -254,7 +257,7 @@ install -d -o "${SUDO_UID:-$UID}" -g "$(id -g "${SUDO_UID:-$UID}")" "${namespace arch-nspawn "${namespace}/build" \ --bind="${PWD}:/startdir" \ --bind="${SRCDEST}:/srcdest" \ - /chrootbuild -C --noconfirm --log --holdver --skipinteg + /chrootbuild -C --noconfirm --log --holdver --skipinteg "${makepkg_options[@]}" ret=$? if (( ${ret} == 0 )); then -- cgit v1.2.3-70-g09d2 From 9a356eae828ce0e75d49e3efdb42bac089eb528a Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Sat, 2 Sep 2023 12:31:12 +0200 Subject: feat(web): implement option to print the URL instead of opening it In certain situations, users may encounter limitations when unable to utilize xdg-open (e.g., when connected to an Arch machine via SSH). Consequently, this commit introduces the option to simply print the repository link to copy or click on it. Signed-off-by: Christian Heusel Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 1 + contrib/completion/zsh/_devtools.in | 1 + doc/man/pkgctl-repo-web.1.asciidoc | 3 +++ src/lib/repo/web.sh | 23 ++++++++++++++++++++--- 4 files changed, 25 insertions(+), 3 deletions(-) (limited to 'contrib/completion/bash/devtools.in') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index 78f0741..83264ce 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -325,6 +325,7 @@ _pkgctl_repo_switch_opts() { _pkgctl_repo_web_args=( + --print -h --help ) _pkgctl_repo_web_opts() { _filedir -d; } diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 372f07b..b82ece4 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -134,6 +134,7 @@ _pkgctl_repo_create_args=( ) _pkgctl_repo_web_args=( + '--print[Print the url instead of opening it with xdg-open]' '(-h --help)'{-h,--help}'[Display usage]' '*:git_dir:_files -/' ) diff --git a/doc/man/pkgctl-repo-web.1.asciidoc b/doc/man/pkgctl-repo-web.1.asciidoc index 8769be7..ba7106a 100644 --- a/doc/man/pkgctl-repo-web.1.asciidoc +++ b/doc/man/pkgctl-repo-web.1.asciidoc @@ -18,6 +18,9 @@ no arguments, open the package cloned in the current working directory. Options ------- +*--print*:: + Print the url instead of opening it with xdg-open + *-h, --help*:: Show a help text diff --git a/src/lib/repo/web.sh b/src/lib/repo/web.sh index 45ea53b..ab3d8c7 100644 --- a/src/lib/repo/web.sh +++ b/src/lib/repo/web.sh @@ -23,6 +23,7 @@ pkgctl_repo_web_usage() { no arguments, open the package cloned in the current working directory. OPTIONS + --print Print the url instead of opening it with xdg-open -h, --help Show this help text EXAMPLES @@ -32,7 +33,8 @@ _EOF_ pkgctl_repo_web() { local pkgbases=() - local path giturl pkgbase + local path giturl pkgbase url + local mode=open # option checking while (( $# )); do @@ -41,6 +43,10 @@ pkgctl_repo_web() { pkgctl_repo_web_usage exit 0 ;; + --print) + mode=print + shift + ;; --) shift break @@ -56,7 +62,7 @@ pkgctl_repo_web() { done # Check if web mode has xdg-open - if ! command -v xdg-open &>/dev/null; then + if [[ ${mode} == open ]] && ! command -v xdg-open &>/dev/null; then die "The web command requires 'xdg-open'" fi @@ -78,7 +84,18 @@ pkgctl_repo_web() { fi for pkgbase in "${pkgbases[@]}"; do + pkgbase=$(basename "${pkgbase}") path=$(gitlab_project_name_to_path "${pkgbase}") - xdg-open "${GIT_PACKAGING_URL_HTTPS}/${path}" + url="${GIT_PACKAGING_URL_HTTPS}/${path}" + case ${mode} in + open) + xdg-open "${url}" + ;; + print) + printf "%s\n" "${url}" + ;; + *) + die "Unknown mode: ${mode}" + esac done } -- cgit v1.2.3-70-g09d2 From 4425913e4f3bfd3cb346c38e13a10f0002615a55 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Thu, 21 Dec 2023 21:40:57 +0100 Subject: chore(build): use more intuitive update-checksums option for humans The philosophy of our CLI is to provide options that better match human expectations in an intuitive way rather than mimic wording of previous tools with abbreviation. Component: pkgctl build Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 2 +- contrib/completion/zsh/_devtools.in | 2 +- doc/man/pkgctl-build.1.asciidoc | 8 ++++++-- src/lib/build/build.sh | 12 ++++++------ 4 files changed, 14 insertions(+), 10 deletions(-) (limited to 'contrib/completion/bash/devtools.in') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index 83264ce..b974257 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -179,7 +179,7 @@ _pkgctl_build_args=( --pkgver --pkgrel --rebuild - --updpkgsums + --update-checksums -e --edit -r --release diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index b82ece4..35ab2dc 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -50,7 +50,7 @@ _pkgctl_build_args=( '--pkgver=[Set pkgver, reset pkgrel and update checksums]:pkgver:' '--pkgrel=[Set pkgrel to a given value]:pkgrel:' '--rebuild[Increment the pkgrel variable]' - '--updpkgsums[Regenerate the checksums]' + '--update-checksums[Force computation and update of the checksums (disables auto-detection)]' '(-e --edit)'{-e,--edit}'[Edit the PKGBUILD before building]' '(-r --release)'{-r,--release}'[Automatically commit, tag and release after building]' '(-m --message=)'{-m,--message=}"[Use the given as the commit message]:message:" diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc index 3f2d44e..12deaaa 100644 --- a/doc/man/pkgctl-build.1.asciidoc +++ b/doc/man/pkgctl-build.1.asciidoc @@ -63,8 +63,12 @@ PKGBUILD Options *--rebuild*:: Increment the current pkgrel variable -*--updpkgsums*:: - Regenerate the checksums +*--update-checksums*:: + Force computation and update of the checksums by disabling auto-detection. + + Should only be used in special circumstances, like when adding new patch + files to the source array. During regular packaging operations, checksums + are either automatically updated when upgrading a package using `--pkgver` + or should remain immutable during rebuilds. *-e, --edit*:: Edit the PKGBUILD before building diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index 2b9d4cf..e0982e4 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -58,7 +58,7 @@ pkgctl_build_usage() { --pkgver=PKGVER Set pkgver, reset pkgrel and update checksums --pkgrel=PKGREL Set pkgrel to a given value --rebuild Increment the current pkgrel variable - --updpkgsums Regenerate the checksums + --update-checksums Force computation and update of the checksums (disables auto-detection) -e, --edit Edit the PKGBUILD before building RELEASE OPTIONS @@ -108,7 +108,7 @@ pkgctl_build() { exit 1 fi - local UPDPKGSUMS=0 + local UPDATE_CHECKSUMS=0 local EDIT=0 local REBUILD=0 local OFFLOAD=0 @@ -165,7 +165,7 @@ pkgctl_build() { pkgctl_build_check_option_group_ver '--pkgver' "${PKGVER}" "${PKGREL}" "${REBUILD}" PKGVER="${1#*=}" PKGREL=1 - UPDPKGSUMS=1 + UPDATE_CHECKSUMS=1 shift ;; --pkgrel=*) @@ -173,8 +173,8 @@ pkgctl_build() { PKGREL="${1#*=}" shift ;; - --updpkgsums) - UPDPKGSUMS=1 + --update-checksums) + UPDATE_CHECKSUMS=1 shift ;; --rebuild) @@ -407,7 +407,7 @@ pkgctl_build() { # update checksums if any sources are declared - if (( UPDPKGSUMS )) && (( ${#source[@]} >= 1 )); then + if (( UPDATE_CHECKSUMS )) && (( ${#source[@]} >= 1 )); then updpkgsums fi -- cgit v1.2.3-70-g09d2 From 4673ad6c89bbdca632b22edfc2ef35486b7a635b Mon Sep 17 00:00:00 2001 From: Jelle van der Waa Date: Sat, 1 Jul 2023 15:21:32 +0200 Subject: feat(search): add subcommand to search across the packaging group Search for an expression across the GitLab packaging group. To use a filter, include it in your query. You may use wildcards (*) to use glob matching. Available filters for the blobs scope: path, extension. Every usage of the search command must be authenticated. Consult the 'pkgctl auth' command to authenticate with GitLab or view the authentication status. This command uses bats for pretty printing the results including line numbers and syntax highlighting. Component: pkgctl search Co-authored-by: Christian Heusel Co-authored-by: Levente Polyak --- README.md | 1 + contrib/completion/bash/devtools.in | 9 ++ contrib/completion/zsh/_devtools.in | 8 ++ doc/man/pkgctl-search.1.asciidoc | 58 ++++++++++ doc/man/pkgctl.1.asciidoc | 4 + src/lib/api/gitlab.sh | 174 ++++++++++++++++++++++++++-- src/lib/cache.sh | 22 ++++ src/lib/search.sh | 221 ++++++++++++++++++++++++++++++++++++ src/pkgctl.in | 9 ++ 9 files changed, 499 insertions(+), 7 deletions(-) create mode 100644 doc/man/pkgctl-search.1.asciidoc create mode 100644 src/lib/cache.sh create mode 100644 src/lib/search.sh (limited to 'contrib/completion/bash/devtools.in') diff --git a/README.md b/README.md index a1b6d42..6c36a37 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ Component: pkgctl db remove - arch-install-scripts - awk - bash +- bats - binutils - coreutils - diffutils diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index b974257..155bb7e 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -139,6 +139,7 @@ _pkgctl_cmds=( diff release repo + search version ) _pkgctl_args=( @@ -331,6 +332,14 @@ _pkgctl_repo_web_args=( _pkgctl_repo_web_opts() { _filedir -d; } +_pkgctl_search_args=( + --json + --no-default-filter + -h --help +) +_pkgctl_search_opts() { :; } + + _pkgctl_diff_args=( -l --list -d --diffoscope diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 35ab2dc..120b47a 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -139,6 +139,13 @@ _pkgctl_repo_web_args=( '*:git_dir:_files -/' ) +_pkgctl_search_args=( + '--json[Enable printing results in JSON]' + '--no-default-filter[Do not apply default filter (like -path:keys/pgp/*.asc)]' + '(-h --help)'{-h,--help}'[Display usage]' + '1:query' +) + _arch_nspawn_args=( '-C[Location of a pacman config file]:pacman_config:_files -g "*.conf(.)"' '-M[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"' @@ -252,6 +259,7 @@ _pkgctl_cmds=( "diff[Compare package files using different modes]" "release[Release step to commit, tag and upload build artifacts]" "repo[Manage Git packaging repositories and their configuration]" + "search[Search for an expression across the GitLab packaging group]" "version[Show pkgctl version information]" ) diff --git a/doc/man/pkgctl-search.1.asciidoc b/doc/man/pkgctl-search.1.asciidoc new file mode 100644 index 0000000..fb79b88 --- /dev/null +++ b/doc/man/pkgctl-search.1.asciidoc @@ -0,0 +1,58 @@ +pkgctl-search(1) +================ + +Name +---- +pkgctl-search - Search for an expression across the GitLab packaging group + +Synopsis +-------- +pkgctl search [OPTIONS] QUERY + +Description +----------- + +Search for an expression across the GitLab packaging group. + +To use a filter, include it in your query. You may use wildcards (*) to +use glob matching. + +Available filters for the blobs scope: path, extension + +Every usage of the search command must be authenticated. Consult the +'pkgctl auth' command to authenticate with GitLab or view the authentication +status. + +Search Tips +----------- + + Syntax Description Example + ─────────────────────────────────────── + " Exact search "gem sidekiq" + ~ Fuzzy search J~ Doe + | Or display | banner + + And display +banner + - Exclude display -banner + * Partial bug error 50* + \ Escape \*md + # Issue ID #23456 + ! Merge request !23456 + +Options +------- + +*--json*:: + Enable printing results in JSON + +*--no-default-filter*:: + Do not apply default filter (like -path:keys/pgp/*.asc) + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-auth[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index 74edf68..1164561 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -44,6 +44,9 @@ pkgctl release:: pkgctl repo:: Manage Git packaging repositories and their configuration +pkgctl search:: + Search for an expression across the GitLab packaging group + pkgctl version:: Show pkgctl version information @@ -56,6 +59,7 @@ linkman:pkgctl-db[1] linkman:pkgctl-diff[1] linkman:pkgctl-release[1] linkman:pkgctl-repo[1] +linkman:pkgctl-search[1] linkman:pkgctl-version[1] include::include/footer.asciidoc[] diff --git a/src/lib/api/gitlab.sh b/src/lib/api/gitlab.sh index e5f4237..e4b8a9d 100644 --- a/src/lib/api/gitlab.sh +++ b/src/lib/api/gitlab.sh @@ -13,13 +13,63 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/config.sh set -e +graphql_api_call() { + local outfile=$1 + local request=$2 + local node_type=$3 + local data=$4 + local hasNextPage cursor + + # empty token + if [[ -z "${GITLAB_TOKEN}" ]]; then + msg_error " api call failed: No token provided" + return 1 + fi + + [[ -z ${WORKDIR:-} ]] && setup_workdir + api_workdir=$(mktemp --tmpdir="${WORKDIR}" --directory pkgctl-gitlab-api.XXXXXXXXXX) + + # normalize graphql data and prepare query + data="${data//\"/\\\"}" + data='{ + "query": "'"${data}"'" + }' + data="${data//$'\t'/ }" + data="${data//$'\n'/}" + + cursor="" + hasNextPage=true + while [[ ${hasNextPage} == true ]]; do + data=$(sed -E 's|after: \\"[a-zA-Z0-9]*\\"|after: \\"'"${cursor}"'\\"|' <<< "${data}") + result="${api_workdir}/result.${cursor}" + + if ! curl --request "${request}" \ + --url "https://${GITLAB_HOST}/api/graphql" \ + --header "Authorization: Bearer ${GITLAB_TOKEN}" \ + --header "Content-Type: application/json" \ + --data "${data}" \ + --output "${result}" \ + --silent; then + msg_error " api call failed: $(cat "${outfile}")" + return 1 + fi + + hasNextPage=$(jq --raw-output ".data | .${node_type} | .pageInfo | .hasNextPage" < "${result}") + cursor=$(jq --raw-output ".data | .${node_type} | .pageInfo | .endCursor" < "${result}") + + cp "${result}" "${api_workdir}/tmp" + jq ".data.${node_type}.nodes" "${api_workdir}/tmp" > "${result}" + done + + jq --slurp add "${api_workdir}"/result.* > "${outfile}" + return 0 +} gitlab_api_call() { local outfile=$1 local request=$2 local endpoint=$3 local data=${4:-} - local error # empty token if [[ -z "${GITLAB_TOKEN}" ]]; then @@ -38,27 +88,102 @@ gitlab_api_call() { return 1 fi + if ! gitlab_check_api_errors "${outfile}"; then + return 1 + fi + + return 0 +} + +gitlab_api_call_paged() { + local outfile=$1 + local request=$2 + local endpoint=$3 + local data=${4:-} + local result header + + # empty token + if [[ -z "${GITLAB_TOKEN}" ]]; then + msg_error " api call failed: No token provided" + return 1 + fi + + [[ -z ${WORKDIR:-} ]] && setup_workdir + api_workdir=$(mktemp --tmpdir="${WORKDIR}" --directory pkgctl-gitlab-api.XXXXXXXXXX) + + next_page=1 + while [[ -n "${next_page}" ]]; do + result="${api_workdir}/result.${next_page}" + header="${api_workdir}/header" + if ! curl --request "${request}" \ + --get \ + --url "https://${GITLAB_HOST}/api/v4/${endpoint}&per_page=100&page=${next_page}" \ + --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \ + --header "Content-Type: application/json" \ + --data-urlencode "${data}" \ + --dump-header "${header}" \ + --output "${result}" \ + --silent; then + msg_error " api call failed: $(cat "${result}")" + return 1 + fi + + if ! gitlab_check_api_errors "${result}"; then + return 1 + fi + + next_page=$(grep "x-next-page" "${header}" | tr -d '\r' | awk '{ print $2 }') + done + + jq --slurp add "${api_workdir}"/result.* > "${outfile}" + return 0 +} + +gitlab_check_api_errors() { + local file=$1 + local error + + # search API only returns an array, no errors + if [[ $(jq --raw-output 'type' < "${file}") == "array" ]]; then + return 0 + fi + # check for general purpose api error - if error=$(jq --raw-output --exit-status '.error' < "${outfile}"); then + if error=$(jq --raw-output --exit-status '.error' < "${file}"); then msg_error " api call failed: ${error}" return 1 fi # check for api specific error messages - if ! jq --raw-output --exit-status '.id' < "${outfile}" >/dev/null; then - if jq --raw-output --exit-status '.message | keys[]' < "${outfile}" &>/dev/null; then + if ! jq --raw-output --exit-status '.id' < "${file}" >/dev/null; then + if jq --raw-output --exit-status '.message | keys[]' < "${file}" &>/dev/null; then while read -r error; do msg_error " api call failed: ${error}" - done < <(jq --raw-output --exit-status '.message|to_entries|map("\(.key) \(.value[])")[]' < "${outfile}") - elif error=$(jq --raw-output --exit-status '.message' < "${outfile}"); then + done < <(jq --raw-output --exit-status '.message|to_entries|map("\(.key) \(.value[])")[]' < "${file}") + elif error=$(jq --raw-output --exit-status '.message' < "${file}"); then msg_error " api call failed: ${error}" fi return 1 fi - return 0 } +graphql_check_api_errors() { + local file=$1 + local error + + # early exit if we do not have errors + if ! jq --raw-output --exit-status '.errors[]' < "${file}" &>/dev/null; then + return 0 + fi + + # check for api specific error messages + while read -r error; do + msg_error " api call failed: ${error}" + done < <(jq --raw-output --exit-status '.errors[].message' < "${file}") + return 1 +} + gitlab_api_get_user() { local outfile username @@ -81,6 +206,23 @@ gitlab_api_get_user() { return 0 } +gitlab_api_get_project_name_mapping() { + local query=$1 + local outfile + + [[ -z ${WORKDIR:-} ]] && setup_workdir + outfile=$(mktemp --tmpdir="${WORKDIR}" pkgctl-gitlab-api.XXXXXXXXXX) + + # query user details + if ! graphql_api_call "${outfile}" POST projects "${query}"; then + msg_warn " Invalid token provided?" + exit 1 + fi + + cat "${outfile}" + return 0 +} + # Convert arbitrary project names to GitLab valid path names. # # GitLab has several limitations on project and group names and also maintains @@ -130,3 +272,21 @@ gitlab_api_create_project() { printf "%s" "${path}" return 0 } + +# TODO: parallelize +# https://docs.gitlab.com/ee/api/search.html#scope-blobs +gitlab_api_search() { + local search=$1 + local outfile + + [[ -z ${WORKDIR:-} ]] && setup_workdir + outfile=$(mktemp --tmpdir="${WORKDIR}" pkgctl-gitlab-api.XXXXXXXXXX) + + if ! gitlab_api_call_paged "${outfile}" GET "/groups/archlinux%2fpackaging%2fpackages/search?scope=blobs" "search=${search}"; then + return 1 + fi + + cat "${outfile}" + + return 0 +} diff --git a/src/lib/cache.sh b/src/lib/cache.sh new file mode 100644 index 0000000..24056fa --- /dev/null +++ b/src/lib/cache.sh @@ -0,0 +1,22 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_CACHE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_CACHE_SH=1 + +set -e + +readonly XDG_DEVTOOLS_CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/devtools" + +get_cache_file() { + local filename=$1 + local path="${XDG_DEVTOOLS_CACHE_DIR}/${filename}" + + mkdir --parents -- "$(dirname -- "$path")" + if [[ ! -f ${path} ]]; then + touch -- "${path}" + fi + + printf '%s' "${path}" +} diff --git a/src/lib/search.sh b/src/lib/search.sh new file mode 100644 index 0000000..cf64db3 --- /dev/null +++ b/src/lib/search.sh @@ -0,0 +1,221 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_SEARCH_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_SEARCH_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/cache.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/cache.sh +# shellcheck source=src/lib/api/gitlab.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/api/gitlab.sh + +source /usr/share/makepkg/util/message.sh + +set -eo pipefail + + +pkgctl_search_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] QUERY + + Search for an expression across the GitLab packaging group. + + To use a filter, include it in your query. You may use wildcards (*) to + use glob matching. + + Available filters for the blobs scope: path, extension + + Every usage of the search command must be authenticated. Consult the + 'pkgctl auth' command to authenticate with GitLab or view the + authentication status. + + SEARCH TIPS + Syntax Description Example + ─────────────────────────────────────── + " Exact search "gem sidekiq" + ~ Fuzzy search J~ Doe + | Or display | banner + + And display +banner + - Exclude display -banner + * Partial bug error 50* + \\ Escape \\*md + # Issue ID #23456 + ! Merge request !23456 + + OPTIONS + --json Enable printing results in JSON + --no-default-filter Do not apply default filter (like -path:keys/pgp/*.asc) + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} linux + $ ${COMMAND} '"pytest -v" +PYTHONPATH' +_EOF_ +} + +pkgctl_search() { + if (( $# < 1 )); then + pkgctl_search_usage + exit 0 + fi + + # options + local search + local formatter=pretty + local use_default_filter=1 + + # variables + local default_filter="-path:keys/pgp/*.asc" + local graphql_lookup_batch=200 + local output result query entries from until length + local project_name_cache_file project_name_lookup project_ids project_id project_name project_slice + local mapping_output path startline data + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_search_usage + exit 0 + ;; + --json) + formatter=json + shift + ;; + --no-default-filter) + use_default_filter=0 + shift + ;; + --) + shift + break + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + break + ;; + esac + done + + if (( $# == 0 )); then + pkgctl_search_usage + exit 1 + fi + + # assign search parameter + search="${*}" + if (( use_default_filter )); then + search+=" ${default_filter}" + fi + + stat_busy "Querying gitlab search api" + output=$(gitlab_api_search "${search}") + stat_done + + project_name_cache_file=$(get_cache_file gitlab/project_id_to_name) + lock 11 "${project_name_cache_file}" "Locking project name cache" + mapfile -t project_ids < <( + jq --raw-output '[.[].project_id] | unique[]' <<< "${output}" | \ + grep --invert-match --file <(awk '{ print $1 }' < "${project_name_cache_file}" )) + + stat_busy "Querying project names" + local entries="${#project_ids[@]}" + local until=0 + while (( until < entries )); do + from=${until} + until=$(( until + graphql_lookup_batch )) + if (( until > entries )); then + until=${entries} + fi + length=$(( until - from )) + + project_slice=("${project_ids[@]:${from}:${length}}") + printf -v projects '"gid://gitlab/Project/%s",' "${project_slice[@]}" + query='{ + projects(after: "" ids: ['"${projects}"']) { + pageInfo { + startCursor + endCursor + hasNextPage + } + nodes { + id + name + } + } + }' + mapping_output=$(gitlab_api_get_project_name_mapping "${query}") + + # update cache + while read -r project_id project_name; do + printf "%s %s\n" "${project_id}" "${project_name}" >> "${project_name_cache_file}" + done < <(jq --raw-output \ + '.[] | "\(.id | rindex("/") as $lastSlash | .[$lastSlash+1:]) \(.name)"' \ + <<< "${mapping_output}") + done + stat_done + + # read project_id to name mapping from cache + declare -A project_name_lookup=() + while read -r project_id project_name; do + project_name_lookup[${project_id}]=${project_name} + done < "${project_name_cache_file}" + + # close project name cache lock + lock_close 11 + + # output mode JSON + if [[ ${formatter} == json ]]; then + jq --from-file <( + for project_id in $(jq '.[].project_id' <<< "${output}"); do + project_name=${project_name_lookup[${project_id}]} + printf 'map(if .project_id == %s then . + {"project_name": "%s"} else . end) | ' \ + "${project_id}" "${project_name}" + done + printf . + ) <<< "${output}" + exit 0 + fi + + # pretty print each result + while read -r result; do + # read properties from search result + mapfile -t data < <(jq --raw-output ".data" <<< "${result}") + { read -r project_id; read -r path; read -r startline; } < <( + jq --raw-output ".project_id, .path, .startline" <<< "${result}" + ) + project_name=${project_name_lookup[${project_id}]} + + # remove trailing newline for multiline results + if (( ${#data[@]} > 1 )) && [[ ${data[-1]} == "" ]]; then + unset "data[${#data[@]}-1]" + fi + + # prepend empty lines to match startline + if (( startline > 1 )); then + mapfile -t data < <( + printf '%.0s\n' $(seq 1 "$(( startline - 1 ))") + printf "%s\n" "${data[@]}" + ) + fi + + bat \ + --file-name="${project_name}/${path}" \ + --line-range "${startline}:" \ + --paging=never \ + --force-colorization \ + --map-syntax "PKGBUILD:Bourne Again Shell (bash)" \ + --map-syntax ".SRCINFO:INI" \ + --map-syntax "*install:Bourne Again Shell (bash)" \ + --map-syntax "*sysusers*:Bourne Again Shell (bash)" \ + --map-syntax "*tmpfiles*:Bourne Again Shell (bash)" \ + --map-syntax "*.hook:INI" \ + <(printf "%s\n" "${data[@]}") + done < <(jq --compact-output '.[]' <<< "${output}") +} diff --git a/src/pkgctl.in b/src/pkgctl.in index ad215ac..10a2348 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -25,6 +25,7 @@ usage() { diff Compare package files using different modes release Release step to commit, tag and upload build artifacts repo Manage Git packaging repositories and their configuration + search Search for an expression across the GitLab packaging group version Show pkgctl version information OPTIONS @@ -96,6 +97,14 @@ while (( $# )); do pkgctl_release "$@" exit 0 ;; + search) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/release.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/search.sh + pkgctl_search "$@" + exit 0 + ;; version|--version|-V) _DEVTOOLS_COMMAND+=" $1" shift -- cgit v1.2.3-70-g09d2 From d0dc0e1a32d6ed9b166eca777f7fb7071c4c2df1 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Fri, 5 Jan 2024 19:23:52 +0100 Subject: feat(search): add optional plain output formatting This allows to run the search command without bats, which is not used in the default pretty output format. Component: pkgctl search Signed-off-by: Levente Polyak --- README.md | 5 +- contrib/completion/bash/devtools.in | 11 ++++- contrib/completion/zsh/_devtools.in | 6 ++- doc/man/pkgctl-search.1.asciidoc | 23 +++++++-- src/lib/common.sh | 4 +- src/lib/search.sh | 93 +++++++++++++++++++++++++++++++++---- src/lib/valid-search.sh | 11 +++++ 7 files changed, 134 insertions(+), 19 deletions(-) create mode 100644 src/lib/valid-search.sh (limited to 'contrib/completion/bash/devtools.in') diff --git a/README.md b/README.md index 6c36a37..ca761db 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,6 @@ Component: pkgctl db remove - arch-install-scripts - awk - bash -- bats - binutils - coreutils - diffutils @@ -87,6 +86,10 @@ Component: pkgctl db remove - mercurial - subversion +### Optional Dependencies + +- bats (pretty printing) + ### Development Dependencies - asciidoc diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index 155bb7e..4c7b73a 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -9,6 +9,8 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh # shellcheck source=src/lib/valid-inspect.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh +# shellcheck source=src/lib/valid-search.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-search.sh _binary_arch=${DEVTOOLS_VALID_ARCHES[*]:0:-1} _colors=(never always auto) @@ -333,11 +335,15 @@ _pkgctl_repo_web_opts() { _filedir -d; } _pkgctl_search_args=( - --json --no-default-filter + --json + -F --format + -N --no-line-number -h --help ) _pkgctl_search_opts() { :; } +_pkgctl_search_args__format_opts() { _devtools_completions_search_format; } +_pkgctl_search_args_F_opts() { _devtools_completions_search_format; } _pkgctl_diff_args=( @@ -391,6 +397,9 @@ _devtools_completions_protocol() { _devtools_completions_inspect() { mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_INSPECT_MODES[*]}" -- "$cur") } +_devtools_completions_search_format() { + mapfile -t COMPREPLY < <(compgen -W "${valid_search_output_format[*]}" -- "$cur") +} __devtools_complete() { local service=$1 diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 120b47a..448fbed 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -9,6 +9,8 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh # shellcheck source=src/lib/valid-inspect.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh +# shellcheck source=src/lib/valid-search.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-search.sh _binary_arch=${DEVTOOLS_VALID_ARCHES[*]:0:-1} _colors=(never always auto) @@ -140,8 +142,10 @@ _pkgctl_repo_web_args=( ) _pkgctl_search_args=( - '--json[Enable printing results in JSON]' '--no-default-filter[Do not apply default filter (like -path:keys/pgp/*.asc)]' + '--json[Enable printing results in JSON]' + '(-F --format)'{-F,--format}"[Controls the formatting of the results]:format:($valid_search_output_format[*])" + '(-N --no-line-number)'{-N,--no-line-number}"[Don't show line numbers when formatting results]" '(-h --help)'{-h,--help}'[Display usage]' '1:query' ) diff --git a/doc/man/pkgctl-search.1.asciidoc b/doc/man/pkgctl-search.1.asciidoc index fb79b88..8172b00 100644 --- a/doc/man/pkgctl-search.1.asciidoc +++ b/doc/man/pkgctl-search.1.asciidoc @@ -20,7 +20,7 @@ use glob matching. Available filters for the blobs scope: path, extension Every usage of the search command must be authenticated. Consult the -'pkgctl auth' command to authenticate with GitLab or view the authentication +`'pkgctl auth'` command to authenticate with GitLab or view the authentication status. Search Tips @@ -41,14 +41,27 @@ Search Tips Options ------- -*--json*:: - Enable printing results in JSON +*-h, --help*:: + Show a help text + +Filter Options +-------------- *--no-default-filter*:: Do not apply default filter (like -path:keys/pgp/*.asc) -*-h, --help*:: - Show a help text +Output Options +-------------- + +*--json*:: + Enable printing in JSON; Shorthand for `'--format json'` + +*-F, --format* 'FORMAT':: + Controls the formatting of the results; `FORMAT` is `'pretty'`, `'plain'`, + or `'json'` (default `pretty`) + +*-N, --no-line-number*:: + Don't show line numbers when formatting results See Also -------- diff --git a/src/lib/common.sh b/src/lib/common.sh index 29b0343..17b91bc 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -33,9 +33,11 @@ export PKGBASE_MAINTAINER_URL=https://archlinux.org/packages/pkgbase-maintainer # check if messages are to be printed using color if [[ -t 2 && "$TERM" != dumb ]] || [[ ${DEVTOOLS_COLOR} == always ]]; then colorize + PURPLE="$(tput setaf 5)" + DARK_GREEN="$(tput setaf 2)" else # shellcheck disable=2034 - declare -gr ALL_OFF='' BOLD='' BLUE='' GREEN='' RED='' YELLOW='' + declare -gr ALL_OFF='' BOLD='' BLUE='' GREEN='' RED='' YELLOW='' PURPLE='' fi stat_busy() { diff --git a/src/lib/search.sh b/src/lib/search.sh index cf64db3..862af25 100644 --- a/src/lib/search.sh +++ b/src/lib/search.sh @@ -12,7 +12,10 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/cache.sh # shellcheck source=src/lib/api/gitlab.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/api/gitlab.sh +# shellcheck source=src/lib/valid-search.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-search.sh +source /usr/share/makepkg/util/util.sh source /usr/share/makepkg/util/message.sh set -eo pipefail @@ -48,16 +51,33 @@ pkgctl_search_usage() { ! Merge request !23456 OPTIONS - --json Enable printing results in JSON - --no-default-filter Do not apply default filter (like -path:keys/pgp/*.asc) - -h, --help Show this help text + -h, --help Show this help text + + FILTER OPTIONS + --no-default-filter Do not apply default filter (like -path:keys/pgp/*.asc) + + OUTPUT OPTIONS + --json Enable printing in JSON; Shorthand for '--format json' + -F, --format FORMAT Controls the formatting of the results; FORMAT is 'pretty', + 'plain', or 'json' (default: pretty) + -N, --no-line-number Don't show line numbers when formatting results EXAMPLES $ ${COMMAND} linux - $ ${COMMAND} '"pytest -v" +PYTHONPATH' + $ ${COMMAND} --json '"pytest -v" +PYTHONPATH' _EOF_ } +pkgctl_search_check_option_group_format() { + local option=$1 + local output_format=$2 + if [[ -n ${output_format} ]]; then + die "The argument '%s' cannot be used with one or more of the other specified arguments" "${option}" + exit 1 + fi + return 0 +} + pkgctl_search() { if (( $# < 1 )); then pkgctl_search_usage @@ -66,15 +86,17 @@ pkgctl_search() { # options local search - local formatter=pretty + local output_format= local use_default_filter=1 + local line_numbers=1 # variables + local bats_style="header,grid" local default_filter="-path:keys/pgp/*.asc" local graphql_lookup_batch=200 local output result query entries from until length local project_name_cache_file project_name_lookup project_ids project_id project_name project_slice - local mapping_output path startline data + local mapping_output path startline currentline data line while (( $# )); do case $1 in @@ -82,12 +104,26 @@ pkgctl_search() { pkgctl_search_usage exit 0 ;; + --no-default-filter) + use_default_filter=0 + shift + ;; --json) - formatter=json + pkgctl_search_check_option_group_format "$1" "${output_format}" + output_format=json shift ;; - --no-default-filter) - use_default_filter=0 + -F|--format) + (( $# <= 1 )) && die "missing argument for %s" "$1" + pkgctl_search_check_option_group_format "$1" "${output_format}" + output_format="${2}" + if ! in_array "${output_format}" "${valid_search_output_format[@]}"; then + die "Unknown output format: %s" "${output_format}" + fi + shift 2 + ;; + -N|--no-line-number) + line_numbers=0 shift ;; --) @@ -114,16 +150,35 @@ pkgctl_search() { search+=" ${default_filter}" fi + # assign default output format + if [[ -z ${output_format} ]]; then + output_format=pretty + fi + + # check for optional dependencies + if [[ ${output_format} == pretty ]] && ! command -v bats &>/dev/null; then + warning "Failed to find optional dependency 'bats': falling back to plain output" + output_format=plain + fi + + # populate line numbers option + if (( line_numbers )); then + bats_style="numbers,${bats_style}" + fi + + # call the gitlab search API stat_busy "Querying gitlab search api" output=$(gitlab_api_search "${search}") stat_done + # collect project ids whose name needs to be looked up project_name_cache_file=$(get_cache_file gitlab/project_id_to_name) lock 11 "${project_name_cache_file}" "Locking project name cache" mapfile -t project_ids < <( jq --raw-output '[.[].project_id] | unique[]' <<< "${output}" | \ grep --invert-match --file <(awk '{ print $1 }' < "${project_name_cache_file}" )) + # look up project names stat_busy "Querying project names" local entries="${#project_ids[@]}" local until=0 @@ -171,7 +226,7 @@ pkgctl_search() { lock_close 11 # output mode JSON - if [[ ${formatter} == json ]]; then + if [[ ${output_format} == json ]]; then jq --from-file <( for project_id in $(jq '.[].project_id' <<< "${output}"); do project_name=${project_name_lookup[${project_id}]} @@ -197,6 +252,23 @@ pkgctl_search() { unset "data[${#data[@]}-1]" fi + # output mode plain + if [[ ${output_format} == plain ]]; then + printf "%s%s%s\n" "${PURPLE}" "${project_name}/${path}" "${ALL_OFF}" + + currentline=${startline} + for line in "${data[@]}"; do + if (( line_numbers )); then + line="${DARK_GREEN}${currentline}${ALL_OFF}: ${line}" + currentline=$(( currentline + 1 )) + fi + printf "%s\n" "${line}" + done + printf "\n" + + continue + fi + # prepend empty lines to match startline if (( startline > 1 )); then mapfile -t data < <( @@ -210,6 +282,7 @@ pkgctl_search() { --line-range "${startline}:" \ --paging=never \ --force-colorization \ + --style "${bats_style}" \ --map-syntax "PKGBUILD:Bourne Again Shell (bash)" \ --map-syntax ".SRCINFO:INI" \ --map-syntax "*install:Bourne Again Shell (bash)" \ diff --git a/src/lib/valid-search.sh b/src/lib/valid-search.sh new file mode 100644 index 0000000..43799a5 --- /dev/null +++ b/src/lib/valid-search.sh @@ -0,0 +1,11 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later +: + +# shellcheck disable=2034 +valid_search_output_format=( + pretty + plain + json +) -- cgit v1.2.3-70-g09d2 From 2b8033b91132d303603f370a54eef02949703750 Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Thu, 8 Jun 2023 14:47:29 +0200 Subject: feat(aur): add subcommand to drop a package from the repos to the AUR Add an aur command to interact with the Arch User Repository including the drop-from-repo subommand which allows to drop packages from the official repository to the Arch User Repository in one go. Related to #143 Component: pkgctl aur drop-from-repo Co-authored-by: Levente Polyak Signed-off-by: Christian Heusel --- contrib/completion/bash/devtools.in | 13 ++- contrib/completion/zsh/_devtools.in | 13 +++ doc/man/pkgctl-aur-drop-from-repo.1.asciidoc | 41 +++++++ doc/man/pkgctl-aur.1.asciidoc | 37 ++++++ doc/man/pkgctl.1.asciidoc | 4 + src/lib/aur.sh | 65 +++++++++++ src/lib/aur/drop-from-repo.sh | 166 +++++++++++++++++++++++++++ src/lib/common.sh | 1 + src/pkgctl.in | 9 ++ 9 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 doc/man/pkgctl-aur-drop-from-repo.1.asciidoc create mode 100644 doc/man/pkgctl-aur.1.asciidoc create mode 100644 src/lib/aur.sh create mode 100644 src/lib/aur/drop-from-repo.sh (limited to 'contrib/completion/bash/devtools.in') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index 4c7b73a..1fbd46c 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -135,6 +135,7 @@ complete -F _offload_build offload-build _pkgctl_cmds=( + aur auth build db @@ -264,6 +265,17 @@ _pkgctl_release_args__repo_opts() { _devtools_completions_repo; } _pkgctl_release_args_r_opts() { _pkgctl_release_args__repo_opts; } _pkgctl_release_opts() { _filedir -d; } +_pkgctl_aur_cmds=( + drop-from-repo +) + +_pkgctl_aur_drop_from_repo_args=( + --no-disown + -f --force + -h --help +) +_pkgctl_aur_drop_from_repo_opts() { _filedir -d; } + _pkgctl_repo_cmds=( clone @@ -308,7 +320,6 @@ _pkgctl_repo_create_args=( -h --help ) - _pkgctl_repo_switch_args=( --discard-changes -f --force diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index b316346..5b51aff 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -96,6 +96,18 @@ _pkgctl_release_args=( '*:git_dir:_files -/' ) +_pkgctl_aur_cmds=( + "pkgctl aur command" + "drop-from-repo[Drop a package from the official repository to the AUR]" +) + +_pkgctl_aur_drop_from_repo_args=( + '(-f --force)'{-f,--force}'[Force push to the AUR overwriting the remote repository]' + '--no-disown[Do not disown the package on the AUR]' + '(-h --help)'{-h,--help}'[Display usage]' + '*:git_dir:_files -/' +) + _pkgctl_repo_cmds=( "pkgctl repo command" "clone[Clone a package repository]" @@ -257,6 +269,7 @@ _devtools_completions_all_packages() { _pkgctl_cmds=( "pkgctl command" + "aur[Interact with the Arch User Repository (AUR)]" "auth[Authenticate with services like GitLab]" "build[Build packages inside a clean chroot]" "db[Pacman database modification for package update, move etc]" diff --git a/doc/man/pkgctl-aur-drop-from-repo.1.asciidoc b/doc/man/pkgctl-aur-drop-from-repo.1.asciidoc new file mode 100644 index 0000000..a9d39c6 --- /dev/null +++ b/doc/man/pkgctl-aur-drop-from-repo.1.asciidoc @@ -0,0 +1,41 @@ +pkgctl-aur-drop-from-repo(1) +============================ + +Name +---- +pkgctl-aur-drop-from-repo - Drop a package from the official repository to the AUR + +Synopsis +-------- +pkgctl aur drop-from-repo [OPTIONS] [PATH]... + +Description +----------- + +Drops a specified package from the official repositories to the Arch User +Repository. + +This command requires a local Git clone of the package repository. It +reconfigures the repository for AUR compatibility and pushes it to the +AUR. Afterwards, the package is removed from the official repository. + +By default, the package is automatically disowned in the AUR. + +Options +------- + +*--no-disown*:: + Do not disown the package on the AUR + +*-f, --force*:: + Force push to the AUR overwriting the remote repository + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-db-remove[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-aur.1.asciidoc b/doc/man/pkgctl-aur.1.asciidoc new file mode 100644 index 0000000..d69124a --- /dev/null +++ b/doc/man/pkgctl-aur.1.asciidoc @@ -0,0 +1,37 @@ +pkgctl-aur(1) +============= + +Name +---- +pkgctl-aur - Interact with the Arch User Repository (AUR) + +Synopsis +-------- +pkgctl aur [OPTIONS] [SUBCOMMAND] + +Description +----------- + +Provides a suite of tools designed for managing and interacting with the Arch +User Repository (AUR). It simplifies various tasks related to AUR, including +importing repositories, managing packages, and transitioning packages between +the official repositories and the AUR. + +Options +------- + +*-h, --help*:: + Show a help text + +Subcommands +----------- + +pkgctl aur drop-from-repo:: + Drop a package from the official repository to the AUR + +See Also +-------- + +linkman:pkgctl-aur-drop-from-repo[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index 1164561..24b0613 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -26,6 +26,9 @@ Options Subcommands ----------- +pkgctl aur:: + Interact with the Arch User Repository + pkgctl auth:: Authenticate with services like GitLab @@ -53,6 +56,7 @@ pkgctl version:: See Also -------- +linkman:pkgctl-aur[1] linkman:pkgctl-auth[1] linkman:pkgctl-build[1] linkman:pkgctl-db[1] diff --git a/src/lib/aur.sh b/src/lib/aur.sh new file mode 100644 index 0000000..24cbb62 --- /dev/null +++ b/src/lib/aur.sh @@ -0,0 +1,65 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_AUR_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_AUR_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} + +set -eo pipefail + + +pkgctl_aur_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [COMMAND] [OPTIONS] + + Interact with the Arch User Repository (AUR). + + Provides a suite of tools designed for managing and interacting with the Arch + User Repository (AUR). It simplifies various tasks related to AUR, including + importing repositories, managing packages, and transitioning packages between + the official repositories and the AUR. + + COMMANDS + drop-from-repo Drop a package from the official repository to the AUR + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} drop-from-repo libfoo +_EOF_ +} + +pkgctl_aur() { + if (( $# < 1 )); then + pkgctl_aur_usage + exit 0 + fi + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_aur_usage + exit 0 + ;; + drop-from-repo) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/aur/drop-from-repo.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/aur/drop-from-repo.sh + pkgctl_aur_drop_from_repo "$@" + exit 0 + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + die "invalid command: %s" "$1" + ;; + esac + done +} diff --git a/src/lib/aur/drop-from-repo.sh b/src/lib/aur/drop-from-repo.sh new file mode 100644 index 0000000..d70b559 --- /dev/null +++ b/src/lib/aur/drop-from-repo.sh @@ -0,0 +1,166 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_AUR_DROP_FROM_REPO_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_AUR_DROP_FROM_REPO_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} + +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/db/remove.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/remove.sh +# shellcheck source=src//lib/util/pacman.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh + +source /usr/share/makepkg/util/message.sh + +set -eo pipefail + + +pkgctl_aur_drop_from_repo_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PATH]... + + Drops a specified package from the official repositories to the Arch + User Repository. + + This command requires a local Git clone of the package repository. It + reconfigures the repository for AUR compatibility and pushes it to the + AUR. Afterwards, the package is removed from the official repository. + + By default, the package is automatically disowned in the AUR. + + OPTIONS + --no-disown Do not disown the package on the AUR + -f, --force Force push to the AUR overwriting the remote repository + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} foo + $ ${COMMAND} --no-disown --force +_EOF_ +} + +pkgctl_aur_drop_from_repo() { + # options + local paths=() + local DISOWN=1 + local FORCE=0 + + # variables + local path realpath pkgbase pkgrepo remote_url + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_aur_drop_from_repo_usage + exit 0 + ;; + --no-disown) + DISOWN=0 + shift + ;; + -f|--force) + FORCE=1 + shift + ;; + --) + 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 + if [[ -f PKGBUILD ]]; then + paths=(".") + else + pkgctl_aur_drop_from_repo_usage + exit 1 + fi + fi + + for path in "${paths[@]}"; do + if ! realpath=$(realpath -e "${path}"); then + die "No such directory: ${path}" + fi + + pkgbase=$(basename "${realpath}") + pkgbase=${pkgbase%.git} + + if [[ ! -d "${path}/.git" ]]; then + die "Not a Git repository: ${path}" + fi + + pushd "${path}" >/dev/null + + if [[ ! -f PKGBUILD ]]; then + die 'PKGBUILD not found in %s' "${path}" + fi + + msg "Dropping ${pkgbase} to the AUR" + + remote_url="${AUR_URL_SSH}:${pkgbase}.git" + if ! git remote add origin "${remote_url}" &>/dev/null; then + git remote set-url origin "${remote_url}" + fi + + # move the main branch to master + if [[ $(git symbolic-ref --quiet --short HEAD) == main ]]; then + git branch --move master + git config branch.master.merge refs/heads/master + git remote set-head origin master + fi + + # auto generate .SRCINFO if not already present + if [[ -z "$(git ls-tree -r HEAD --name-only .SRCINFO)" ]]; then + stat_busy 'Generating .SRCINFO' + makepkg --printsrcinfo > .SRCINFO + stat_done + + git add --force -- .SRCINFO + git commit --quiet --message "Adding .SRCINFO" -- .SRCINFO + fi + + msg "Pushing ${pkgbase} to the AUR" + if (( FORCE )); then + AUR_OVERWRITE=1 \ + GIT_SSH_COMMAND="ssh -o SendEnv=AUR_OVERWRITE" \ + git push --force origin master + else + git push origin master + fi + + if (( DISOWN )); then + msg "Disowning ${pkgbase} on the AUR" + # shellcheck disable=SC2029 + ssh "${AUR_URL_SSH}" disown "${pkgbase}" + fi + + # auto-detection of the repo to remove from + if ! pkgrepo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then + die 'Failed to get pacman repo' + fi + + msg "Deleting ${pkgbase} from the official repository" + if [[ -z "${pkgrepo}" ]]; then + warning 'Did not find %s in any repository, please delete manually' "${pkgbase}" + else + msg2 " repo: ${pkgrepo}" + pkgctl_db_remove "${pkgrepo}" "${pkgbase}" + fi + + popd >/dev/null + done +} diff --git a/src/lib/common.sh b/src/lib/common.sh index 17b91bc..a93e906 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -29,6 +29,7 @@ export GIT_PACKAGING_URL_SSH="git@${GITLAB_HOST}:${GIT_PACKAGING_NAMESPACE}" export GIT_PACKAGING_URL_HTTPS="https://${GITLAB_HOST}/${GIT_PACKAGING_NAMESPACE}" export PACKAGING_REPO_RELEASE_HOST=repos.archlinux.org export PKGBASE_MAINTAINER_URL=https://archlinux.org/packages/pkgbase-maintainer +export AUR_URL_SSH=aur@aur.archlinux.org # check if messages are to be printed using color if [[ -t 2 && "$TERM" != dumb ]] || [[ ${DEVTOOLS_COLOR} == always ]]; then diff --git a/src/pkgctl.in b/src/pkgctl.in index 10a2348..070e0cd 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -19,6 +19,7 @@ usage() { Unified command-line frontend for devtools. COMMANDS + aur Interact with the Arch User Repository auth Authenticate with services like GitLab build Build packages inside a clean chroot db Pacman database modification for package update, move etc @@ -51,6 +52,14 @@ while (( $# )); do usage exit 0 ;; + aur) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/aur.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/aur.sh + pkgctl_aur "$@" + exit 0 + ;; build) _DEVTOOLS_COMMAND+=" $1" shift -- cgit v1.2.3-70-g09d2 From e6f7aa395fabc7eca1ee4d93e454d2551cea505c Mon Sep 17 00:00:00 2001 From: Jelle van der Waa Date: Sun, 5 Nov 2023 16:11:12 +0100 Subject: feat(version): introduce version check subcommand The version subcommand handles pkgver related commands, the first subcommand being `check`. Check runs nvchecker if a `.nvchecker.toml` file exists and compares the current pkgver with the latest release. Introduces nvchecker as optional dependency which has to be installed in order to use this particular subcommand. BREAKING CHANGE: formerly pkgctl version would output the version of the pkgctl tool, now it is used as a version related subcommand. Fixes #140 Component: pkgctl version Component: pkgctl version check Co-authored-by: Christian Heusel --- README.md | 1 + contrib/completion/bash/devtools.in | 9 +++ contrib/completion/zsh/_devtools.in | 10 +++- doc/man/pkgctl-version-check.1.asciidoc | 35 ++++++++++++ doc/man/pkgctl-version.1.asciidoc | 18 +++++- doc/man/pkgctl.1.asciidoc | 2 +- src/lib/version.sh | 56 +++++++++++++++++++ src/lib/version/check.sh | 97 +++++++++++++++++++++++++++++++++ src/lib/version/version.sh | 47 ---------------- src/pkgctl.in | 20 +++++-- 10 files changed, 238 insertions(+), 57 deletions(-) create mode 100644 doc/man/pkgctl-version-check.1.asciidoc create mode 100644 src/lib/version.sh create mode 100644 src/lib/version/check.sh delete mode 100644 src/lib/version/version.sh (limited to 'contrib/completion/bash/devtools.in') diff --git a/README.md b/README.md index ca761db..8b85bd9 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ Component: pkgctl db remove ### Optional Dependencies - bats (pretty printing) +- nvchecker (version checking) ### Development Dependencies diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index 1fbd46c..f1084ab 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -337,6 +337,15 @@ _pkgctl_repo_switch_opts() { fi } +_pkgctl_version_cmds=( + check +) + +_pkgctl_version_check_args=( + -h --help +) + +_pkgctl_version_check_opts() { _filedir -d; } _pkgctl_repo_web_args=( --print diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 5b51aff..575c327 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -277,7 +277,7 @@ _pkgctl_cmds=( "release[Release step to commit, tag and upload build artifacts]" "repo[Manage Git packaging repositories and their configuration]" "search[Search for an expression across the GitLab packaging group]" - "version[Show pkgctl version information]" + "version[Package version related commands]" ) _pkgctl_args=( @@ -285,8 +285,14 @@ _pkgctl_args=( '(-h --help)'{-h,--help}'[Display usage]' ) -_pkgctl_version_args=( +_pkgctl_version_cmds=( + "pkgctl version command" + "check[Check if there is an new upstream version available]" +) + +_pkgctl_version_check_args=( '(-h --help)'{-h,--help}'[Display usage]' + '*:git_dir:_files -/' ) _pkgctl_diff_args=("${_diffpkg_args[@]}") diff --git a/doc/man/pkgctl-version-check.1.asciidoc b/doc/man/pkgctl-version-check.1.asciidoc new file mode 100644 index 0000000..97d8c47 --- /dev/null +++ b/doc/man/pkgctl-version-check.1.asciidoc @@ -0,0 +1,35 @@ +pkgctl-version-check(1) +======================= + +Name +---- +pkgctl-version-check - Check if there is an new upstream version available + +Synopsis +-------- +pkgctl version check [OPTIONS] [PKGBASE...] + +Description +----------- + +Uses nvchecker, a .nvchecker.toml file and the version specified in the current +PKGBUILDs pkgver to check if there is a newer package version available to +which this package could possibly be upgraded. + +The current working directory is used if no PKGBASE is specified. + +See the section on configuration files in **nvchecker**(1) for possible options +which can be utilized in .nvchecker.toml. + +Options +------- + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:nvchecker[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-version.1.asciidoc b/doc/man/pkgctl-version.1.asciidoc index 9beebf5..53a72f3 100644 --- a/doc/man/pkgctl-version.1.asciidoc +++ b/doc/man/pkgctl-version.1.asciidoc @@ -3,16 +3,17 @@ pkgctl-version(1) Name ---- -pkgctl-version - Show pkgctl version information +pkgctl-version - Package version related commands. + Synopsis -------- -pkgctl version [OPTIONS] +pkgctl version [OPTIONS] [SUBCOMMAND] Description ----------- -Shows the current version information of pkgctl. +Package version related commands such as checking if a package is out of date. Options ------- @@ -20,4 +21,15 @@ Options *-h, --help*:: Show a help text +Subcommands +----------- + +pkgctl version check:: + Check if there is an new upstream version available + +See Also +-------- + +linkman:pkgctl-version-check[1] + include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index 24b0613..929ae9a 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -51,7 +51,7 @@ pkgctl search:: Search for an expression across the GitLab packaging group pkgctl version:: - Show pkgctl version information + Package version related commands See Also -------- diff --git a/src/lib/version.sh b/src/lib/version.sh new file mode 100644 index 0000000..826b306 --- /dev/null +++ b/src/lib/version.sh @@ -0,0 +1,56 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_VERSION_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_VERSION_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} + +set -e + + +pkgctl_version_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [COMMAND] [OPTIONS] + + Package version related commands. + + COMMANDS + check Check if there is a newer version availble + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} check libfoo linux libbar +_EOF_ +} + +pkgctl_version() { + if (( $# < 1 )); then + pkgctl_version_usage + exit 0 + fi + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_version_usage + exit 0 + ;; + check) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/version/check.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version/check.sh + pkgctl_version_check "$@" + exit 0 + ;; + *) + die "invalid argument: %s" "$1" + ;; + esac + done +} diff --git a/src/lib/version/check.sh b/src/lib/version/check.sh new file mode 100644 index 0000000..f6619c2 --- /dev/null +++ b/src/lib/version/check.sh @@ -0,0 +1,97 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +[[ -z ${DEVTOOLS_INCLUDE_VERSION_CHECK_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_VERSION_CHECK_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 -e + +pkgctl_version_check_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PKGBASE]... + + Uses nvchecker, a .nvchecker.toml file and the current PKGBUILD + pkgver to check if there is a newer package version available. + + The current working directory is used if no PKGBASE is specified. + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} neovim vim +_EOF_ +} + +pkgctl_version_check() { + local path + local pkgbases=() + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_version_check_usage + exit 0 + ;; + --) + shift + break + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + pkgbases=("$@") + break + ;; + esac + done + + if ! command -v nvchecker &>/dev/null; then + die "The \"$_DEVTOOLS_COMMAND\" command requires 'nvchecker'" + fi + + # Check if used without pkgbases in a packaging directory + if (( ${#pkgbases[@]} == 0 )); then + if [[ -f PKGBUILD ]]; then + pkgbases=(".") + else + pkgctl_version_check_usage + exit 1 + fi + fi + + for path in "${pkgbases[@]}"; do + pushd "${path}" >/dev/null + run_nvchecker "${path}" + popd >/dev/null + done +} + +run_nvchecker() { + local path=$1 + local pkgbase latest_version + + if [[ ! -f ".nvchecker.toml" || ! -f "PKGBUILD" ]]; then + die "No .nvchecker.toml or PKGBUILD found for ${path}" + exit 1 + fi + + # TODO: parse .SRCINFO file + # shellcheck source=contrib/makepkg/PKGBUILD.proto + . ./PKGBUILD + pkgbase=${pkgbase:-$pkgname} + + latest_version=$(nvchecker -c .nvchecker.toml --logger json | jq --raw-output 'select( .version ) | .version') + if (( $(vercmp "${latest_version}" "${pkgver}") > 0 )); then + msg2 "New ${pkgbase} version ${latest_version} is available upstream" + fi +} diff --git a/src/lib/version/version.sh b/src/lib/version/version.sh deleted file mode 100644 index d00a460..0000000 --- a/src/lib/version/version.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/hint/bash -# -# SPDX-License-Identifier: GPL-3.0-or-later - -[[ -z ${DEVTOOLS_INCLUDE_VERSION_SH:-} ]] || return 0 -DEVTOOLS_INCLUDE_VERSION_SH=1 - -_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} - -source /usr/share/makepkg/util/message.sh - -set -e - - -pkgctl_version_usage() { - local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} - cat <<- _EOF_ - Usage: ${COMMAND} [OPTIONS] - - Shows the current version information of pkgctl - - OPTIONS - -h, --help Show this help text -_EOF_ -} - -pkgctl_version_print() { - cat <<- _EOF_ - pkgctl @buildtoolver@ -_EOF_ -} - -pkgctl_version() { - while (( $# )); do - case $1 in - -h|--help) - pkgctl_version_usage - exit 0 - ;; - *) - die "invalid argument: %s" "$1" - ;; - esac - done - - pkgctl_version_print -} diff --git a/src/pkgctl.in b/src/pkgctl.in index 070e0cd..9deb4b2 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -27,7 +27,7 @@ usage() { release Release step to commit, tag and upload build artifacts repo Manage Git packaging repositories and their configuration search Search for an expression across the GitLab packaging group - version Show pkgctl version information + version Package version related commands OPTIONS -h, --help Show this help text @@ -39,6 +39,12 @@ if (( $# < 1 )); then exit 1 fi +pkgctl_version_print() { + cat <<- _EOF_ + pkgctl @buildtoolver@ +_EOF_ +} + export _DEVTOOLS_COMMAND='pkgctl' setup_workdir @@ -114,14 +120,20 @@ while (( $# )); do pkgctl_search "$@" exit 0 ;; - version|--version|-V) + version) _DEVTOOLS_COMMAND+=" $1" shift - # shellcheck source=src/lib/version/version.sh - source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version/version.sh + # shellcheck source=src/lib/version.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version.sh pkgctl_version "$@" exit 0 ;; + --version|-V) + _DEVTOOLS_COMMAND+=" $1" + shift + pkgctl_version_print + exit 0 + ;; *) die "invalid command: %s" "$1" ;; -- cgit v1.2.3-70-g09d2 From 6054c869e1b9b853aa7408261e477dcb187ff498 Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Fri, 5 Jan 2024 19:10:38 +0100 Subject: feat(upgrade): introduce the version upgrade subcommand This subcommand applies the detected upstream version upgrades to a PKGBUILD. Component: pkgctl version upgrade Co-authored-by: Levente Polyak Signed-off-by: Christian Heusel --- contrib/completion/bash/devtools.in | 7 ++ contrib/completion/zsh/_devtools.in | 6 ++ doc/man/pkgctl-version-upgrade.1.asciidoc | 33 +++++++++ doc/man/pkgctl-version.1.asciidoc | 4 ++ src/lib/version.sh | 11 ++- src/lib/version/upgrade.sh | 108 ++++++++++++++++++++++++++++++ 6 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 doc/man/pkgctl-version-upgrade.1.asciidoc create mode 100644 src/lib/version/upgrade.sh (limited to 'contrib/completion/bash/devtools.in') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index f1084ab..101bd78 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -339,6 +339,7 @@ _pkgctl_repo_switch_opts() { _pkgctl_version_cmds=( check + upgrade ) _pkgctl_version_check_args=( @@ -347,6 +348,12 @@ _pkgctl_version_check_args=( _pkgctl_version_check_opts() { _filedir -d; } +_pkgctl_version_upgrade_args=( + -h --help +) + +_pkgctl_version_upgrade_opts() { _filedir -d; } + _pkgctl_repo_web_args=( --print -h --help diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 575c327..38bf582 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -288,6 +288,7 @@ _pkgctl_args=( _pkgctl_version_cmds=( "pkgctl version command" "check[Check if there is an new upstream version available]" + "upgrade[Upgrade the PKGBUILD according to the latest available upstream version]" ) _pkgctl_version_check_args=( @@ -295,6 +296,11 @@ _pkgctl_version_check_args=( '*:git_dir:_files -/' ) +_pkgctl_version_upgrade_args=( + '(-h --help)'{-h,--help}'[Display usage]' + '*:git_dir:_files -/' +) + _pkgctl_diff_args=("${_diffpkg_args[@]}") _handle_subcommands() { diff --git a/doc/man/pkgctl-version-upgrade.1.asciidoc b/doc/man/pkgctl-version-upgrade.1.asciidoc new file mode 100644 index 0000000..3d5d882 --- /dev/null +++ b/doc/man/pkgctl-version-upgrade.1.asciidoc @@ -0,0 +1,33 @@ +pkgctl-version-upgrade(1) +========================= + +Name +---- +pkgctl-version-upgrade - Upgrade the PKGBUILD according to the latest available upstream version + +Synopsis +-------- +pkgctl version upgrade [OPTIONS] [PKGBASE...] + +Description +----------- + +Upgrade the PKGBUILD according to the latest available upstream version. + +Uses nvchecker, a .nvchecker.toml file and the current PKGBUILD pkgver to check +if there is a newer package version available. + +The current working directory is used if no PKGBASE is specified. + +Options +------- + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:nvchecker[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-version.1.asciidoc b/doc/man/pkgctl-version.1.asciidoc index 53a72f3..e71becd 100644 --- a/doc/man/pkgctl-version.1.asciidoc +++ b/doc/man/pkgctl-version.1.asciidoc @@ -27,9 +27,13 @@ Subcommands pkgctl version check:: Check if there is an new upstream version available +pkgctl version upgrade:: + Upgrade the PKGBUILD according to the latest available upstream version + See Also -------- linkman:pkgctl-version-check[1] +linkman:pkgctl-version-upgrade[1] include::include/footer.asciidoc[] diff --git a/src/lib/version.sh b/src/lib/version.sh index 826b306..14cd810 100644 --- a/src/lib/version.sh +++ b/src/lib/version.sh @@ -18,7 +18,8 @@ pkgctl_version_usage() { Package version related commands. COMMANDS - check Check if there is a newer version availble + check Check if there is a newer version availble + upgrade Upgrade the PKGBUILD according to the latest available upstream version OPTIONS -h, --help Show this help text @@ -48,6 +49,14 @@ pkgctl_version() { pkgctl_version_check "$@" exit 0 ;; + upgrade) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/version/upgrade.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version/upgrade.sh + pkgctl_version_upgrade "$@" + exit 0 + ;; *) die "invalid argument: %s" "$1" ;; diff --git a/src/lib/version/upgrade.sh b/src/lib/version/upgrade.sh new file mode 100644 index 0000000..704431a --- /dev/null +++ b/src/lib/version/upgrade.sh @@ -0,0 +1,108 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +[[ -z ${DEVTOOLS_INCLUDE_VERSION_UPGRADE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_VERSION_UPGRADE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/version/check.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version/check.sh +# shellcheck source=src/lib/util/pkgbuild.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pkgbuild.sh + +source /usr/share/makepkg/util/message.sh + +set -e + +pkgctl_version_upgrade_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PKGBASE]... + + Upgrade the PKGBUILD according to the latest available upstream version + + Uses nvchecker, a .nvchecker.toml file and the current PKGBUILD + pkgver to check if there is a newer package version available. + + The current working directory is used if no PKGBASE is specified. + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} neovim vim +_EOF_ +} + +pkgctl_version_upgrade() { + local path upstream_version result + local pkgbases=() + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_version_upgrade_usage + exit 0 + ;; + --) + shift + break + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + pkgbases=("$@") + break + ;; + esac + done + + if ! command -v nvchecker &>/dev/null; then + die "The \"$_DEVTOOLS_COMMAND\" command requires 'nvchecker'" + fi + + # Check if used without pkgbases in a packaging directory + if (( ${#pkgbases[@]} == 0 )); then + if [[ -f PKGBUILD ]]; then + pkgbases=(".") + else + pkgctl_version_upgrade_usage + exit 1 + fi + fi + + for path in "${pkgbases[@]}"; do + pushd "${path}" >/dev/null + + if [[ ! -f "PKGBUILD" ]]; then + die "No PKGBUILD found for ${path}" + fi + + # reset common PKGBUILD variables + unset pkgbase pkgname arch source pkgver pkgrel validpgpkeys + # shellcheck source=contrib/makepkg/PKGBUILD.proto + . ./PKGBUILD + pkgbase=${pkgbase:-$pkgname} + + if ! upstream_version=$(get_upstream_version); then + die "Failed to get latest upstream version for %s" "${pkgbase}" + fi + + if ! result=$(vercmp "${upstream_version}" "${pkgver}"); then + die "Failed to compare version %s against %s" "${upstream_version}" "${pkgver}" + fi + + if (( result > 0 )); then + msg_success "${BOLD}${pkgbase}${ALL_OFF}: upgrading from version ${PURPLE}${pkgver}${ALL_OFF} to ${DARK_GREEN}${upstream_version}${ALL_OFF}" + + pkgbuild_set_pkgver "${upstream_version}" + pkgbuild_set_pkgrel 1 + fi + + popd >/dev/null + done +} -- cgit v1.2.3-70-g09d2 From b258bb3b7c55d06bad108400450acd32cff05366 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Thu, 18 Jan 2024 03:33:13 +0100 Subject: feat(version): add verbose option to display up-to-date versions Sometimes it can be desired to get a results for each entry even if the current version is up-to-date. Add a --verbose option to print this optional detail. Component: pkgctl version check Component: pkgctl version upgrade Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 2 ++ contrib/completion/zsh/_devtools.in | 2 ++ doc/man/pkgctl-version-check.1.asciidoc | 3 +++ doc/man/pkgctl-version-upgrade.1.asciidoc | 3 +++ src/lib/version/check.sh | 25 ++++++++++++++++++++++--- src/lib/version/upgrade.sh | 21 ++++++++++++++++++++- 6 files changed, 52 insertions(+), 4 deletions(-) (limited to 'contrib/completion/bash/devtools.in') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index 101bd78..f8b1c9f 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -343,12 +343,14 @@ _pkgctl_version_cmds=( ) _pkgctl_version_check_args=( + -v --verbose -h --help ) _pkgctl_version_check_opts() { _filedir -d; } _pkgctl_version_upgrade_args=( + -v --verbose -h --help ) diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 38bf582..b427d20 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -292,11 +292,13 @@ _pkgctl_version_cmds=( ) _pkgctl_version_check_args=( + '(-v --verbose)'{-v,--verbose}'[Display results including up-to-date versions]' '(-h --help)'{-h,--help}'[Display usage]' '*:git_dir:_files -/' ) _pkgctl_version_upgrade_args=( + '(-v --verbose)'{-v,--verbose}'[Display results including up-to-date versions]' '(-h --help)'{-h,--help}'[Display usage]' '*:git_dir:_files -/' ) diff --git a/doc/man/pkgctl-version-check.1.asciidoc b/doc/man/pkgctl-version-check.1.asciidoc index ed9abdf..3113afa 100644 --- a/doc/man/pkgctl-version-check.1.asciidoc +++ b/doc/man/pkgctl-version-check.1.asciidoc @@ -30,6 +30,9 @@ which can be utilized in .nvchecker.toml. Options ------- +*-v, --verbose*:: + Display results including up-to-date versions + *-h, --help*:: Show a help text diff --git a/doc/man/pkgctl-version-upgrade.1.asciidoc b/doc/man/pkgctl-version-upgrade.1.asciidoc index 3d5d882..7f9cd96 100644 --- a/doc/man/pkgctl-version-upgrade.1.asciidoc +++ b/doc/man/pkgctl-version-upgrade.1.asciidoc @@ -22,6 +22,9 @@ The current working directory is used if no PKGBASE is specified. Options ------- +*-v, --verbose*:: + Display results including up-to-date versions + *-h, --help*:: Show a help text diff --git a/src/lib/version/check.sh b/src/lib/version/check.sh index fba2d1a..9bc29c1 100644 --- a/src/lib/version/check.sh +++ b/src/lib/version/check.sh @@ -29,7 +29,8 @@ pkgctl_version_check_usage() { will be supplied from \${XDG_CONFIG_HOME}/nvchecker. OPTIONS - -h, --help Show this help text + -v, --verbose Display results including up-to-date versions + -h, --help Show this help text EXAMPLES $ ${COMMAND} neovim vim @@ -37,9 +38,10 @@ _EOF_ } pkgctl_version_check() { - local path local pkgbases=() - local status_file path pkgbase upstream_version result + local verbose=0 + + local path status_file path pkgbase upstream_version result local up_to_date=() local out_of_date=() @@ -53,6 +55,10 @@ pkgctl_version_check() { pkgctl_version_check_usage exit 0 ;; + -v|--verbose) + verbose=1 + shift + ;; --) shift break @@ -81,6 +87,11 @@ pkgctl_version_check() { fi fi + # enable verbose mode when we only have a single item to check + if (( ${#pkgbases[@]} == 1 )); then + verbose=1 + fi + # start a terminal spinner as checking versions takes time status_dir=$(mktemp --tmpdir="${WORKDIR}" --directory pkgctl-version-check-spinner.XXXXXXXXXX) term_spinner_start "${status_dir}" @@ -140,6 +151,14 @@ pkgctl_version_check() { # stop the terminal spinner after all checks term_spinner_stop "${status_dir}" + if (( verbose )) && (( ${#up_to_date[@]} > 0 )); then + printf "%sUp-to-date%s\n" "${section_separator}${BOLD}${UNDERLINE}" "${ALL_OFF}" + section_separator=$'\n' + for result in "${up_to_date[@]}"; do + msg_success " ${result}" + done + fi + if (( ${#failure[@]} > 0 )); then printf "%sFailure%s\n" "${section_separator}${BOLD}${UNDERLINE}" "${ALL_OFF}" section_separator=$'\n' diff --git a/src/lib/version/upgrade.sh b/src/lib/version/upgrade.sh index 9f884d0..70513ce 100644 --- a/src/lib/version/upgrade.sh +++ b/src/lib/version/upgrade.sh @@ -32,7 +32,8 @@ pkgctl_version_upgrade_usage() { The current working directory is used if no PKGBASE is specified. OPTIONS - -h, --help Show this help text + -v, --verbose Display results including up-to-date versions + -h, --help Show this help text EXAMPLES $ ${COMMAND} neovim vim @@ -42,6 +43,7 @@ _EOF_ pkgctl_version_upgrade() { local path upstream_version result local pkgbases=() + local verbose=0 local exit_code=0 local current_item=0 @@ -51,6 +53,10 @@ pkgctl_version_upgrade() { pkgctl_version_upgrade_usage exit 0 ;; + -v|--verbose) + verbose=1 + shift + ;; --) shift break @@ -79,6 +85,11 @@ pkgctl_version_upgrade() { fi fi + # enable verbose mode when we only have a single item to check + if (( ${#pkgbases[@]} == 1 )); then + verbose=1 + fi + # start a terminal spinner as checking versions takes time status_dir=$(mktemp --tmpdir="${WORKDIR}" --directory pkgctl-version-check-spinner.XXXXXXXXXX) term_spinner_start "${status_dir}" @@ -142,6 +153,14 @@ pkgctl_version_upgrade() { # stop the terminal spinner after all checks term_spinner_stop "${status_dir}" + if (( verbose )) && (( ${#up_to_date[@]} > 0 )); then + printf "%sUp-to-date%s\n" "${section_separator}${BOLD}${UNDERLINE}" "${ALL_OFF}" + section_separator=$'\n' + for result in "${up_to_date[@]}"; do + msg_success " ${result}" + done + fi + if (( ${#failure[@]} > 0 )); then exit_code=1 printf "%sFailure%s\n" "${section_separator}${BOLD}${UNDERLINE}" "${ALL_OFF}" -- cgit v1.2.3-70-g09d2 From 5042dcaeb4916e199b30ecf21048a4234da43499 Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Thu, 15 Jun 2023 16:30:41 +0200 Subject: feat(build): allow to test-install the built packages This change introduces the new --install-to-host flag to pkgctl build, which can be used with one of the modes 'all' or 'auto'. Depending on the mode either all or just already installed packages are installed to the host system. BREAKING CHANGE: the --install flag is renamed to --install-to-chroot to avoid confusion with the newly introduced flag. Component: pkgctl build Signed-off-by: Christian Heusel Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 11 +++++++ contrib/completion/zsh/_devtools.in | 5 ++- doc/man/pkgctl-build.1.asciidoc | 14 +++++++-- src/lib/build/build.sh | 61 ++++++++++++++++++++++++++++++++++--- src/lib/valid-build-install.sh | 11 +++++++ 5 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 src/lib/valid-build-install.sh (limited to 'contrib/completion/bash/devtools.in') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index f8b1c9f..11fa234 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -3,6 +3,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/valid-build-install.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-build-install.sh # shellcheck source=src/lib/valid-tags.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh # shellcheck source=src/lib/valid-repos.sh @@ -179,6 +181,8 @@ _pkgctl_build_args=( -c --clean -w --worker --inspect + -I --install-to-chroot + -i --install-to-host --pkgver --pkgrel @@ -199,9 +203,16 @@ _pkgctl_build_args_w_opts() { _pkgctl_build_args__worker_opts; } _pkgctl_build_args__inspect_opts() { _devtools_completions_inspect; } _pkgctl_build_args__pkgver_opts() { :; } _pkgctl_build_args__pkgrel_opts() { :; } +_pkgctl_build_args__install_to_host_opts() { _pkgctl_build_completions_install_mode; } +_pkgctl_build_args_i_opts() { _pkgctl_build_args__install_to_host_opts; } +_pkgctl_build_args__install_to_chroot_opts() { _makechrootpkg_args_I_opts; } +_pkgctl_build_args_I_opts() { _pkgctl_build_args__install_to_chroot_opts; } _pkgctl_build_args__message_opts() { :; } _pkgctl_build_args_m_opts() { _pkgctl_build_args__message_opts; } _pkgctl_build_opts() { _filedir -d; } +_pkgctl_build_completions_install_mode() { + mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_BUILD_INSTALL[*]}" -- "$cur") +} _pkgctl_db_cmds=( diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 34f90c6..24e57bf 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -3,6 +3,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/valid-build-install.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-build-install.sh # shellcheck source=src/lib/valid-tags.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh # shellcheck source=src/lib/valid-repos.sh @@ -45,8 +47,9 @@ _pkgctl_build_args=( '(-t --testing)'{-t,--testing}'[Build against the testing counterpart of the auto-detected repo]' '(-o --offload)'{-o,--offload}'[Build on a remote server and transfer artifacts afterwards]' '(-c --clean)'{-c,--clean}'[Recreate the chroot before building]' - '(-I --install)'{-I,--install}'[Install a package into the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"' "--inspect[Spawn an interactive shell to inspect the chroot (never, always, failure)]:inspect:($DEVTOOLS_VALID_INSPECT_MODES[*])" + '(-I --install-to-chroot)'{-I,--install-to-chroot}'[Install a package to the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"' + '(-i --install-to-host)'{-i,--install-to-host}"[Install the built packages to the host system]:mode:($DEVTOOLS_VALID_BUILD_INSTALL[*])" '(-w --worker)'{-w,--worker}'[Name of the worker slot, useful for concurrent builds (disables auto-detection)]:slot:' '--nocheck[Do not run the check() function in the PKGBUILD]' '--pkgver=[Set pkgver, reset pkgrel and update checksums]:pkgver:' diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc index 12deaaa..e7ec714 100644 --- a/doc/man/pkgctl-build.1.asciidoc +++ b/doc/man/pkgctl-build.1.asciidoc @@ -35,9 +35,6 @@ Build Options *-c, --clean*:: Recreate the chroot before building -*-I, --install* 'FILE':: - Install a package into the working copy of the chroot - *--inspect* 'WHEN':: Spawn an interactive shell to inspect the chroot after building. Useful to ease the debugging of a package build. + Possible values for 'WHEN' are `'never'`, `'always'` or `'failure'` @@ -51,6 +48,17 @@ Build Options *--nocheck*:: Do not run the check() function in the PKGBUILD +Install Options +--------------- + +*-I, --install-to-chroot* 'FILE':: + Install a package to the working copy of the chroot + +*-i, --install-to-host* 'MODE':: + Install the built packages to the host system. Useful when one wants to verify that the package works as intended. + * When 'MODE' is 'all', this installs all built packages + * When 'MODE' is 'auto', this installs all built packages which are currently installed + PKGBUILD Options ---------------- diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index 712be22..64a6ce3 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -20,6 +20,8 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/srcinfo.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh # shellcheck source=src/lib/util/pkgbuild.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pkgbuild.sh +# shellcheck source=src/lib/valid-build-install.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-build-install.sh # shellcheck source=src/lib/valid-repos.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh # shellcheck source=src/lib/valid-tags.sh @@ -52,11 +54,14 @@ pkgctl_build_usage() { -t, --testing Build against the testing counterpart of the auto-detected repo -o, --offload Build on a remote server and transfer artifacts afterwards -c, --clean Recreate the chroot before building - -I, --install FILE Install a package into the working copy of the chroot --inspect WHEN Spawn an interactive shell to inspect the chroot (never, always, failure) -w, --worker SLOT Name of the worker slot, useful for concurrent builds (disables automatic names) --nocheck Do not run the check() function in the PKGBUILD + INSTALL OPTIONS + -I, --install-to-chroot FILE Install a package to the working copy of the chroot + -i, --install-to-host MODE Install the built package to the host system, possible modes are 'all' and 'auto' + PKGBUILD OPTIONS --pkgver=PKGVER Set pkgver, reset pkgrel and update checksums --pkgrel=PKGREL Set pkgrel to a given value @@ -119,6 +124,7 @@ pkgctl_build() { local TESTING=0 local RELEASE=0 local DB_UPDATE=0 + local INSTALL_TO_HOST=none local REPO= local PKGVER= @@ -131,12 +137,13 @@ pkgctl_build() { local MAKECHROOT_OPTIONS=() local RELEASE_OPTIONS=() local MAKEPKG_OPTIONS=() + local INSTALL_HOST_PACKAGES=() local WORKER= local WORKER_SLOT= # variables - local _arch path pkgbase pkgrepo source pkgbuild_checksum + local _arch path pkgbase pkgrepo source pkgbuild_checksum current_checksum while (( $# )); do case $1 in @@ -209,14 +216,22 @@ pkgctl_build() { BUILD_OPTIONS+=("-c") shift ;; - -I|--install) + -I|--install-to-chroot) (( $# <= 1 )) && die "missing argument for %s" "$1" if (( OFFLOAD )); then MAKECHROOT_OPTIONS+=("-I" "$2") else MAKECHROOT_OPTIONS+=("-I" "$(realpath "$2")") fi - warning 'installing packages into the chroot may break reproducible builds, use with caution!' + warning 'installing packages to the chroot may break reproducible builds, use with caution!' + shift 2 + ;; + -i|--install-to-host) + (( $# <= 1 )) && die "missing argument for %s" "$1" + if ! in_array "$2" "${DEVTOOLS_VALID_BUILD_INSTALL[@]}"; then + die 'invalid install mode: %s' "${2}" + fi + INSTALL_TO_HOST=$2 shift 2 ;; --nocheck) @@ -410,7 +425,9 @@ pkgctl_build() { fi # re-source the PKGBUILD if it changed - if [[ ${pkgbuild_checksum} != "$(b2sum PKGBUILD | awk '{print $1}')" ]]; then + current_checksum="$(b2sum PKGBUILD | awk '{print $1}')" + if [[ ${pkgbuild_checksum} != "${current_checksum}" ]]; then + pkgbuild_checksum=${current_checksum} # shellcheck source=contrib/makepkg/PKGBUILD.proto . ./PKGBUILD fi @@ -432,10 +449,38 @@ pkgctl_build() { fi done + # re-source the PKGBUILD if it changed + current_checksum="$(b2sum PKGBUILD | awk '{print $1}')" + if [[ ${pkgbuild_checksum} != "${current_checksum}" ]]; then + pkgbuild_checksum=${current_checksum} + # shellcheck source=contrib/makepkg/PKGBUILD.proto + . ./PKGBUILD + fi + # auto generate .SRCINFO # shellcheck disable=SC2119 write_srcinfo_file + # test-install (some of) the produced packages + if [[ ${INSTALL_TO_HOST} == auto ]] || [[ ${INSTALL_TO_HOST} == all ]]; then + # shellcheck disable=2119 + load_makepkg_config + + # this is inspired by print_all_package_names from libmakepkg + local version pkg_architecture pkg pkgfile + version=$(get_full_version) + + for pkg in "${pkgname[@]}"; do + pkg_architecture=$(get_pkg_arch "$pkg") + pkgfile=$(realpath "$(printf "%s/%s-%s-%s%s\n" "${PKGDEST:-.}" "$pkg" "$version" "$pkg_architecture" "$PKGEXT")") + + # check if we install all packages or if the (split-)package is already installed + if [[ ${INSTALL_TO_HOST} == all ]] || ( [[ ${INSTALL_TO_HOST} == auto ]] && pacman -Qq -- "$pkg" &>/dev/null ); then + INSTALL_HOST_PACKAGES+=("$pkgfile") + fi + done + fi + # release the build if (( RELEASE )); then pkgctl_release --repo "${pkgrepo}" "${RELEASE_OPTIONS[@]}" @@ -446,6 +491,12 @@ pkgctl_build() { popd >/dev/null done + # install all collected packages to the host system + if (( ${#INSTALL_HOST_PACKAGES[@]} )); then + msg "Installing built packages to the host system" + sudo pacman -U -- "${INSTALL_HOST_PACKAGES[@]}" + fi + # update the binary package repo db as last action if (( RELEASE )) && (( DB_UPDATE )); then # shellcheck disable=2119 diff --git a/src/lib/valid-build-install.sh b/src/lib/valid-build-install.sh new file mode 100644 index 0000000..9e98be2 --- /dev/null +++ b/src/lib/valid-build-install.sh @@ -0,0 +1,11 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later +: + +# shellcheck disable=2034 +DEVTOOLS_VALID_BUILD_INSTALL=( + none + auto + all +) -- cgit v1.2.3-70-g09d2