bin: add bash completion for copy command

Add bash completion for the common datastores, like we already do in the
CLI, and update the usage text accordingly.

Also, make sure to install to /usr/bin, not /bin since we've now merged
the hierarchies since a while back.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2025-10-23 15:23:59 +02:00
parent 3e03ece1d9
commit 21256a8ac1
4 changed files with 115 additions and 8 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ BIN_LICENSE = BSD-3-Clause
BIN_LICENSE_FILES = LICENSE
BIN_REDISTRIBUTE = NO
BIN_DEPENDENCIES = sysrepo libite
BIN_CONF_OPTS = --prefix= --disable-silent-rules
BIN_CONF_OPTS = --disable-silent-rules
BIN_AUTORECONF = YES
define BIN_CONF_ENV
+4
View File
@@ -3,6 +3,10 @@ ACLOCAL_AMFLAGS = -I m4
bin_PROGRAMS = copy erase files
# Bash completion
bashcompdir = $(datadir)/bash-completion/completions
dist_bashcomp_DATA = copy.bash
copy_SOURCES = copy.c util.c util.h
copy_CPPFLAGS = -D_DEFAULT_SOURCE -D_GNU_SOURCE
copy_CFLAGS = -W -Wall -Wextra
+93
View File
@@ -0,0 +1,93 @@
# bash completion for copy command
# SPDX-License-Identifier: ISC
_copy_completion()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
# Options for the copy command
opts="-h -n -q -s -t -u -v"
local datastores_dst="running-config startup-config"
local datastores_src="running-config startup-config factory-config"
case "${prev}" in
-t)
# Timeout expects a number, no completion
return 0
;;
-u)
# Username, could complete with getent passwd but keep it simple
return 0
;;
esac
# If current word starts with -, complete options
if [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
# Determine position (source or destination)
# Count non-option arguments before current position
local arg_count=0
local i
for ((i=1; i < COMP_CWORD; i++)); do
case "${COMP_WORDS[i]}" in
-h|-n|-q|-s|-v)
# Flag without argument
;;
-t|-u)
# Flag with argument, skip next word
((i++))
;;
-*)
# Unknown flag, might have argument
;;
*)
# Non-option argument
((arg_count++))
;;
esac
done
# Helper function to add non-hidden files/dirs, filtering out dotfiles unless explicitly requested
_add_files() {
local IFS=$'\n'
local files
# If user is explicitly typing a dotfile path, include dotfiles
if [[ ${cur} == .* || ${cur} == */.* ]]; then
files=( $(compgen -f -- "${cur}") )
else
# Only show non-hidden files and directories
files=( $(compgen -f -- "${cur}" | grep -v '/\.[^/]*$' | grep -v '^\.[^/]') )
fi
COMPREPLY+=( "${files[@]}" )
}
case ${arg_count} in
0)
# First argument (source): complete with files and all datastores including factory-config
COMPREPLY=( $(compgen -W "${datastores_src}" -- ${cur}) )
_add_files
;;
1)
# Second argument (destination): complete with files and limited datastores (no factory-config)
COMPREPLY=( $(compgen -W "${datastores_dst}" -- ${cur}) )
_add_files
;;
*)
# No more arguments expected
return 0
;;
esac
return 0
}
complete -F _copy_completion copy
+17 -7
View File
@@ -503,13 +503,23 @@ static int usage(int rc)
printf("Usage: %s [OPTIONS] SRC DST\n"
"\n"
"Options:\n"
" -h This help text\n"
" -n Dry-run, validate configuration without applying\n"
" -q Quiet mode, suppress informational messages\n"
" -s Sanitize paths for CLI use (restrict path traversal)\n"
" -u USER Username for remote commands, like scp\n"
" -t SEEC Timeout for the operation, or default %d sec\n"
" -v Show version\n", prognm, timeout);
" -h This help text\n"
" -n Dry-run, validate configuration without applying\n"
" -q Quiet mode, suppress informational messages\n"
" -s Sanitize paths for CLI use (restrict path traversal)\n"
" -t SEC Timeout for the operation, or default %d sec\n"
" -u USER Username for remote commands, like scp\n"
" -v Show version\n"
"\n"
"Files:\n"
" SRC JSON configuration file, or a datastore\n"
" DST A file or datastore, except factory-config\n"
"\n"
"Datastores:\n"
" running-config The running datastore, current active config\n"
" startup-config The non-volatile config used at startup\n"
" factory-config The device's factory default configuration\n"
"\n", prognm, timeout);
return rc;
}