From 52b51235e086c592b05abebb12983830c1e84174 Mon Sep 17 00:00:00 2001 From: montag451 Date: Sun, 1 Dec 2024 21:20:20 +0100 Subject: [PATCH] incus: Improve completion for `file push` and `file pull` Signed-off-by: montag451 --- cmd/incus/completion.go | 58 +++++++++++++++++++++++++++++++++++++++++ cmd/incus/file.go | 18 +++++++++++++ 2 files changed, 76 insertions(+) diff --git a/cmd/incus/completion.go b/cmd/incus/completion.go index 31814df102..f5b850fde5 100644 --- a/cmd/incus/completion.go +++ b/cmd/incus/completion.go @@ -2,6 +2,8 @@ package main import ( "fmt" + "io/fs" + "path/filepath" "regexp" "strings" @@ -1222,3 +1224,59 @@ func (g *cmdGlobal) cmpStoragePoolVolumes(poolName string) ([]string, cobra.Shel return volumes, cobra.ShellCompDirectiveNoFileComp } + +func (g *cmdGlobal) cmpFiles(toComplete string, includeLocalFiles bool) ([]string, cobra.ShellCompDirective) { + instances, directives := g.cmpInstances(toComplete) + for i := range instances { + if strings.HasSuffix(instances[i], ":") { + continue + } + + instances[i] += "/" + } + + if len(instances) > 0 { + directives |= cobra.ShellCompDirectiveNoSpace + } + + if !includeLocalFiles { + return instances, directives + } + + var files []string + switch toComplete { + case ".": + files = append(files, "./") + fallthrough + case "..": + files = append(files, "../") + directives |= cobra.ShellCompDirectiveNoSpace + } + + dir, file := filepath.Split(toComplete) + root := filepath.Dir(dir) + _ = filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { + if err != nil || path == root { + return err + } + + base := filepath.Base(path) + if strings.HasPrefix(base, file) { + file := dir + base + if d.IsDir() { + file += string(filepath.Separator) + directives |= cobra.ShellCompDirectiveNoSpace + } + + files = append(files, file) + } + + if d.IsDir() { + return fs.SkipDir + } + + return nil + }) + + return append(instances, files...), directives +} diff --git a/cmd/incus/file.go b/cmd/incus/file.go index e9424d186c..1d623c8c3f 100644 --- a/cmd/incus/file.go +++ b/cmd/incus/file.go @@ -475,8 +475,17 @@ func (c *cmdFilePull) Command() *cobra.Command { cmd.Flags().BoolVarP(&c.file.flagMkdir, "create-dirs", "p", false, i18n.G("Create any directories necessary")) cmd.Flags().BoolVarP(&c.file.flagRecursive, "recursive", "r", false, i18n.G("Recursively transfer files")) + cmd.RunE = c.Run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpFiles(toComplete, false) + } + + return c.global.cmpFiles(toComplete, true) + } + return cmd } @@ -697,8 +706,17 @@ func (c *cmdFilePush) Command() *cobra.Command { cmd.Flags().IntVar(&c.file.flagUID, "uid", -1, i18n.G("Set the file's uid on push")+"``") cmd.Flags().IntVar(&c.file.flagGID, "gid", -1, i18n.G("Set the file's gid on push")+"``") cmd.Flags().StringVar(&c.file.flagMode, "mode", "", i18n.G("Set the file's perms on push")+"``") + cmd.RunE = c.Run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return nil, cobra.ShellCompDirectiveDefault + } + + return c.global.cmpFiles(toComplete, true) + } + return cmd }