Skip to content
Open
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
54 changes: 41 additions & 13 deletions pkg/granted/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (

"github.com/common-fate/clio"
"github.com/fwdcloudsec/granted/internal/build"
"github.com/fwdcloudsec/granted/pkg/assume"
"github.com/fwdcloudsec/granted/pkg/config"
"github.com/fwdcloudsec/granted/pkg/shells"
"github.com/urfave/cli/v2"
Expand Down Expand Up @@ -54,26 +53,55 @@ var CompletionCommand = cli.Command{
}

func installFishCompletions(c *cli.Context) error {
assumeApp := assume.GetCliApp()
c.App.Name = build.GrantedBinaryName()
assumeApp.Name = build.AssumeScriptName()
grantedAppOutput, _ := c.App.ToFishCompletion()
assumeAppOutput, _ := assumeApp.ToFishCompletion()
combinedOutput := fmt.Sprintf("%s\n%s", grantedAppOutput, assumeAppOutput)
tmpl, err := template.ParseFS(templateFiles, "templates/*")
if err != nil {
return err
}

assumeData := AutoCompleteTemplateData{
Program: build.AssumeScriptName(),
}
assumeBuf := new(bytes.Buffer)
err = tmpl.ExecuteTemplate(assumeBuf, "fish_autocomplete_assume.tmpl", assumeData)
if err != nil {
return err
}

grantedData := AutoCompleteTemplateData{
Program: build.GrantedBinaryName(),
}
grantedBuf := new(bytes.Buffer)
err = tmpl.ExecuteTemplate(grantedBuf, "fish_autocomplete_granted.tmpl", grantedData)
if err != nil {
return err
}

// try to fetch user home dir
user, _ := user.Current()
usr, _ := user.Current()
completionsDir := path.Join(usr.HomeDir, ".config/fish/completions")

// ensure the completions directory exists
err = os.MkdirAll(completionsDir, 0755)
if err != nil {
return fmt.Errorf("something went wrong when creating fish completions directory: %s", err.Error())
}

executableDir := path.Join(user.HomeDir, ".config/fish/completions", fmt.Sprintf("%s.fish", c.App.Name))
assumeFile := path.Join(completionsDir, fmt.Sprintf("%s.fish", assumeData.Program))
err = os.WriteFile(assumeFile, assumeBuf.Bytes(), 0600)
if err != nil {
return fmt.Errorf("something went wrong when saving fish autocompletions: %s", err.Error())
}

// Try to create a file
err := os.WriteFile(executableDir, []byte(combinedOutput), 0600)
grantedFile := path.Join(completionsDir, fmt.Sprintf("%s.fish", grantedData.Program))
err = os.WriteFile(grantedFile, grantedBuf.Bytes(), 0600)
if err != nil {
return fmt.Errorf("something went wrong when saving fish autocompletions: %s", err.Error())
}

clio.Success("Fish autocompletions generated successfully")
clio.Info("To use these completions please run the executable:")
clio.Infof("source %s", executableDir)
clio.Info("To use these completions please run:")
clio.Infof("source %s", assumeFile)
clio.Infof("source %s", grantedFile)
return nil
}

Expand Down
18 changes: 18 additions & 0 deletions pkg/granted/templates/fish_autocomplete_assume.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Fish completion for {{ .Program }} (assume)
# Dynamically calls {{ .Program }}go --generate-bash-completion to list profiles and flags

# Disable file completions by default for the assume command
complete -c {{ .Program }} -f

complete -c {{ .Program }} -a '(
set -l tokens (commandline -opc)
set -l current (commandline -ct)

# pass all tokens except the command name, plus --generate-bash-completion
set -l args
if test (count $tokens) -gt 1
set args $tokens[2..-1]
end

FORCE_NO_ALIAS=true {{ .Program }}go $args --generate-bash-completion 2>/dev/null
)'
18 changes: 18 additions & 0 deletions pkg/granted/templates/fish_autocomplete_granted.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Fish completion for {{ .Program }} (granted)
# Dynamically calls {{ .Program }} --generate-bash-completion to list subcommands and flags

# Disable file completions by default for the granted command
complete -c {{ .Program }} -f

complete -c {{ .Program }} -a '(
set -l tokens (commandline -opc)
set -l current (commandline -ct)

# pass all tokens except the command name, plus --generate-bash-completion
set -l args
if test (count $tokens) -gt 1
set args $tokens[2..-1]
end

_CLI_ZSH_AUTOCOMPLETE_HACK=1 {{ .Program }} $args --generate-bash-completion 2>/dev/null
)'