github.com/saucelabs/saucectl@v0.175.1/internal/cmd/apit/vault.go (about) 1 package apit 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 8 "github.com/AlecAivazis/survey/v2" 9 "github.com/mattn/go-isatty" 10 "github.com/saucelabs/saucectl/internal/apitest" 11 "github.com/spf13/cobra" 12 ) 13 14 type ResolvedProject struct { 15 apitest.ProjectMeta 16 Hooks []apitest.Hook 17 } 18 19 var ( 20 selectedProject ResolvedProject 21 ) 22 23 func VaultCommand(preRunE func(cmd *cobra.Command, args []string) error) *cobra.Command { 24 var projectName string 25 var err error 26 cmd := &cobra.Command{ 27 Use: "vault", 28 Short: "Commands for interacting with API Testing project vaults", 29 SilenceUsage: true, 30 PersistentPreRunE: func(cmd *cobra.Command, args []string) error { 31 if preRunE != nil { 32 err = preRunE(cmd, args) 33 if err != nil { 34 return err 35 } 36 } 37 selectedProject, err = resolve(projectName) 38 if err != nil { 39 return err 40 } 41 return nil 42 }, 43 } 44 45 cmd.PersistentFlags().StringVar(&projectName, "project", "", "The name of the project the vault belongs to.") 46 47 cmd.AddCommand( 48 GetCommand(), 49 SetVariableCommand(), 50 GetVariableCommand(), 51 GetSnippetCommand(), 52 SetSnippetCommand(), 53 ListFilesCommand(), 54 DownloadFileCommand(), 55 UploadFileCommand(), 56 DeleteFileCommand(), 57 ) 58 return cmd 59 } 60 61 func projectSurvey(names []string) (string, error) { 62 var selection string 63 prompt := &survey.Select{ 64 Help: "Select the project the vault belongs to. Use --project to define a project in your command and skip this selection", 65 Message: "Select a vault by project name", 66 Options: names, 67 } 68 69 err := survey.AskOne(prompt, &selection) 70 71 return selection, err 72 } 73 74 func isTerm(fd uintptr) bool { 75 return isatty.IsTerminal(fd) || isatty.IsCygwinTerminal(fd) 76 } 77 78 func resolve(projectName string) (ResolvedProject, error) { 79 projects, err := apitesterClient.GetProjects(context.Background()) 80 if projectName == "" { 81 if !isTerm(os.Stdin.Fd()) || !isTerm(os.Stdout.Fd()) { 82 return ResolvedProject{}, fmt.Errorf("no project specified, use --project to choose a project by name") 83 } 84 var names []string 85 for _, p := range projects { 86 names = append(names, p.Name) 87 } 88 projectName, err = projectSurvey(names) 89 } 90 if err != nil { 91 return ResolvedProject{}, err 92 } 93 var project apitest.ProjectMeta 94 for _, p := range projects { 95 if p.Name == projectName { 96 project = p 97 break 98 } 99 } 100 if project.ID == "" { 101 return ResolvedProject{}, fmt.Errorf("could not find project named %s", projectName) 102 } 103 104 hooks, err := apitesterClient.GetHooks(context.Background(), project.ID) 105 if err != nil { 106 return ResolvedProject{}, err 107 } 108 if len(hooks) == 0 { 109 return ResolvedProject{}, fmt.Errorf("project named %s has no hooks configured", projectName) 110 } 111 112 return ResolvedProject{ 113 ProjectMeta: project, 114 Hooks: hooks, 115 }, nil 116 }