From 39d7e5b252adb25bdd61ebf873b98df6db284ffc Mon Sep 17 00:00:00 2001 From: Mikkel Ricky Date: Fri, 6 Mar 2026 10:21:15 +0100 Subject: [PATCH] Built completions with Completely --- README.md | 16 +- Taskfile.yml | 3 + completion/Taskfile.yml | 40 ++++ .../itkdev-docker-compose-completion.bash | 20 -- .../itkdev-docker-compose-completion.bash | 69 +++++++ .../itkdev-docker-compose.completely.yaml | 173 ++++++++++++++++++ completion/zsh/_itkdev-docker-compose | 86 --------- scripts/itkdev-docker-compose | 18 ++ 8 files changed, 315 insertions(+), 110 deletions(-) create mode 100644 completion/Taskfile.yml delete mode 100644 completion/bash/itkdev-docker-compose-completion.bash create mode 100644 completion/itkdev-docker-compose-completion.bash create mode 100644 completion/itkdev-docker-compose.completely.yaml delete mode 100644 completion/zsh/_itkdev-docker-compose diff --git a/README.md b/README.md index a04656c..9bdaa3b 100644 --- a/README.md +++ b/README.md @@ -127,20 +127,28 @@ The certificate is located in `./treafik/ssl/docker.crt` in this repository. ### Bash -You can install completions for `bash` by running: +You can install completions for `bash` by adding ```sh -ln -s $(git rev-parse --show-toplevel)/completion/bash/itkdev-docker-compose-completion.bash $(brew --prefix)/etc/bash_completion.d/itkdev-docker-compose +eval "$(itkdev-docker-compose completions)" ``` +to your `~/.bashrc`. + ### Zsh -You can install completions for `zsh` by updating `fpath` in `~/.zshrc`, e.g. by running: +Add ```sh -echo "fpath=($(git rev-parse --show-toplevel)/completion/zsh \$fpath) # itkdev-docker " >> ~/.zshrc +# Load completion functions +autoload -Uz +X compinit && compinit +autoload -Uz +X bashcompinit && bashcompinit + +eval "$(itkdev-docker-compose completions)" ``` +to your `~/.zshrc`. If you are using Oh-My-Zsh, you can leave out the `autoload` incantations. + ### Docker UI If you want a graphical user interface to see what images and containers are diff --git a/Taskfile.yml b/Taskfile.yml index 3ce3dc8..e0ea312 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -4,6 +4,9 @@ version: "3" includes: github-actions: ./task/Taskfile.github-actions.yml + completion: + taskfile: ./completion/Taskfile.yml + dir: ./completion vars: GITHUB_ACTIONS_TEMPLATES_HEADER: | diff --git a/completion/Taskfile.yml b/completion/Taskfile.yml new file mode 100644 index 0000000..bb8a503 --- /dev/null +++ b/completion/Taskfile.yml @@ -0,0 +1,40 @@ +# yaml-language-server: $schema=https://taskfile.dev/schema.json + +version: "3" + +env: + COMPLETELY_CONFIG_PATH: itkdev-docker-compose.completely.yaml + COMPLETELY_OUTPUT_PATH: itkdev-docker-compose-completion.bash + +tasks: + build: + desc: Build completion script for Bash + cmds: + - task: completely + vars: + TASK_ARGS: generate + + test: + desc: Template completions + cmds: + # Notice: The completions are not sorted alphabetically when running `completely test`. + - for: + - "itkdev-docker-compose -" + - "itkdev-docker-compose u" + - "itkdev-docker-compose op" + - "itkdev-docker-compose dru" + - "itkdev-docker-compose s" + - "itkdev-docker-compose sy" + - "itkdev-docker-compose sync:" + - "itkdev-docker-compose templa" + - "itkdev-docker-compose template:install -" + - "itkdev-docker-compose template:install " + task: completely + vars: + TASK_ARGS: test '{{.ITEM}}' + silent: true + + completely: + desc: Run completely (https://github.com/bashly-framework/completely). Example `{{.TASK}} preview` + cmds: + - docker run --rm --env COMPLETELY_CONFIG_PATH --env COMPLETELY_OUTPUT_PATH --env COMPLETELY_DEBUG --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/completely {{.TASK_ARGS}} {{.CLI_ARGS}} diff --git a/completion/bash/itkdev-docker-compose-completion.bash b/completion/bash/itkdev-docker-compose-completion.bash deleted file mode 100644 index 0b52a60..0000000 --- a/completion/bash/itkdev-docker-compose-completion.bash +++ /dev/null @@ -1,20 +0,0 @@ -#/usr/bin/env bash -_idc_completions() -{ - local cur - _get_comp_words_by_ref -n : cur - - if [ "${#COMP_WORDS[@]}" != "2" ]; then - return - fi - - # Keep the suggestions in a local variable - local suggestions=($(compgen -W "url open drush nfs:enable template:install template:update traefik:start traefik:stop traefik:open traefik:url mail:open mail:url mailhog:open mailhog:url sql:cli sql:connect sql:log sql:port sql:open xdebug xdebug3 hosts:insert self:update sync sync:db sync:files images:pull composer php version bin/console" -- "${COMP_WORDS[1]}")) - - COMPREPLY=("${suggestions[@]}") - - __ltrim_colon_completions "$cur" -} - -complete -F _idc_completions itkdev-docker-compose -complete -F _idc_completions idc diff --git a/completion/itkdev-docker-compose-completion.bash b/completion/itkdev-docker-compose-completion.bash new file mode 100644 index 0000000..c0ab8c9 --- /dev/null +++ b/completion/itkdev-docker-compose-completion.bash @@ -0,0 +1,69 @@ +# itkdev-docker-compose completion -*- shell-script -*- + +# This bash completions script was generated by +# completely (https://github.com/bashly-framework/completely) +# Modifying it manually is not recommended + +_itkdev-docker-compose_completions_filter() { + local words="$1" + local cur=${COMP_WORDS[COMP_CWORD]} + local result=() + + # words the user already typed (excluding the command itself) + local used=() + if ((COMP_CWORD > 1)); then + used=("${COMP_WORDS[@]:1:$((COMP_CWORD - 1))}") + fi + + if [[ "${cur:0:1}" == "-" ]]; then + # Completing an option: offer everything (including options) + echo "$words" + + else + # Completing a non-option: offer only non-options, + # and don't re-offer ones already used earlier in the line. + for word in $words; do + [[ "${word:0:1}" == "-" ]] && continue + + local seen=0 + for u in "${used[@]}"; do + if [[ "$u" == "$word" ]]; then + seen=1 + break + fi + done + ((!seen)) && result+=("$word") + done + + echo "${result[*]}" + fi +} + +_itkdev-docker-compose_completions() { + local cur=${COMP_WORDS[COMP_CWORD]} + local compwords=() + if ((COMP_CWORD > 0)); then + compwords=("${COMP_WORDS[@]:1:$((COMP_CWORD - 1))}") + fi + local compline="${compwords[*]}" + + COMPREPLY=() + + case "$compline" in + 'template:install'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_itkdev-docker-compose_completions_filter "--force --list $(itkdev-docker-compose template:install --list-compact 2>/dev/null)")" -- "$cur") + ;; + + 'template:update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_itkdev-docker-compose_completions_filter "--force")" -- "$cur") + ;; + + *) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_itkdev-docker-compose_completions_filter "--help url open drush self:update sync sync:db sync:files sql:cli sql:connect sql:log sql:open sql:port template:install template:update traefik:start traefik:stop traefik:url traefik:open traefik:logs traefik:pull mail:url mail:open mailhog:url mailhog:open xdebug xdebug3 hosts:insert images:pull shell composer php down version")" -- "$cur") + ;; + + esac +} && + complete -F _itkdev-docker-compose_completions itkdev-docker-compose + +# ex: filetype=sh diff --git a/completion/itkdev-docker-compose.completely.yaml b/completion/itkdev-docker-compose.completely.yaml new file mode 100644 index 0000000..48be9a6 --- /dev/null +++ b/completion/itkdev-docker-compose.completely.yaml @@ -0,0 +1,173 @@ +# https://github.com/bashly-framework/completely?tab=readme-ov-file#configuration-syntax + +itkdev-docker-compose: + - --help + + # url [service [port]] + # Print url to site or a service + # + # Protip: run + # + # brew install jq + # + # for improved handling of Traefik host names using jq (https://stedolan.github.io/jq/). + - url + + # open [service [port]] + # Open url in default browser + - open + + # drush + # Run drush command. If drush in installed via composer, + # the vendor/bin/drush command is run inside the phpfpm + # container. Otherwise, the drush container is used to + # run the command. + - drush + + # self:update + # Update this script and other stuff. + - self:update + + # sync + # Sync both database and files. + - sync + + # sync:db + # Sync database base on 'REMOTE_DB_DUMP_CMD' in the env + # file. + # + # If 'SYNC_DB_POST_SCRIPT' is set, it will be eval'ed after + # importing the remote database. + - sync:db + + # sync:files + # Sync files base on 'REMOTE_PATH' or 'LOCAL_PATH' in + # the env file. + - sync:files + + # sql:cli + # Open MySQL client to the database (named `db`) in the database + # container (`mariadb`). + # + # Execute a SQL query from the command line: + # + # itkdev-docker-compose sql:cli --table <<< 'SHOW TABLES' + # + # Run a SQL script: + # + # itkdev-docker-compose sql:cli < query.sql + - sql:cli + + # sql:connect + # Print mysql command for connecting to database (named + # `db`) in the database container (`mariadb`). + # + # Use `$(itkdev-docker-compose sql:connect)` to open the + # database cli. + - sql:connect + + # sql:log + # Log SQL queries sent to database. + - sql:log + + # sql:open + # Open database GUI and connect to MariaDB. + - sql:open + + # sql:port + # Display the exposed MariaDB SQL server port. + - sql:port + + # template:install name [--force] [--list] + # Install a named docker-composer template in the current + # directory. + - template:install: + - --force + - --list + - $(itkdev-docker-compose template:install --list-compact 2>/dev/null) + + # template:update [--force] + # Update template installed in project. + - template:update: + - --force + + # traefik:start + # Start traefik reverse proxy. + - traefik:start + + # traefik:stop + # Stop traefik reverse proxy + - traefik:stop + + # traefik:url + # URL for the administrative UI for traefik. + - traefik:url + + # traefik:open + # Open the administrative UI for traefik. + - traefik:open + + # traefik:logs + # See traefik logs + - traefik:logs + + # traefik:pull + # Pull latest traefik & socket-proxy containers + - traefik:pull + + # mail:url + # URL for the test mail web interface. + - mail:url + + # mail:open + # Open test mail web interface in default browser. + - mail:open + + # mailhog:url + # URL for the mailhog web-interface. + - mailhog:url + + # mailhog:open + # Open mailhog url in default browser + - mailhog:open + + # xdebug + # Boot the containers with PHP xdebug support enabled. + - xdebug + + # xdebug3 + # Boot the containers with PHP xdebug support enabled. + # Consider using `xdebug` for an improved developer experience. + - xdebug3 + + # hosts:insert + # Insert the docker site url into the hosts file. + - hosts:insert + + # images:pull + # Update/pull all docker images. + - images:pull + + # shell [service name] + # Enter into /usr/bin/env sh inside container. E.g. itkdev-docker-compose shell phpfpm + - shell + + # composer + # Run composer command inside phpfpm container + - composer + + # php + # Run php command inside phpfpm container + - php + + # bin/* + # vendor/bin/* + # Run command command inside phpfpm container + + # down + # Stop and remove containers, networks, images, and volumes + - down + + # version + # Display this tool's current version + - version diff --git a/completion/zsh/_itkdev-docker-compose b/completion/zsh/_itkdev-docker-compose deleted file mode 100644 index 78cc251..0000000 --- a/completion/zsh/_itkdev-docker-compose +++ /dev/null @@ -1,86 +0,0 @@ -#compdef itkdev-docker-compose - -# Description -# ----------- -# zsh completion for itkdev-docker-compose -# ------------------------------------------------------------------------- -# Authors -# ------- -# * Mikkel Ricky -# ------------------------------------------------------------------------- -# Inspiration -# ----------- -# * https://github.com/docker/compose/blob/master/contrib/completion/zsh/_docker-compose -# ------------------------------------------------------------------------- - -_itkdev-docker-compose() { - local curcontext="$curcontext" state line - integer ret=1 - typeset -A opt_args - - _arguments -C \ - '--help[Get help]' \ - '(-): :->command' \ - '(-)*:: :->option-or-argument' \ - && ret=0 - - case $state in - (command) - _values 'itkdev-docker-compose command' \ - 'url[Print url to site.]' \ - 'open[Open url in default browser.]' \ - 'drush[Run drush command.]' \ - 'nfs\:enable[Enable NFS volume sharing.]' \ - 'self\:update[Update stuff.]' \ - 'sync[Sync both database and files.]' \ - 'sync\:db[Sync database base.]' \ - 'sync\:files[Sync files base.]' \ - 'sql\:cli[Open mysql cli.]' \ - 'sql\:connect[Print mysql command for connecting to database.]' \ - 'sql\:log[Log SQL queries sent to database.]' \ - 'sql\:port[Display the exposed MariaDB SQL server port.]' \ - 'sql\:open[Open default SQL UI.]' \ - 'template\:install[Install template]' \ - 'template\:update[Update template]' \ - 'traefik\:start[Start reverse proxy]' \ - 'traefik\:stop[Stop reverse proxy]' \ - 'traefik\:open[Open reverse proxy web-interface]' \ - 'traefik\:url[URL for the reverse proxy web-interface]' \ - 'mail\:url[URL for the mail web-interface.]' \ - 'mail\:open[Open mail url in default browser.]' \ - 'mailhog\:url[URL for the mailhog web-interface.]' \ - 'mailhog\:open[Open mailhog url in default browser.]' \ - 'xdebug[Start the containers with Xdebug enabled.]' \ - 'xdebug3[Start the containers with Xdebug enabled.]' \ - 'hosts\:insert[Insert the docker site url into the hosts file.]' \ - 'images\:pull[Update/pull all docker images.]' \ - 'composer[Run composer command inside phpfpm container.]' \ - 'php[Run php command inside phpfpm container.]' \ - 'version[Display this tool'\''s current version.]' \ - && ret=0 - - # 'bin'{bin/*,vendor/bin/*}'[Run command command inside phpfpm container]' \ - # *[Pass command and arguments to `docker-compose` and - # hope for the best. - ;; - - # __itkdev-docker-compose_commands && ret=0 - # ;; - # (option-or-argument) - # curcontext=${curcontext%:*:*}:docker-compose-$words[1]: - # __itkdev-docker-compose_subcommand && ret=0 - # ;; - esac - - return ret -} - -_itkdev-docker-compose "$@" - -# Local Variables: -# mode: Shell-Script -# sh-indentation: 2 -# indent-tabs-mode: nil -# sh-basic-offset: 2 -# End: -# vim: ft=zsh sw=2 ts=2 et diff --git a/scripts/itkdev-docker-compose b/scripts/itkdev-docker-compose index bbca8b5..67a5f0d 100755 --- a/scripts/itkdev-docker-compose +++ b/scripts/itkdev-docker-compose @@ -51,6 +51,7 @@ function self_update { function template_install { local force=0 local list=0 + local list_compact=0 local name="" for var in "$@" @@ -62,6 +63,9 @@ function template_install { --list) list=1 ;; + --list-compact) + list_compact=1 + ;; *) name="$var" ;; @@ -72,6 +76,14 @@ function template_install { local source_dir=$templates_dir/$name/ local target_dir=$PWD + if [ "$list_compact" -eq 1 ]; then + for name in $(find "$templates_dir" -mindepth 1 -maxdepth 1 -type d | sort --version-sort); do + echo -n "$(basename $name) " + done + echo + exit 0 + fi + if [ "$list" -eq 1 ]; then echo Templates: for name in $(find "$templates_dir" -mindepth 1 -maxdepth 1 -type d | sort --version-sort); do @@ -484,6 +496,12 @@ if [[ "$#" -gt "0" && "$1" == "version" ]]; then exit fi +# Allow completion without existence of compose file. +if [[ "$#" -gt "0" && "$1" == "completions" ]]; then + cat ${script_dir}/../completion/itkdev-docker-compose-completion.bash + exit +fi + # Allow help without existence of compose file. if [[ "$#" -gt "0" && "$1" == "--help" ]]; then usage