diff --git a/README.md b/README.md index 2ef2c41..832c236 100644 --- a/README.md +++ b/README.md @@ -43,3 +43,4 @@ database, etc.. See our guides on [installing & getting started](https://containertoolbx.org/install/) with Toolbox and [Linux distro support](https://containertoolbx.org/distros/). + diff --git a/completion/bash/toolbox b/completion/bash/toolbox deleted file mode 100644 index 7fbf2cf..0000000 --- a/completion/bash/toolbox +++ /dev/null @@ -1,100 +0,0 @@ -# Check for bash -[ -z "$BASH_VERSION" ] && return - -__toolbox_containers() { - toolbox list -c 2>/dev/null | tail -n +2 2>/dev/null | cut -d " " -f 3 2>/dev/null -} - -__toolbox_distros() { - echo "fedora" - echo "rhel" -} - -__toolbox_images() { - toolbox list -i 2>/dev/null | tail -n +2 2>/dev/null | cut -d " " -f 3 2>/dev/null -} - -__toolbox() { - local MIN_VERSION=32 - local RAWHIDE_VERSION=34 - - local commands="create enter help init-container list rm rmi run" - local global_options="--assumeyes --help --log-level --log-podman" - local log_levels="debug info warn error fatal panic" - - declare -A options - local options=([create]="--distro --image --release" \ - [enter]="--distro --release" \ - [help]="$commands" \ - [init-container]="--home --home-link --monitor-host --shell --uid --user" \ - [list]="--containers --images" \ - [rm]="--all --force" \ - [rmi]="--all --force" \ - [run]="--container --distro --release") - - _init_completion -s || return - - if [ "${COMP_CWORD}" -eq 1 ]; then - mapfile -t COMPREPLY < <(compgen -W "$global_options $commands" -- "$2") - return 0 - fi - - # If a global option is mentioned, don't mention it anymore - for option in $global_options; do - if [[ "${COMP_LINE}" =~ "$option" ]]; then - global_options="${global_options/$option}" - fi - done - - # If a command is mentioned, don't mention any more commands - local command - for cmd in $commands; do - if [[ "${COMP_LINE}" =~ "$cmd" ]]; then - commands="" - command="$cmd" - fi - done - - case "$prev" in - --assumeyes | -y | --help | -h | --verbose | -v | --log-podman) - mapfile -t COMPREPLY < <(compgen -W "$global_options $commands" -- "$2") - return 0 - ;; - --container | -c) - mapfile -t COMPREPLY < <(compgen -W "$(__toolbox_containers)" -- "$2") - return 0 - ;; - --distro | -d) - mapfile -t COMPREPLY < <(compgen -W "$(__toolbox_distros)" -- "$2") - return 0 - ;; - --image | -i) - mapfile -t COMPREPLY < <(compgen -W "$(__toolbox_images)" -- "$2") - return 0 - ;; - --release | -r) - mapfile -t COMPREPLY < <(compgen -W "$(seq $MIN_VERSION $RAWHIDE_VERSION)" -- "$2") - return 0 - ;; - --log-level) - mapfile -t COMPREPLY < <(compgen -W "$log_levels" -- "$2") - return 0 - ;; - esac - - local extra_comps - case "$command" in - rm | enter) - extra_comps="$(__toolbox_containers)" - ;;& - rmi) - extra_comps="$(__toolbox_images)" - ;;& - *) - mapfile -t COMPREPLY < <(compgen -W "${options[$command]} $extra_comps" -- "$2") - return 0; - ;; - esac -} - -complete -F __toolbox toolbox diff --git a/completion/generate_completions.py b/completion/generate_completions.py new file mode 100644 index 0000000..bde5af5 --- /dev/null +++ b/completion/generate_completions.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# +# Copyright © 2022 Ondřej Míchal +# Copyright © 2022 Red Hat Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import os +import subprocess +import sys + +if len(sys.argv) != 3: + print('{}: wrong arguments'.format(sys.argv[0]), file=sys.stderr) + print('Usage: {} [SOURCE DIR] [COMPLETION TYPE]'.format(sys.argv[0]), file=sys.stderr) + print() + print("SOURCE DIR is path to the Toolbox Go source code") + print("COMPLETION TYPE is either 'bash', 'zsh' or 'fish'") + sys.exit(1) + +source_dir = sys.argv[1] +completion_type = sys.argv[2] + +try: + os.chdir(source_dir) + output = subprocess.run(['go', 'run', '.', 'completion', completion_type], check=True) +except subprocess.CalledProcessError as e: + print('{}: go run returned non-zero exit status {}'.format(sys.argv[0], e.returncode), file=sys.stderr) + sys.exit(e.returncode) + +sys.exit(0) diff --git a/completion/meson.build b/completion/meson.build new file mode 100644 index 0000000..0421f6a --- /dev/null +++ b/completion/meson.build @@ -0,0 +1,36 @@ +generate_completions_program = find_program('generate_completions.py') + +if bash_completion.found() + bash_comp_dir = bash_completion.get_pkgconfig_variable('completionsdir') +else + bash_comp_dir = get_option('datadir') / 'bash-completion' / 'completions' + message('bash-completion not found: using', get_option('prefix') / bash_comp_dir, 'as a falback install directory') +endif + +if fish.found() + fish_comp_dir = fish.get_pkgconfig_variable('completionsdir') +else + fish_comp_dir = get_option('datadir') / 'fish' / 'completions' + message('fish not found: using', get_option('prefix') / fish_comp_dir, 'as a fallback install directory') +endif + +completion_bash = custom_target('bash-completion', + capture: true, + command: [generate_completions_program, meson.global_source_root() / 'src', 'bash'], + install: true, + install_dir: bash_comp_dir, + output: 'toolbox') + +completion_zsh = custom_target('zsh-completion', + capture: true, + command: [generate_completions_program, meson.global_source_root() / 'src', 'zsh'], + install: true, + install_dir: get_option('datadir') / 'zsh' / 'site_functions', + output: '_toolbox') + +completion_fish = custom_target('fish-completion', + capture: true, + command: [generate_completions_program, meson.global_source_root() / 'src', 'fish'], + install: true, + install_dir: fish_comp_dir, + output: 'toolbox.fish') diff --git a/meson.build b/meson.build index cf32ae3..70aa0a5 100644 --- a/meson.build +++ b/meson.build @@ -19,6 +19,7 @@ shellcheck = find_program('shellcheck', required: false) skopeo = find_program('skopeo', required: false) bash_completion = dependency('bash-completion', required: false) +fish = dependency('fish', required: false) migration_path_for_coreos_toolbox = get_option('migration_path_for_coreos_toolbox') profiledir = get_option('profile_dir') @@ -32,13 +33,6 @@ if tmpfilesdir == '' or not fs.exists('/run/.containerenv') endif endif -if bash_completion.found() - install_data( - 'completion/bash/toolbox', - install_dir: bash_completion.get_variable(pkgconfig: 'completionsdir') - ) -endif - if not skopeo.found() message('Running system tests requires Skopeo for OCI image manipulation.') endif @@ -70,5 +64,8 @@ subdir('data') subdir('doc') subdir('profile.d') subdir('src') +if get_option('install_completions') + subdir('completion') +endif meson.add_install_script('meson_post_install.py') diff --git a/meson_options.txt b/meson_options.txt index 9afcc7b..6be8202 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -17,3 +17,10 @@ option( description: 'Directory for system-wide tmpfiles.d(5) files', type: 'string', ) + +option( + 'install_completions', + description: 'Install bash, zsh and fish command completions', + type: 'boolean', + value: true, +)