Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,34 @@ $ newa -D /var/tmp/newa/run-123 list --refresh
$ newa -P list --refresh-all
```

## Bash Auto-Completion

NEWA includes bash auto-completion support for all commands and options. When you install NEWA via the RPM package, bash completion is automatically installed.

### Using bash completion

After installing the RPM package, completion will be available in new shell sessions. To enable it immediately:

```bash
source /usr/share/bash-completion/completions/newa
```

### Examples

```bash
# Complete subcommands
newa <TAB>
event jira schedule execute report cancel summarize list

# Complete options
newa event --<TAB>
--erratum --compose --jira-issue --rog-mr --compose-mapping ...

# Complete architectures
newa event --compose CentOS-Stream-9 jira --issue-config config.yaml schedule --arch <TAB>
x86_64 aarch64 ppc64le s390x
```

## Contribute

Currently the code expects a stable Fedora release.
Expand Down
101 changes: 101 additions & 0 deletions newa-completion.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env bash
# Bash completion for newa (New Errata Workflow Automation)
# Source this file or add it to /etc/bash_completion.d/
#
# This completion script dynamically extracts commands and options from
# newa's help output, ensuring it stays in sync with the actual CLI.

_newa_completion() {
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"

# Predefined value completions that can't be extracted from help
local arch_values="x86_64 aarch64 ppc64le s390x"
local result_values="passed failed error"

# Check if we're completing after a specific option that expects a value
case "${prev}" in
--state-dir|-D|--extract-state-dir|-E|--conf-file|--issue-config|--job-recipe)
# Complete with files/directories
COMPREPLY=( $(compgen -f -- "${cur}") )
return 0
;;
--arch)
# Complete with architecture values
COMPREPLY=( $(compgen -W "${arch_values}" -- "${cur}") )
return 0
;;
--restart-result|-r)
# Complete with result values
COMPREPLY=( $(compgen -W "${result_values}" -- "${cur}") )
return 0
;;
--workers|--last)
# Complete with numbers - just return empty to allow user input
return 0
;;
--erratum|-e|--compose|-c|--jira-issue|--rog-mr|--compose-mapping|--map-issue|--issue|--assignee|--restart-request|-R|--fixture|--action-id-filter|--issue-id-filter|--event-filter|--environment)
# These expect user-provided values, return empty
return 0
;;
esac

# Find which command (if any) has been specified
# We need to find the LAST command before the current word (for command chaining support)
local cmd=""
local all_commands

# Extract available commands from newa help
# Look for lines that list commands, typically in format: " command Description"
all_commands=$(newa --help 2>/dev/null | grep -E '^ [a-z]+ ' | awk '{print $1}' | tr '\n' ' ')

for ((i=1; i < COMP_CWORD; i++)); do
local word="${COMP_WORDS[i]}"
# Check if this word is a command (not an option)
if [[ " ${all_commands} " =~ " ${word} " ]]; then
cmd="${word}"
# Don't break - keep looking for more commands (command chaining)
fi
done

# If we're completing the current word and it starts with -, offer options
if [[ ${cur} == -* ]]; then
local help_output
if [[ -n "${cmd}" ]]; then
# Get help for the specific command
help_output=$(newa "${cmd}" --help 2>/dev/null)
else
# Get main help
help_output=$(newa --help 2>/dev/null)
fi

# Extract options from help output
# Look for lines with options: " -s, --long-option" or " --long-option"
local options
options=$(echo "${help_output}" | grep -E '^\s+(-[a-zA-Z]|--[a-z-]+)' | \
sed -E 's/.*\s(--[a-z][a-z-]*).*/\1/' | \
grep -E '^--' | sort -u | tr '\n' ' ')

# Also extract short options
local short_options
short_options=$(echo "${help_output}" | grep -E '^\s+-[a-zA-Z],' | \
sed -E 's/.*\s(-[a-zA-Z]).*/\1/' | \
grep -E '^-[a-zA-Z]$' | sort -u | tr '\n' ' ')

COMPREPLY=( $(compgen -W "${options} ${short_options}" -- "${cur}") )
return 0
fi

# If we're not completing an option, offer commands
COMPREPLY=( $(compgen -W "${all_commands}" -- "${cur}") )
return 0
}

# Register the completion function with filenames option
# The -o filenames option tells bash to:
# - Add trailing slashes to directory names
# - Handle spaces in filenames properly
# - Apply standard file completion behavior
complete -o filenames -F _newa_completion newa
4 changes: 4 additions & 0 deletions newa.spec
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,16 @@ export SETUPTOOLS_SCM_PRETEND_VERSION=%{version}
%pyproject_install
%pyproject_save_files newa

# Install bash completion
install -D -m 0644 newa-completion.bash %{buildroot}%{_datadir}/bash-completion/completions/newa

%check
%pyproject_check_import

%files -n newa -f %{pyproject_files}
%doc README.md
%{_bindir}/newa
%{_datadir}/bash-completion/completions/newa

%changelog
* Thu June 06 2024 Miroslav Vadkerti <mvadkert@redhat.com> - 0.1-1
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ raw-options.version_scheme = "release-branch-semver"
include = [
"/newa",
"/README.md",
"/newa-completion.bash",
]

# TODO: man page?
Expand Down
Loading