aws-sso-cli icon indicating copy to clipboard operation
aws-sso-cli copied to clipboard

Command completion does not continue for the `exec`ed command

Open viraptor opened this issue 2 years ago • 3 comments

Output of aws-sso version:

AWS SSO CLI Version 1.9.10 -- Copyright 2021-2022 Aaron Turner
unknown (nixpkgs) built at unknown

Describe the bug: When using command completion, the state doesn't "reset" after exec ... --

To Reproduce:

  1. aws-sso exec -p <TAB> - I get profiles completion
  2. aws-sso exec -p some-profile -- aws <TAB> - no completion available

Expected behavior: exec ... -- should go back to normal completion. I expect: aws-sso exec -p some-profile -- aws <TAB> to show me the awscli options.

Desktop (please complete the following information):

  • OS: macOS
  • Version 13.4.1
  • shell: zsh 5.9

viraptor avatar Jun 26 '23 04:06 viraptor

Can you provide an example of another command which calls another command in this manner and supports auto-completion?

synfinatic avatar Jul 27 '23 17:07 synfinatic

sudo does it for example. I believe it's done here https://github.com/scop/bash-completion/blob/master/completions/sudo#L17 (not 100% sure though, I'm not great with bash completions)

I ended up writing a custom zsh completion after all - feel free to reuse:

#compdef aws-sso

function _aws-sso() {
  local context state line curcontext="$curcontext"
  local global_args
  global_args=(
    '(-h --help)'{-h,--help}'[Help]'
    '(-b --browser)'{-b,--browser}'[Browser]: :'
    '--config[Config file]: :_files'
    '(-L --level)'{-L,--level}'[Logging level]: :(error warn info debug trace)'
    '--lines[Print line number in logs]'
    '(-u --url-action)'{-u,--url-action}'[How to handle URLs]: :(clip exec open print printurl granted-containers open-url-in-container)'
    '(-S --sso)'{-S,--sso}'[Override default AWS SSO Instance]: :'
    '--sts-refresh[Force refresh of STS Token Credentials]'
    '--no-config-check[Disable automatic ~/.aws/config updates]'
    '--threads[Override number of threads for talking to AWS]: :_numbers'
  )

  _arguments -C \
    $global_args \
    '1: : _aws-sso_cmds' \
    '*::arg:->args' && ret=0

  case "$state" in
    (args)
      local subcommand; subcommand="$words[1]"
      curcontext="${curcontext%:*:*}:aws-sso-cmd-$subcommand:"
      case "$subcommand" in
        (exec)
          _arguments -S -C \
            $global_args \
            '(-a --arn)'{-a,--arn}'[ARN of role to assume]: :' \
            '(-A --account)'{-A,--account}'[AWS AccountID of role to assume]: :' \
            '(-R --role)'{-R,--role}'[Name of AWS Role to assume]: :' \
            '(-p --profile)'{-p,--profile}'[Name of AWS Profile to assume]: :_aws-sso_profiles' \
            '(-n --no-region)'{-n,--no-region}'[Do not set AWS_DEFAULT_REGION from config.yaml]' \
            '*::cmd:->cmd' && ret=0
          case $state in
            (cmd)
              _normal -P
              ;;
          esac
          ;;

        (console)
          _arguments -C \
            $global_args \
            '--region[AWS Region]: :' \
            '(-d --duration)'{-d,--duration}'[AWS Session duration in minutes]: :_numbers -u minutes' \
            '(-P --prompt)'{-P,--prompt}'[Force interactive prompt to select role]' \
            '(-a --arn)'{-a,--arn}'[ARN of role to assume]: :' \
            '(-A --account)'{-A,--account}'[AWS AccountID of role to assume]: :' \
            '(-R --role)'{-R,--role}'[Name of AWS Role to assume]: :' \
            '(-p --profile)'{-p,--profile}'[Name of AWS Profile to assume]: :_aws-sso_profiles' \
            && ret=0
          ;;

        (eval)
          _arguments -C \
            $global_args \
            '(-a --arn)'{-a,--arn}'[ARN of role to assume]: :' \
            '(-A --account)'{-A,--account}'[AWS AccountID of role to assume]: :' \
            '(-R --role)'{-R,--role}'[Name of AWS Role to assume]: :' \
            '(-p --profile)'{-p,--profile}'[Name of AWS Profile to assume]: :_aws-sso_profiles' \
            '(-c --clear)'{-c,--clear}'[Generate "unset XXXX" commands to clear environment]' \
            '(-n --no-region)'{-n,--no-region}'[Do not set AWS_DEFAULT_REGION from config.yaml]' \
            '(-r --refresh)'{-r,--refresh}'[Refresh current IAM credentials]' \
            && ret=0
          ;;

        (flush)
          _arguments -C \
            $global_args \
            '(-t --type)'{-t,--type}'[Type of credentials to flush]: :(sts sso all)' \
            && ret=0
          ;;
        
        (list)
          _aws-sso_fields
          ;;
      esac
      ;;
  esac

  return ret
}

_aws-sso_cmds() {
  local commands
  commands=("${(@f)$(aws-sso --help | gawk '/Commands:/ {enable="true"} /^  \S/ && enable == "true" {scmd=$1} /^    \S/ && enable == "true" {sub(/^    /,"") ; print scmd ":" $0}')}")
  _describe -t commands 'command' commands "$@"
}

_aws-sso_fields() {
  local fields
  fields=("${(@f)$(aws-sso list -f | gawk '/\S/ && enable=="true" {sub(/\s*\|\s*/, ":"); print} /^=/ {enable="true"}')}")
  _describe -t fields 'fields' fields
}

_aws-sso_profiles() {
  local profiles
  profiles=("${(@f)$(aws-sso list --csv Profile)}")
  _describe -t profiles 'profiles' profiles
}

The magic part here is the

          case $state in
            (cmd)
              _normal -P

viraptor avatar Jul 28 '23 01:07 viraptor

opened: https://github.com/WillAbides/kongplete/issues/21

synfinatic avatar Oct 17 '23 00:10 synfinatic