github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/integration/helpers/command.go (about) 1 package helpers 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "os/exec" 8 "regexp" 9 "strings" 10 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13 . "github.com/onsi/gomega/gexec" 14 ) 15 16 const ( 17 DebugCommandPrefix = "\nCMD>" 18 DebugCommandPrefixWithDir = "\nCMD %s>" 19 DebugOutPrefix = "OUT: " 20 DebugErrPrefix = "ERR: " 21 ) 22 23 var isPass = regexp.MustCompile("(?i)password|token") 24 25 // CF runs a 'cf' command with given arguments. 26 func CF(args ...string) *Session { 27 WriteCommand("", nil, args) 28 session, err := Start( 29 exec.Command("cf", args...), 30 NewPrefixedWriter(DebugOutPrefix, GinkgoWriter), 31 NewPrefixedWriter(DebugErrPrefix, GinkgoWriter)) 32 Expect(err).NotTo(HaveOccurred()) 33 return session 34 } 35 36 // CFEnv represents configuration for running a 'cf' command. It allows us to 37 // run a 'cf' command with a custom working directory, specific environment 38 // variables, and stdin. 39 type CFEnv struct { 40 WorkingDirectory string 41 EnvVars map[string]string 42 stdin io.Reader 43 } 44 45 // CustomCF runs a 'cf' command with a custom environment and given arguments. 46 func CustomCF(cfEnv CFEnv, args ...string) *Session { 47 command := exec.Command("cf", args...) 48 if cfEnv.stdin != nil { 49 command.Stdin = cfEnv.stdin 50 } 51 if cfEnv.WorkingDirectory != "" { 52 command.Dir = cfEnv.WorkingDirectory 53 } 54 55 if cfEnv.EnvVars != nil { 56 env := os.Environ() 57 for key, val := range cfEnv.EnvVars { 58 env = AddOrReplaceEnvironment(env, key, val) 59 } 60 command.Env = env 61 } 62 63 WriteCommand("", cfEnv.EnvVars, args) 64 session, err := Start( 65 command, 66 NewPrefixedWriter(DebugOutPrefix, GinkgoWriter), 67 NewPrefixedWriter(DebugErrPrefix, GinkgoWriter)) 68 Expect(err).NotTo(HaveOccurred()) 69 return session 70 } 71 72 // DebugCustomCF runs a 'cf' command with a custom environment and given 73 // arguments, with CF_LOG_LEVEL set to 'debug'. 74 func DebugCustomCF(cfEnv CFEnv, args ...string) *Session { 75 if cfEnv.EnvVars == nil { 76 cfEnv.EnvVars = map[string]string{} 77 } 78 cfEnv.EnvVars["CF_LOG_LEVEL"] = "debug" 79 80 return CustomCF(cfEnv, args...) 81 } 82 83 // CFWithStdin runs a 'cf' command with a custom stdin and given arguments. 84 func CFWithStdin(stdin io.Reader, args ...string) *Session { 85 WriteCommand("", nil, args) 86 command := exec.Command("cf", args...) 87 command.Stdin = stdin 88 session, err := Start( 89 command, 90 NewPrefixedWriter(DebugOutPrefix, GinkgoWriter), 91 NewPrefixedWriter(DebugErrPrefix, GinkgoWriter)) 92 Expect(err).NotTo(HaveOccurred()) 93 return session 94 } 95 96 // CFWithEnv runs a 'cf' command with specified environment variables and given arguments. 97 func CFWithEnv(envVars map[string]string, args ...string) *Session { 98 return CustomCF(CFEnv{EnvVars: envVars}, args...) 99 } 100 101 // WriteCommand prints the working directory, the environment variables, and 102 // 'cf' with the given arguments. Environment variables that are passwords will 103 // be redacted. 104 func WriteCommand(workingDir string, env map[string]string, args []string) { 105 start := DebugCommandPrefix 106 if workingDir != "" { 107 start = fmt.Sprintf(DebugCommandPrefixWithDir, workingDir) 108 } 109 110 display := []string{ 111 start, 112 } 113 114 for key, val := range env { 115 if isPass.MatchString(key) { 116 val = "*****" 117 } 118 display = append(display, fmt.Sprintf("%s=%s", key, val)) 119 } 120 121 display = append(display, "cf") 122 display = append(display, args...) 123 GinkgoWriter.Write([]byte(strings.Join(append(display, "\n"), " "))) 124 }