github.com/jfrog/jfrog-cli-go@v1.22.1-0.20200318093948-4826ef344ffd/artifactory/utils/argsutils.go (about) 1 package utils 2 3 import ( 4 "errors" 5 "fmt" 6 "strconv" 7 "strings" 8 9 "github.com/jfrog/jfrog-client-go/utils/errorutils" 10 ) 11 12 // Removes the provided flag and value from the command arguments 13 func RemoveFlagFromCommand(args *[]string, flagIndex, flagValueIndex int) { 14 argsCopy := *args 15 // Remove flag from Command if required. 16 if flagIndex != -1 { 17 argsCopy = append(argsCopy[:flagIndex], argsCopy[flagValueIndex+1:]...) 18 } 19 *args = argsCopy 20 } 21 22 // Find value of required CLI flag in Command. 23 // If flag does not exist, the returned index is -1 and nil is returned as the error. 24 // Return values: 25 // err - error if flag exists but failed to extract its value. 26 // flagIndex - index of flagName in Command. 27 // flagValueIndex - index in Command in which the value of the flag exists. 28 // flagValue - value of flagName. 29 func FindFlag(flagName string, args []string) (flagIndex, flagValueIndex int, flagValue string, err error) { 30 flagIndex = -1 31 flagValueIndex = -1 32 for index, arg := range args { 33 // Check current argument. 34 if !strings.HasPrefix(arg, flagName) { 35 continue 36 } 37 38 // Get flag value. 39 flagValue, flagValueIndex, err = getFlagValueAndValueIndex(flagName, args, index) 40 if err != nil { 41 return 42 } 43 44 // If was not the correct flag, continue looking. 45 if flagValueIndex == -1 { 46 continue 47 } 48 49 // Return value. 50 flagIndex = index 51 return 52 } 53 54 // Flag not found. 55 return 56 } 57 58 // Boolean flag can be provided in one of the following forms: 59 // 1. --flag=value, where value can be true/false 60 // 2. --flag, here the value is true 61 // Return values: 62 // flagIndex - index of flagName in args. 63 // flagValue - value of flagName. 64 // err - error if flag exists, but we failed to extract its value. 65 // If flag does not exist flagIndex = -1 with false value and nil error. 66 func FindBooleanFlag(flagName string, args []string) (flagIndex int, flagValue bool, err error) { 67 var arg string 68 for flagIndex, arg = range args { 69 if strings.HasPrefix(arg, flagName) { 70 value := strings.TrimPrefix(arg, flagName) 71 if len(value) == 0 { 72 flagValue = true 73 } else if strings.HasPrefix(value, "=") { 74 flagValue, err = strconv.ParseBool(value[1:]) 75 } else { 76 continue 77 } 78 return 79 } 80 } 81 return -1, false, nil 82 } 83 84 // Get the provided flag's value, and the index of the value. 85 // Value-index can either be same as flag's index, or the next one. 86 // Return error if flag is found, but couldn't extract value. 87 // If the provided index doesn't contain the searched flag, return flagIndex = -1. 88 func getFlagValueAndValueIndex(flagName string, args []string, flagIndex int) (flagValue string, flagValueIndex int, err error) { 89 indexValue := args[flagIndex] 90 91 // Check if flag is in form '--key=value' 92 indexValue = strings.TrimPrefix(indexValue, flagName) 93 if strings.HasPrefix(indexValue, "=") { 94 if len(indexValue) > 1 { 95 return indexValue[1:], flagIndex, nil 96 } 97 return "", -1, errorutils.CheckError(errors.New(fmt.Sprintf("Flag %s is provided with empty value.", flagName))) 98 } 99 100 // Check if it is a different flag with same prefix, e.g --server-id-another 101 if len(indexValue) > 0 { 102 return "", -1, nil 103 } 104 105 // If reached here, expect the flag value in next argument. 106 if len(args) < flagIndex+2 { 107 // Flag value does not exist. 108 return "", -1, errorutils.CheckError(errors.New(fmt.Sprintf("Failed extracting value of provided flag: %s.", flagName))) 109 } 110 111 nextIndexValue := args[flagIndex+1] 112 // Don't allow next value to be a flag. 113 if strings.HasPrefix(nextIndexValue, "-") { 114 // Flag value does not exist. 115 return "", -1, errorutils.CheckError(errors.New(fmt.Sprintf("Failed extracting value of provided flag: %s.", flagName))) 116 } 117 118 return nextIndexValue, flagIndex + 1, nil 119 } 120 121 // Find the first match of any of the provided flags in args. 122 // Return same values as FindFlag. 123 func FindFlagFirstMatch(flags, args []string) (flagIndex, flagValueIndex int, flagValue string, err error) { 124 // Look for provided flags. 125 for _, flag := range flags { 126 flagIndex, flagValueIndex, flagValue, err = FindFlag(flag, args) 127 if err != nil { 128 return 129 } 130 if flagIndex != -1 { 131 // Found value for flag. 132 return 133 } 134 } 135 return 136 } 137 138 func ExtractBuildDetailsFromArgs(args []string) (cleanArgs []string, buildConfig *BuildConfiguration, err error) { 139 var flagIndex, valueIndex int 140 buildConfig = &BuildConfiguration{} 141 cleanArgs = append([]string(nil), args...) 142 143 // Extract build-info information from the args. 144 flagIndex, valueIndex, buildConfig.BuildName, err = FindFlag("--build-name", cleanArgs) 145 if err != nil { 146 return 147 } 148 RemoveFlagFromCommand(&cleanArgs, flagIndex, valueIndex) 149 150 flagIndex, valueIndex, buildConfig.BuildNumber, err = FindFlag("--build-number", cleanArgs) 151 if err != nil { 152 return 153 } 154 RemoveFlagFromCommand(&cleanArgs, flagIndex, valueIndex) 155 156 // Retrieve build name and build number from env if both missing 157 buildConfig.BuildName, buildConfig.BuildNumber = GetBuildNameAndNumber(buildConfig.BuildName, buildConfig.BuildNumber) 158 flagIndex, valueIndex, buildConfig.Module, err = FindFlag("--module", cleanArgs) 159 if err != nil { 160 return 161 } 162 RemoveFlagFromCommand(&cleanArgs, flagIndex, valueIndex) 163 err = ValidateBuildAndModuleParams(buildConfig) 164 return 165 } 166 167 func ExtractInsecureTlsFromArgs(args []string) (cleanArgs []string, insecureTls bool, err error) { 168 cleanArgs = append([]string(nil), args...) 169 170 flagIndex, insecureTls, err := FindBooleanFlag("--insecure-tls", args) 171 if err != nil { 172 return 173 } 174 RemoveFlagFromCommand(&cleanArgs, flagIndex, flagIndex) 175 return 176 }