synfinatic / aws-sso-cli

A powerful tool for using AWS Identity Center for the CLI and web console.
https://synfinatic.github.io/aws-sso-cli/
GNU General Public License v3.0
458 stars 56 forks source link

Update aws-sso.fish to add completion helper for aws-sso-profile #865

Closed drmikecrowe closed 3 months ago

drmikecrowe commented 4 months ago

I think this add a missing fish completion for aws-sso-profile command to fish completions. I'm using NixOS, so I had to add this from a test script, but I'm pretty confident this is useful.

As an side note, the following is how I'm configuring the completions in my NixOS config. If we had a discussion area or wiki, this might be useful to others. Open to suggestions as to how you want to share:


      home.packages = with pkgs; [aws-sso-cli];
      programs = {
        bash.initExtra = ''
          __aws_sso_profile_complete() {
              COMPREPLY=()
              local _args=''${AWS_SSO_HELPER_ARGS:- -L error --no-config-check}
              local cur
              _get_comp_words_by_ref -n : cur

              COMPREPLY=($(compgen -W '$(${pkgs.aws-sso-cli}/bin/.aws-sso-wrapped $_args list --csv -P "Profile=$cur" Profile)' -- ""))

              __ltrim_colon_completions "$cur"
          }

          aws-sso-profile() {
              local _args=''${AWS_SSO_HELPER_ARGS:- -L error --no-config-check}
              if [ -n "$AWS_PROFILE" ]; then
                  echo "Unable to assume a role while AWS_PROFILE is set"
                  return 1
              fi
              eval $(${pkgs.aws-sso-cli}/bin/.aws-sso-wrapped $_args eval -p "$1")
              if [ "$AWS_SSO_PROFILE" != "$1" ]; then
                  return 1
              fi
          }

          aws-sso-clear() {
              local _args=''${AWS_SSO_HELPER_ARGS:- -L error --no-config-check}
              if [ -z "$AWS_SSO_PROFILE" ]; then
                  echo "AWS_SSO_PROFILE is not set"
                  return 1
              fi
              eval $(aws-sso eval $_args -c)
          }

          complete -F __aws_sso_profile_complete aws-sso-profile
          complete -C ${pkgs.aws-sso-cli}/bin/.aws-sso-wrapped aws-sso
        '';

        fish.interactiveShellInit = ''
          function __complete_aws-sso
              set -lx COMP_LINE (commandline -cp)
              test -z (commandline -ct)
              and set COMP_LINE "$COMP_LINE "
              ${pkgs.aws-sso-cli}/bin/.aws-sso-wrapped
          end
          complete -f -c aws-sso -a "(__complete_aws-sso)"

          function aws-sso-profile
            set --local _args (string split -- ' ' $AWS_SSO_HELPER_ARGS)
            set -q AWS_SSO_HELPER_ARGS; or set --local _args -L error --no-config-check
            if [ -n "$AWS_PROFILE" ]
                echo "Unable to assume a role while AWS_PROFILE is set"
                return 1
            end
            set -x
            eval $(${pkgs.aws-sso-cli}/bin/.aws-sso-wrapped $_args eval -p $argv[1])
            if [ "$AWS_SSO_PROFILE" != "$1" ]
                set +x
                return 1
            end
            set +x
          end

          function __aws_sso_profile_complete
            set --local _args (string split -- ' ' $AWS_SSO_HELPER_ARGS)
            set -q AWS_SSO_HELPER_ARGS; or set --local _args -L error --no-config-check
            set -l cur (commandline -t)

            set -l cmd "${pkgs.aws-sso-cli}/bin/.aws-sso-wrapped list $_args --csv -P Profile=$cur Profile"
            for completion in (eval $cmd)
              printf "%s\n" $completion
            end
          end
          complete -f -c aws-sso-profile -f -a '(__aws_sso_profile_complete)'

          function aws-sso-clear
            set --local _args (string split -- ' ' $AWS_SSO_HELPER_ARGS)
            set -q AWS_SSO_HELPER_ARGS; or set --local _args -L error
            if [ -z "$AWS_SSO_PROFILE" ]
                echo "AWS_SSO_PROFILE is not set"
                return 1
            end
            eval "$(${pkgs.aws-sso-cli}/bin/.aws-sso-wrapped $_args eval -c | string replace "unset" "set --erase" )"
          end
        '';
      };
synfinatic commented 4 months ago

@drmikecrowe If you feel there is information useful to others, there is the docs directory and you can share it there. maybe create a NixOS page?

That said, I don't run NixOS and not sure how I can test this sorta thing? Any suggestions?

synfinatic commented 4 months ago

I should also mention that tab completion with fish for items with a : in them (often used for profiles) does not seem to work. The issue is here: https://github.com/synfinatic/aws-sso-cli/blob/main/internal/predictor/predictor.go#L174, where the colon is escaped for bash/zsh. But this is not necessary and breaks fish. Unfortunately, I've get to discover a way to detect the user running the fish shell... attempts to use os.Getenv("FISH_VERSION") don't seem to work. Curious if you know any tricks?

drmikecrowe commented 4 months ago

Curious if you know any tricks?

How about __fish_config_dir?

root@nas ~# echo $__fish_config_dir
/root/.config/fish
synfinatic commented 4 months ago

Nope. None of the fish specific variables seem to be exported?

drmikecrowe commented 3 months ago

The only other idea I have is to pass in an environment variable indicating fish. Something like:

set -l cmd "__FISH_SHELL=1 {{ .Executable }} list $_args --csv -P Profile=$cur Profile"

Can you share where it breaks? I changed my profiles to use : and I'm not sure I see what the issue is yet

synfinatic commented 3 months ago

if you do aws-sso exec -p <tab> and then when it gets to a colon, aws-sso wants to escape it (foo\:bar), but fish doing something different than bash/zsh and messing it up: foo\\:bar which then doesn't match.

anyways, i opened a ticket with fish and see what they say: https://github.com/fish-shell/fish-shell/issues/10553