summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLevente Polyak <anthraxx@archlinux.org>2024-01-05 19:23:52 +0100
committerLevente Polyak <anthraxx@archlinux.org>2024-01-07 02:38:42 +0100
commitd0dc0e1a32d6ed9b166eca777f7fb7071c4c2df1 (patch)
tree02f06b909f89166532bbfac91a545b31bd219048
parent0e538cf4983f27548077c0a2a272ecd8deebacb1 (diff)
downloaddevtools-d0dc0e1a32d6ed9b166eca777f7fb7071c4c2df1.tar.xz
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 <anthraxx@archlinux.org>
-rw-r--r--README.md5
-rw-r--r--contrib/completion/bash/devtools.in11
-rw-r--r--contrib/completion/zsh/_devtools.in6
-rw-r--r--doc/man/pkgctl-search.1.asciidoc23
-rw-r--r--src/lib/common.sh4
-rw-r--r--src/lib/search.sh93
-rw-r--r--src/lib/valid-search.sh11
7 files changed, 134 insertions, 19 deletions
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
+)