├── .gitignore ├── LICENSE ├── README.md ├── cmd ├── dirs.go ├── files.go └── root.go ├── common └── common.go ├── dirs └── dirs.go ├── files └── files.go ├── go.mod ├── go.sum ├── main.go └── playground └── dirScan.go /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 Matt J. Wiater 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # golangcliscaffold 2 | 3 | Learn how to create your first Golang CLI tool with Cobra and Viper. This step-by-step guide will show you how to bootstrap your project, add commands and flags, and create a usable CLI tool. By the end of this article, you'll have a working CLI tool that you can use to automate your tasks. 4 | 5 | ## Tutorial Article 6 | 7 | [Step By Step: Using Cobra and Viper to Create Your First Golang CLI Tool](https://betterprogramming.pub/step-by-step-using-cobra-and-viper-to-create-your-first-golang-cli-tool-8050d7675093) 8 | 9 | ## Command 10 | 11 | ### getsize 12 | 13 | `go build -o bin/getsize && ./bin/getsize --help` 14 | 15 | ``` 16 | This command will display the size of a directory with several different options. 17 | 18 | Usage: 19 | getsize [command] 20 | 21 | Available Commands: 22 | completion Generate the autocompletion script for the specified shell 23 | dirs Show the largest directories in the given path. 24 | files Show the largest files in the given path. 25 | help Help about any command 26 | 27 | Flags: 28 | -d, --debug Display debugging output in the console. (default: false) 29 | -h, --help help for getsize 30 | --highlight int Highlight files/directories over this threshold, in MB (default 500) 31 | -p, --path string Define the path to scan. (default "/home/matt") 32 | -v, --verbose Display more verbose output in console output. (default: false) 33 | 34 | Use "getsize [command] --help" for more information about a command. 35 | `````` 36 | 37 | ## Subcommands 38 | 39 | ### getsize files 40 | 41 | `go build -o bin/getsize && ./bin/getsize files --help` 42 | 43 | ``` 44 | Quickly scan a directory and find large files. . Use the flags below to target the output. 45 | 46 | Usage: 47 | getsize files [flags] 48 | 49 | Flags: 50 | -f, --filecount int Limit the number of files returned (default 10) 51 | -h, --help help for files 52 | --minfilesize int Minimum size for files in search in MB. (default 50) 53 | 54 | Global Flags: 55 | -d, --debug Display debugging output in the console. (default: false) 56 | --highlight int Highlight files/directories over this threshold, in MB (default 500) 57 | -p, --path string Define the path to scan. (default "/home/matt") 58 | -v, --verbose Display more verbose output in console output. (default: false) 59 | ``` 60 | 61 | ### getsize dirs 62 | 63 | `go build -o bin/getsize && ./bin/getsize dirs --help` 64 | 65 | ``` 66 | 67 | Quickly scan a directory and find large directories. Use the flags below to target the output. 68 | 69 | Usage: 70 | getsize dirs [flags] 71 | 72 | Flags: 73 | --depth int Depth of directory tree to display (default 2) 74 | -h, --help help for dirs 75 | --mindirsize int Only display directories larger than this threshold in MB. (default 100) 76 | 77 | Global Flags: 78 | -d, --debug Display debugging output in the console. (default: false) 79 | --highlight int Highlight files/directories over this threshold, in MB (default 500) 80 | -p, --path string Define the path to scan. (default "/home/matt") 81 | -v, --verbose Display more verbose output in console output. (default: false) 82 | 83 | ``` 84 | -------------------------------------------------------------------------------- /cmd/dirs.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2023 NAME HERE 3 | 4 | */ 5 | package cmd 6 | 7 | import ( 8 | "github.com/mwiater/golangcliscaffold/common" 9 | "github.com/mwiater/golangcliscaffold/dirs" 10 | "github.com/spf13/cobra" 11 | "github.com/spf13/viper" 12 | ) 13 | 14 | var Depth int 15 | var Mindirsize int 16 | 17 | // dirsCmd represents the dirs command 18 | var dirsCmd = &cobra.Command{ 19 | Use: "dirs", 20 | Short: "Show the largest directories in the given path.", 21 | Long: `Quickly scan a directory and find large directories. Use the flags below to target the output.`, 22 | Run: func(cmd *cobra.Command, args []string) { 23 | if Debug { 24 | common.LogFlags() 25 | } 26 | dirsFound, _ := dirs.ReadDirDepth(Path) 27 | dirs.PrintResults(dirsFound) 28 | }, 29 | } 30 | 31 | func init() { 32 | rootCmd.AddCommand(dirsCmd) 33 | 34 | dirsCmd.PersistentFlags().IntVarP(&Depth, "depth", "", 2, "Depth of directory tree to display") 35 | viper.BindPFlag("depth", dirsCmd.PersistentFlags().Lookup("depth")) 36 | 37 | dirsCmd.PersistentFlags().IntVarP(&Mindirsize, "mindirsize", "", 100, "Only display directories larger than this threshold in MB.") 38 | viper.BindPFlag("mindirsize", dirsCmd.PersistentFlags().Lookup("mindirsize")) 39 | } 40 | -------------------------------------------------------------------------------- /cmd/files.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/mwiater/golangcliscaffold/common" 7 | "github.com/mwiater/golangcliscaffold/files" 8 | 9 | "github.com/spf13/cobra" 10 | "github.com/spf13/viper" 11 | ) 12 | 13 | var Path string 14 | var Filecount int 15 | var Minfilesize int64 16 | 17 | // filesCmd represents the files command 18 | var filesCmd = &cobra.Command{ 19 | Use: "files", 20 | Short: "Show the largest files in the given path.", 21 | Long: `Quickly scan a directory and find large files. . Use the flags below to target the output.`, 22 | Run: func(cmd *cobra.Command, args []string) { 23 | if Debug { 24 | common.LogFlags() 25 | } 26 | 27 | filesFound, err := files.ReadDirRecursively(Path) 28 | if err != nil { 29 | fmt.Println(err) 30 | return 31 | } 32 | 33 | if Filecount > len(filesFound) { 34 | Filecount = len(filesFound) 35 | } 36 | 37 | filesFound = filesFound[0:Filecount] 38 | files.PrintResults(filesFound) 39 | }, 40 | } 41 | 42 | func init() { 43 | rootCmd.AddCommand(filesCmd) 44 | 45 | filesCmd.PersistentFlags().IntVarP(&Filecount, "filecount", "f", 10, "Limit the number of files returned") 46 | viper.BindPFlag("filecount", filesCmd.PersistentFlags().Lookup("filecount")) 47 | 48 | filesCmd.PersistentFlags().Int64VarP(&Minfilesize, "minfilesize", "", 50, "Minimum size for files in search in MB.") 49 | viper.BindPFlag("minfilesize", filesCmd.PersistentFlags().Lookup("minfilesize")) 50 | } 51 | -------------------------------------------------------------------------------- /cmd/root.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/spf13/cobra" 7 | "github.com/spf13/viper" 8 | ) 9 | 10 | var Verbose bool 11 | var Debug bool 12 | var Highlight int 13 | 14 | var rootCmd = &cobra.Command{ 15 | Use: "getsize", 16 | Short: "List the size of a local directory.", 17 | Long: `This command will display the size of a directory with several different options.`, 18 | } 19 | 20 | func Execute() { 21 | err := rootCmd.Execute() 22 | if err != nil { 23 | os.Exit(1) 24 | } 25 | 26 | } 27 | 28 | func init() { 29 | rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "Display more verbose output in console output. (default: false)") 30 | viper.BindPFlag("verbose", rootCmd.PersistentFlags().Lookup("verbose")) 31 | 32 | rootCmd.PersistentFlags().BoolVarP(&Debug, "debug", "d", false, "Display debugging output in the console. (default: false)") 33 | viper.BindPFlag("debug", rootCmd.PersistentFlags().Lookup("debug")) 34 | 35 | rootCmd.PersistentFlags().IntVarP(&Highlight, "highlight", "", 500, "Highlight files/directories over this threshold, in MB") 36 | viper.BindPFlag("highlight", rootCmd.PersistentFlags().Lookup("highlight")) 37 | 38 | rootCmd.PersistentFlags().StringVarP(&Path, "path", "p", os.Getenv("HOME"), "Define the path to scan.") 39 | rootCmd.MarkFlagRequired("path") 40 | viper.BindPFlag("path", rootCmd.PersistentFlags().Lookup("path")) 41 | 42 | } 43 | -------------------------------------------------------------------------------- /common/common.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | 7 | "github.com/go-playground/colors" 8 | "github.com/gookit/color" 9 | log "github.com/sirupsen/logrus" 10 | "github.com/spf13/viper" 11 | ) 12 | 13 | func LogFlags() { 14 | for key, value := range viper.GetViper().AllSettings() { 15 | log.WithFields(log.Fields{ 16 | key: value, 17 | }).Info("Command Flag") 18 | } 19 | } 20 | 21 | func SliceContains(s []string, str string) bool { 22 | for _, v := range s { 23 | if v == str { 24 | return true 25 | } 26 | } 27 | return false 28 | } 29 | 30 | func PrettyBytes(b int64) string { 31 | const unit = 1000 32 | if b < unit { 33 | return fmt.Sprintf("%d B", b) 34 | } 35 | div, exp := int64(unit), 0 36 | for n := b / unit; n >= unit; n /= unit { 37 | div *= unit 38 | exp++ 39 | } 40 | return fmt.Sprintf("%.1f %cB", 41 | float64(b)/float64(div), "kMGTPE"[exp]) 42 | } 43 | 44 | func PrettyPrint(v interface{}) (err error) { 45 | b, err := json.MarshalIndent(v, "", " ") 46 | if err == nil { 47 | fmt.Println(string(b)) 48 | } 49 | return 50 | } 51 | 52 | func PrintColor(colorName string, colorType string, text string) { 53 | rgbColor, err := colors.Parse(AllHex[colorName]) 54 | if err != nil { 55 | panic(err) 56 | } 57 | 58 | if colorType == "background" { 59 | if rgbColor.ToRGB().IsDark() { 60 | color.HEXStyle("fff", AllHex[colorName]).Printf(" %s ", text) 61 | fmt.Println() 62 | } else { 63 | color.HEXStyle("000", AllHex[colorName]).Printf(" %s ", text) 64 | fmt.Println() 65 | } 66 | } else { 67 | color.HEXStyle(AllHex[colorName]).Printf(" %s ", text) 68 | fmt.Println() 69 | } 70 | } 71 | 72 | func ColorTest() { 73 | for colorName, colorHex := range AllHex { 74 | rgbColor, err := colors.Parse(colorHex) 75 | if err != nil { 76 | panic(err) 77 | } 78 | 79 | if rgbColor.ToRGB().IsDark() { 80 | color.HEXStyle("fff", colorHex).Printf("%-20s", colorName) 81 | fmt.Println() 82 | fmt.Println() 83 | } else { 84 | color.HEXStyle("000", colorHex).Printf("%-20s", colorName) 85 | fmt.Println() 86 | fmt.Println() 87 | } 88 | } 89 | } 90 | 91 | var AllHex = map[string]string{ 92 | "crimson": "#DC143C", 93 | "lightpink": "#FFB6C1", 94 | "lightpink1": "#FFAEB9", 95 | "lightpink2": "#EEA2AD", 96 | "lightpink3": "#CD8C95", 97 | "lightpink4": "#8B5F65", 98 | "pink": "#FFC0CB", 99 | "pink1": "#FFB5C5", 100 | "pink2": "#EEA9B8", 101 | "pink3": "#CD919E", 102 | "pink4": "#8B636C", 103 | "palevioletred": "#DB7093", 104 | "palevioletred1": "#FF82AB", 105 | "palevioletred2": "#EE799F", 106 | "palevioletred3": "#CD6889", 107 | "palevioletred4": "#8B475D", 108 | "lavenderblush1": "#FFF0F5", 109 | "lavenderblush2": "#EEE0E5", 110 | "lavenderblush3": "#CDC1C5", 111 | "lavenderblush4": "#8B8386", 112 | "violetred1": "#FF3E96", 113 | "violetred2": "#EE3A8C", 114 | "violetred3": "#CD3278", 115 | "violetred4": "#8B2252", 116 | "hotpink": "#FF69B4", 117 | "hotpink1": "#FF6EB4", 118 | "hotpink2": "#EE6AA7", 119 | "hotpink3": "#CD6090", 120 | "hotpink4": "#8B3A62", 121 | "raspberry": "#872657", 122 | "deeppink1": "#FF1493", 123 | "deeppink2": "#EE1289", 124 | "deeppink3": "#CD1076", 125 | "deeppink4": "#8B0A50", 126 | "maroon1": "#FF34B3", 127 | "maroon2": "#EE30A7", 128 | "maroon3": "#CD2990", 129 | "maroon4": "#8B1C62", 130 | "mediumvioletred": "#C71585", 131 | "violetred": "#D02090", 132 | "orchid": "#DA70D6", 133 | "orchid1": "#FF83FA", 134 | "orchid2": "#EE7AE9", 135 | "orchid3": "#CD69C9", 136 | "orchid4": "#8B4789", 137 | "thistle": "#D8BFD8", 138 | "thistle1": "#FFE1FF", 139 | "thistle2": "#EED2EE", 140 | "thistle3": "#CDB5CD", 141 | "thistle4": "#8B7B8B", 142 | "plum1": "#FFBBFF", 143 | "plum2": "#EEAEEE", 144 | "plum3": "#CD96CD", 145 | "plum4": "#8B668B", 146 | "plum": "#DDA0DD", 147 | "violet": "#EE82EE", 148 | "magenta": "#FF00FF", 149 | "magenta2": "#EE00EE", 150 | "magenta3": "#CD00CD", 151 | "magenta4": "#8B008B", 152 | "purple": "#800080", 153 | "mediumorchid": "#BA55D3", 154 | "mediumorchid1": "#E066FF", 155 | "mediumorchid2": "#D15FEE", 156 | "mediumorchid3": "#B452CD", 157 | "mediumorchid4": "#7A378B", 158 | "darkviolet": "#9400D3", 159 | "darkorchid": "#9932CC", 160 | "darkorchid1": "#BF3EFF", 161 | "darkorchid2": "#B23AEE", 162 | "darkorchid3": "#9A32CD", 163 | "darkorchid4": "#68228B", 164 | "indigo": "#4B0082", 165 | "blueviolet": "#8A2BE2", 166 | "purple1": "#9B30FF", 167 | "purple2": "#912CEE", 168 | "purple3": "#7D26CD", 169 | "purple4": "#551A8B", 170 | "mediumpurple": "#9370DB", 171 | "mediumpurple1": "#AB82FF", 172 | "mediumpurple2": "#9F79EE", 173 | "mediumpurple3": "#8968CD", 174 | "mediumpurple4": "#5D478B", 175 | "darkslateblue": "#483D8B", 176 | "lightslateblue": "#8470FF", 177 | "mediumslateblue": "#7B68EE", 178 | "slateblue": "#6A5ACD", 179 | "slateblue1": "#836FFF", 180 | "slateblue2": "#7A67EE", 181 | "slateblue3": "#6959CD", 182 | "slateblue4": "#473C8B", 183 | "ghostwhite": "#F8F8FF", 184 | "lavender": "#E6E6FA", 185 | "blue": "#0000FF", 186 | "blue2": "#0000EE", 187 | "blue3": "#0000CD", 188 | "blue4": "#00008B", 189 | "navy": "#000080", 190 | "midnightblue": "#191970", 191 | "cobalt": "#3D59AB", 192 | "royalblue": "#4169E1", 193 | "royalblue1": "#4876FF", 194 | "royalblue2": "#436EEE", 195 | "royalblue3": "#3A5FCD", 196 | "royalblue4": "#27408B", 197 | "cornflowerblue": "#6495ED", 198 | "lightsteelblue": "#B0C4DE", 199 | "lightsteelblue1": "#CAE1FF", 200 | "lightsteelblue2": "#BCD2EE", 201 | "lightsteelblue3": "#A2B5CD", 202 | "lightsteelblue4": "#6E7B8B", 203 | "lightslategray": "#778899", 204 | "slategray": "#708090", 205 | "slategray1": "#C6E2FF", 206 | "slategray2": "#B9D3EE", 207 | "slategray3": "#9FB6CD", 208 | "slategray4": "#6C7B8B", 209 | "dodgerblue1": "#1E90FF", 210 | "dodgerblue2": "#1C86EE", 211 | "dodgerblue3": "#1874CD", 212 | "dodgerblue4": "#104E8B", 213 | "aliceblue": "#F0F8FF", 214 | "steelblue": "#4682B4", 215 | "steelblue1": "#63B8FF", 216 | "steelblue2": "#5CACEE", 217 | "steelblue3": "#4F94CD", 218 | "steelblue4": "#36648B", 219 | "lightskyblue": "#87CEFA", 220 | "lightskyblue1": "#B0E2FF", 221 | "lightskyblue2": "#A4D3EE", 222 | "lightskyblue3": "#8DB6CD", 223 | "lightskyblue4": "#607B8B", 224 | "skyblue1": "#87CEFF", 225 | "skyblue2": "#7EC0EE", 226 | "skyblue3": "#6CA6CD", 227 | "skyblue4": "#4A708B", 228 | "skyblue": "#87CEEB", 229 | "deepskyblue1": "#00BFFF", 230 | "deepskyblue2": "#00B2EE", 231 | "deepskyblue3": "#009ACD", 232 | "deepskyblue4": "#00688B", 233 | "peacock": "#33A1C9", 234 | "lightblue": "#ADD8E6", 235 | "lightblue1": "#BFEFFF", 236 | "lightblue2": "#B2DFEE", 237 | "lightblue3": "#9AC0CD", 238 | "lightblue4": "#68838B", 239 | "powderblue": "#B0E0E6", 240 | "cadetblue1": "#98F5FF", 241 | "cadetblue2": "#8EE5EE", 242 | "cadetblue3": "#7AC5CD", 243 | "cadetblue4": "#53868B", 244 | "turquoise1": "#00F5FF", 245 | "turquoise2": "#00E5EE", 246 | "turquoise3": "#00C5CD", 247 | "turquoise4": "#00868B", 248 | "cadetblue": "#5F9EA0", 249 | "darkturquoise": "#00CED1", 250 | "azure1": "#F0FFFF", 251 | "azure2": "#E0EEEE", 252 | "azure3": "#C1CDCD", 253 | "azure4": "#838B8B", 254 | "lightcyan1": "#E0FFFF", 255 | "lightcyan2": "#D1EEEE", 256 | "lightcyan3": "#B4CDCD", 257 | "lightcyan4": "#7A8B8B", 258 | "paleturquoise1": "#BBFFFF", 259 | "paleturquoise2": "#AEEEEE", 260 | "paleturquoise3": "#96CDCD", 261 | "paleturquoise4": "#668B8B", 262 | "darkslategray": "#2F4F4F", 263 | "darkslategray1": "#97FFFF", 264 | "darkslategray2": "#8DEEEE", 265 | "darkslategray3": "#79CDCD", 266 | "darkslategray4": "#528B8B", 267 | "cyan/aqua": "#00FFFF", 268 | "cyan2": "#00EEEE", 269 | "cyan3": "#00CDCD", 270 | "cyan4": "#008B8B", 271 | "teal": "#008080", 272 | "mediumturquoise": "#48D1CC", 273 | "lightseagreen": "#20B2AA", 274 | "manganeseblue": "#03A89E", 275 | "turquoise": "#40E0D0", 276 | "coldgrey": "#808A87", 277 | "turquoiseblue": "#00C78C", 278 | "aquamarine1": "#7FFFD4", 279 | "aquamarine2": "#76EEC6", 280 | "aquamarine3": "#66CDAA", 281 | "aquamarine4": "#458B74", 282 | "mediumspringgreen": "#00FA9A", 283 | "mintcream": "#F5FFFA", 284 | "springgreen": "#00FF7F", 285 | "springgreen1": "#00EE76", 286 | "springgreen2": "#00CD66", 287 | "springgreen3": "#008B45", 288 | "mediumseagreen": "#3CB371", 289 | "seagreen1": "#54FF9F", 290 | "seagreen2": "#4EEE94", 291 | "seagreen3": "#43CD80", 292 | "seagreen4": "#2E8B57", 293 | "emeraldgreen": "#00C957", 294 | "mint": "#BDFCC9", 295 | "cobaltgreen": "#3D9140", 296 | "honeydew1": "#F0FFF0", 297 | "honeydew2": "#E0EEE0", 298 | "honeydew3": "#C1CDC1", 299 | "honeydew4": "#838B83", 300 | "darkseagreen": "#8FBC8F", 301 | "darkseagreen1": "#C1FFC1", 302 | "darkseagreen2": "#B4EEB4", 303 | "darkseagreen3": "#9BCD9B", 304 | "darkseagreen4": "#698B69", 305 | "palegreen": "#98FB98", 306 | "palegreen1": "#9AFF9A", 307 | "palegreen2": "#90EE90", 308 | "palegreen3": "#7CCD7C", 309 | "palegreen4": "#548B54", 310 | "limegreen": "#32CD32", 311 | "forestgreen": "#228B22", 312 | "green1": "#00FF00", 313 | "green2": "#00EE00", 314 | "green3": "#00CD00", 315 | "green4": "#008B00", 316 | "green": "#008000", 317 | "darkgreen": "#006400", 318 | "sapgreen": "#308014", 319 | "lawngreen": "#7CFC00", 320 | "chartreuse1": "#7FFF00", 321 | "chartreuse2": "#76EE00", 322 | "chartreuse3": "#66CD00", 323 | "chartreuse4": "#458B00", 324 | "greenyellow": "#ADFF2F", 325 | "darkolivegreen1": "#CAFF70", 326 | "darkolivegreen2": "#BCEE68", 327 | "darkolivegreen3": "#A2CD5A", 328 | "darkolivegreen4": "#6E8B3D", 329 | "darkolivegreen": "#556B2F", 330 | "olivedrab": "#6B8E23", 331 | "olivedrab1": "#C0FF3E", 332 | "olivedrab2": "#B3EE3A", 333 | "olivedrab3": "#9ACD32", 334 | "olivedrab4": "#698B22", 335 | "ivory1": "#FFFFF0", 336 | "ivory2": "#EEEEE0", 337 | "ivory3": "#CDCDC1", 338 | "ivory4": "#8B8B83", 339 | "beige": "#F5F5DC", 340 | "lightyellow1": "#FFFFE0", 341 | "lightyellow2": "#EEEED1", 342 | "lightyellow3": "#CDCDB4", 343 | "lightyellow4": "#8B8B7A", 344 | "lightgoldenrodyellow": "#FAFAD2", 345 | "yellow1": "#FFFF00", 346 | "yellow2": "#EEEE00", 347 | "yellow3": "#CDCD00", 348 | "yellow4": "#8B8B00", 349 | "warmgrey": "#808069", 350 | "olive": "#808000", 351 | "darkkhaki": "#BDB76B", 352 | "khaki1": "#FFF68F", 353 | "khaki2": "#EEE685", 354 | "khaki3": "#CDC673", 355 | "khaki4": "#8B864E", 356 | "khaki": "#F0E68C", 357 | "palegoldenrod": "#EEE8AA", 358 | "lemonchiffon1": "#FFFACD", 359 | "lemonchiffon2": "#EEE9BF", 360 | "lemonchiffon3": "#CDC9A5", 361 | "lemonchiffon4": "#8B8970", 362 | "lightgoldenrod1": "#FFEC8B", 363 | "lightgoldenrod2": "#EEDC82", 364 | "lightgoldenrod3": "#CDBE70", 365 | "lightgoldenrod4": "#8B814C", 366 | "banana": "#E3CF57", 367 | "gold1": "#FFD700", 368 | "gold2": "#EEC900", 369 | "gold3": "#CDAD00", 370 | "gold4": "#8B7500", 371 | "cornsilk1": "#FFF8DC", 372 | "cornsilk2": "#EEE8CD", 373 | "cornsilk3": "#CDC8B1", 374 | "cornsilk4": "#8B8878", 375 | "goldenrod": "#DAA520", 376 | "goldenrod1": "#FFC125", 377 | "goldenrod2": "#EEB422", 378 | "goldenrod3": "#CD9B1D", 379 | "goldenrod4": "#8B6914", 380 | "darkgoldenrod": "#B8860B", 381 | "darkgoldenrod1": "#FFB90F", 382 | "darkgoldenrod2": "#EEAD0E", 383 | "darkgoldenrod3": "#CD950C", 384 | "darkgoldenrod4": "#8B6508", 385 | "orange1": "#FFA500", 386 | "orange2": "#EE9A00", 387 | "orange3": "#CD8500", 388 | "orange4": "#8B5A00", 389 | "floralwhite": "#FFFAF0", 390 | "oldlace": "#FDF5E6", 391 | "wheat": "#F5DEB3", 392 | "wheat1": "#FFE7BA", 393 | "wheat2": "#EED8AE", 394 | "wheat3": "#CDBA96", 395 | "wheat4": "#8B7E66", 396 | "moccasin": "#FFE4B5", 397 | "papayawhip": "#FFEFD5", 398 | "blanchedalmond": "#FFEBCD", 399 | "navajowhite1": "#FFDEAD", 400 | "navajowhite2": "#EECFA1", 401 | "navajowhite3": "#CDB38B", 402 | "navajowhite4": "#8B795E", 403 | "eggshell": "#FCE6C9", 404 | "tan": "#D2B48C", 405 | "brick": "#9C661F", 406 | "cadmiumyellow": "#FF9912", 407 | "antiquewhite": "#FAEBD7", 408 | "antiquewhite1": "#FFEFDB", 409 | "antiquewhite2": "#EEDFCC", 410 | "antiquewhite3": "#CDC0B0", 411 | "antiquewhite4": "#8B8378", 412 | "burlywood": "#DEB887", 413 | "burlywood1": "#FFD39B", 414 | "burlywood2": "#EEC591", 415 | "burlywood3": "#CDAA7D", 416 | "burlywood4": "#8B7355", 417 | "bisque1": "#FFE4C4", 418 | "bisque2": "#EED5B7", 419 | "bisque3": "#CDB79E", 420 | "bisque4": "#8B7D6B", 421 | "melon": "#E3A869", 422 | "carrot": "#ED9121", 423 | "darkorange": "#FF8C00", 424 | "darkorange1": "#FF7F00", 425 | "darkorange2": "#EE7600", 426 | "darkorange3": "#CD6600", 427 | "darkorange4": "#8B4500", 428 | "orange": "#FF8000", 429 | "tan1": "#FFA54F", 430 | "tan2": "#EE9A49", 431 | "tan3": "#CD853F", 432 | "tan4": "#8B5A2B", 433 | "linen": "#FAF0E6", 434 | "peachpuff1": "#FFDAB9", 435 | "peachpuff2": "#EECBAD", 436 | "peachpuff3": "#CDAF95", 437 | "peachpuff4": "#8B7765", 438 | "seashell1": "#FFF5EE", 439 | "seashell2": "#EEE5DE", 440 | "seashell3": "#CDC5BF", 441 | "seashell4": "#8B8682", 442 | "sandybrown": "#F4A460", 443 | "rawsienna": "#C76114", 444 | "chocolate": "#D2691E", 445 | "chocolate1": "#FF7F24", 446 | "chocolate2": "#EE7621", 447 | "chocolate3": "#CD661D", 448 | "chocolate4": "#8B4513", 449 | "ivoryblack": "#292421", 450 | "flesh": "#FF7D40", 451 | "cadmiumorange": "#FF6103", 452 | "burntsienna": "#8A360F", 453 | "sienna": "#A0522D", 454 | "sienna1": "#FF8247", 455 | "sienna2": "#EE7942", 456 | "sienna3": "#CD6839", 457 | "sienna4": "#8B4726", 458 | "lightsalmon1": "#FFA07A", 459 | "lightsalmon2": "#EE9572", 460 | "lightsalmon3": "#CD8162", 461 | "lightsalmon4": "#8B5742", 462 | "coral": "#FF7F50", 463 | "orangered1": "#FF4500", 464 | "orangered2": "#EE4000", 465 | "orangered3": "#CD3700", 466 | "orangered4": "#8B2500", 467 | "sepia": "#5E2612", 468 | "darksalmon": "#E9967A", 469 | "salmon1": "#FF8C69", 470 | "salmon2": "#EE8262", 471 | "salmon3": "#CD7054", 472 | "salmon4": "#8B4C39", 473 | "coral1": "#FF7256", 474 | "coral2": "#EE6A50", 475 | "coral3": "#CD5B45", 476 | "coral4": "#8B3E2F", 477 | "burntumber": "#8A3324", 478 | "tomato1": "#FF6347", 479 | "tomato2": "#EE5C42", 480 | "tomato3": "#CD4F39", 481 | "tomato4": "#8B3626", 482 | "salmon": "#FA8072", 483 | "mistyrose1": "#FFE4E1", 484 | "mistyrose2": "#EED5D2", 485 | "mistyrose3": "#CDB7B5", 486 | "mistyrose4": "#8B7D7B", 487 | "snow1": "#FFFAFA", 488 | "snow2": "#EEE9E9", 489 | "snow3": "#CDC9C9", 490 | "snow4": "#8B8989", 491 | "rosybrown": "#BC8F8F", 492 | "rosybrown1": "#FFC1C1", 493 | "rosybrown2": "#EEB4B4", 494 | "rosybrown3": "#CD9B9B", 495 | "rosybrown4": "#8B6969", 496 | "lightcoral": "#F08080", 497 | "indianred": "#CD5C5C", 498 | "indianred1": "#FF6A6A", 499 | "indianred2": "#EE6363", 500 | "indianred4": "#8B3A3A", 501 | "indianred3": "#CD5555", 502 | "brown": "#A52A2A", 503 | "brown1": "#FF4040", 504 | "brown2": "#EE3B3B", 505 | "brown3": "#CD3333", 506 | "brown4": "#8B2323", 507 | "firebrick": "#B22222", 508 | "firebrick1": "#FF3030", 509 | "firebrick2": "#EE2C2C", 510 | "firebrick3": "#CD2626", 511 | "firebrick4": "#8B1A1A", 512 | "red1": "#FF0000", 513 | "red2": "#EE0000", 514 | "red3": "#CD0000", 515 | "red4": "#8B0000", 516 | "maroon": "#800000", 517 | "sgibeet": "#8E388E", 518 | "sgislateblue": "#7171C6", 519 | "sgilightblue": "#7D9EC0", 520 | "sgiteal": "#388E8E", 521 | "sgichartreuse": "#71C671", 522 | "sgiolivedrab": "#8E8E38", 523 | "sgibrightgray": "#C5C1AA", 524 | "sgisalmon": "#C67171", 525 | "sgidarkgray": "#555555", 526 | "sgigray12": "#1E1E1E", 527 | "sgigray16": "#282828", 528 | "sgigray32": "#515151", 529 | "sgigray36": "#5B5B5B", 530 | "sgigray52": "#848484", 531 | "sgigray56": "#8E8E8E", 532 | "sgilightgray": "#AAAAAA", 533 | "sgigray72": "#B7B7B7", 534 | "sgigray76": "#C1C1C1", 535 | "sgigray92": "#EAEAEA", 536 | "sgigray96": "#F4F4F4", 537 | "white": "#FFFFFF", 538 | "gainsboro": "#DCDCDC", 539 | "lightgrey": "#D3D3D3", 540 | "silver": "#C0C0C0", 541 | "darkgray": "#A9A9A9", 542 | "gray": "#808080", 543 | "dimgray": "#696969", 544 | "black": "#000000", 545 | "gray99": "#FCFCFC", 546 | "gray98": "#FAFAFA", 547 | "gray97": "#F7F7F7", 548 | "gray95": "#F2F2F2", 549 | "gray94": "#F0F0F0", 550 | "gray93": "#EDEDED", 551 | "gray92": "#EBEBEB", 552 | "gray91": "#E8E8E8", 553 | "gray90": "#E5E5E5", 554 | "gray89": "#E3E3E3", 555 | "gray88": "#E0E0E0", 556 | "gray87": "#DEDEDE", 557 | "gray86": "#DBDBDB", 558 | "gray85": "#D9D9D9", 559 | "gray84": "#D6D6D6", 560 | "gray83": "#D4D4D4", 561 | "gray82": "#D1D1D1", 562 | "gray81": "#CFCFCF", 563 | "gray80": "#CCCCCC", 564 | "gray79": "#C9C9C9", 565 | "gray78": "#C7C7C7", 566 | "gray77": "#C4C4C4", 567 | "gray76": "#C2C2C2", 568 | "gray75": "#BFBFBF", 569 | "gray74": "#BDBDBD", 570 | "gray73": "#BABABA", 571 | "gray72": "#B8B8B8", 572 | "gray71": "#B5B5B5", 573 | "gray70": "#B3B3B3", 574 | "gray69": "#B0B0B0", 575 | "gray68": "#ADADAD", 576 | "gray67": "#ABABAB", 577 | "gray66": "#A8A8A8", 578 | "gray65": "#A6A6A6", 579 | "gray64": "#A3A3A3", 580 | "gray63": "#A1A1A1", 581 | "gray62": "#9E9E9E", 582 | "gray61": "#9C9C9C", 583 | "gray60": "#999999", 584 | "gray59": "#969696", 585 | "gray58": "#949494", 586 | "gray57": "#919191", 587 | "gray56": "#8F8F8F", 588 | "gray55": "#8C8C8C", 589 | "gray54": "#8A8A8A", 590 | "gray53": "#878787", 591 | "gray52": "#858585", 592 | "gray51": "#828282", 593 | "gray50": "#7F7F7F", 594 | "gray49": "#7D7D7D", 595 | "gray48": "#7A7A7A", 596 | "gray47": "#787878", 597 | "gray46": "#757575", 598 | "gray45": "#737373", 599 | "gray44": "#707070", 600 | "gray43": "#6E6E6E", 601 | "gray42": "#6B6B6B", 602 | "gray41": "#696969", 603 | "gray40": "#666666", 604 | "gray39": "#636363", 605 | "gray38": "#616161", 606 | "gray37": "#5E5E5E", 607 | "gray36": "#5C5C5C", 608 | "gray35": "#595959", 609 | "gray34": "#575757", 610 | "gray33": "#545454", 611 | "gray32": "#525252", 612 | "gray31": "#4F4F4F", 613 | "gray30": "#4D4D4D", 614 | "gray29": "#4A4A4A", 615 | "gray28": "#474747", 616 | "gray27": "#454545", 617 | "gray26": "#424242", 618 | "gray25": "#404040", 619 | "gray24": "#3D3D3D", 620 | "gray23": "#3B3B3B", 621 | "gray22": "#383838", 622 | "gray21": "#363636", 623 | "gray20": "#333333", 624 | "gray19": "#303030", 625 | "gray18": "#2E2E2E", 626 | "gray17": "#2B2B2B", 627 | "gray16": "#292929", 628 | "gray15": "#262626", 629 | "gray14": "#242424", 630 | "gray13": "#212121", 631 | "gray12": "#1F1F1F", 632 | "gray11": "#1C1C1C", 633 | "gray10": "#1A1A1A", 634 | "gray9": "#171717", 635 | "gray8": "#141414", 636 | "gray7": "#121212", 637 | "gray6": "#0F0F0F", 638 | "gray5": "#0D0D0D", 639 | "gray4": "#0A0A0A", 640 | "gray3": "#080808", 641 | "gray2": "#050505", 642 | "gray1": "#030303"} 643 | -------------------------------------------------------------------------------- /dirs/dirs.go: -------------------------------------------------------------------------------- 1 | package dirs 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "path/filepath" 8 | "sort" 9 | "strconv" 10 | "strings" 11 | 12 | "github.com/gookit/color" 13 | "github.com/mwiater/golangcliscaffold/common" 14 | "github.com/spf13/viper" 15 | ) 16 | 17 | type Dir struct { 18 | Path string 19 | Depth int 20 | BytesSize int64 21 | PrettyBytesSize string 22 | } 23 | 24 | var dirsVisited []string 25 | var dirs []Dir 26 | 27 | func ReadDirDepth(dirPath string) ([]Dir, error) { 28 | currentDir := strings.ReplaceAll(dirPath, viper.GetString("path"), "") 29 | currentDepth := len(strings.Split(currentDir, "/")) 30 | 31 | files, err := ioutil.ReadDir(dirPath) 32 | if err != nil { 33 | return nil, err 34 | } 35 | 36 | for _, file := range files { 37 | if file.IsDir() { 38 | _, err := ReadDirDepth(filepath.Join(dirPath, file.Name())) 39 | if err != nil { 40 | return nil, err 41 | } 42 | if viper.GetInt("depth") >= currentDepth { 43 | 44 | if !common.SliceContains(dirsVisited, filepath.Join(dirPath, file.Name())) { 45 | dirSize, _ := DirSizeBytes(filepath.Join(dirPath, file.Name())) 46 | if dirSize > int64(viper.GetInt("mindirsize")*1000000) { 47 | dir := Dir{} 48 | dir.Path = filepath.Join(dirPath, file.Name()) 49 | dir.Depth = viper.GetInt("depth") 50 | dir.BytesSize = dirSize 51 | dir.PrettyBytesSize = common.PrettyBytes(dirSize) 52 | 53 | dirs = append(dirs, dir) 54 | } 55 | 56 | } 57 | } 58 | } 59 | } 60 | 61 | sort.Slice(dirs, func(i, j int) bool { 62 | return dirs[i].BytesSize > dirs[j].BytesSize 63 | }) 64 | 65 | return dirs, nil 66 | } 67 | 68 | // DirSize returns the size of a directory in bytes. 69 | func DirSizeBytes(dirPath string) (int64, error) { 70 | var size int64 71 | fsi, err := os.Open(dirPath) 72 | if err != nil { 73 | return 0, err 74 | } 75 | filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error { 76 | if err != nil { 77 | return err 78 | } 79 | if !info.IsDir() { 80 | size += info.Size() 81 | } 82 | return nil 83 | }) 84 | defer fsi.Close() 85 | return size, nil 86 | } 87 | 88 | func PrintResults(dirs []Dir) { 89 | fmt.Println() 90 | common.PrintColor("forestgreen", "background", fmt.Sprintf("Largest directories in: %s", viper.GetString("path"))) 91 | fmt.Println("----------------------------------------------------------") 92 | fmt.Println() 93 | 94 | spacing := make(map[string]int) 95 | highWaterMark := 0 96 | 97 | for _, dir := range dirs { 98 | if len(dir.Path) > highWaterMark { 99 | highWaterMark = len(dir.Path) 100 | } 101 | 102 | spacing[dir.Path] = len(dir.Path) 103 | } 104 | 105 | for _, dir := range dirs { 106 | padding := strconv.Itoa(highWaterMark + 2) 107 | if dir.BytesSize >= int64(viper.GetInt("highlight")*1000000) { 108 | color.HEXStyle("000", common.AllHex["yellow1"]).Printf("%-"+padding+"s %10s\n", dir.Path, dir.PrettyBytesSize) 109 | } else { 110 | color.HEXStyle(common.AllHex["steelblue2"]).Printf("%-"+padding+"s %10s\n", dir.Path, dir.PrettyBytesSize) 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /files/files.go: -------------------------------------------------------------------------------- 1 | package files 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "path/filepath" 7 | "sort" 8 | "strconv" 9 | 10 | "github.com/gookit/color" 11 | "github.com/mwiater/golangcliscaffold/common" 12 | "github.com/spf13/viper" 13 | ) 14 | 15 | type File struct { 16 | Path string 17 | BytesSize int64 18 | PrettyBytesSize string 19 | } 20 | 21 | func ReadDirRecursively(dirPath string) ([]File, error) { 22 | files, err := ioutil.ReadDir(dirPath) 23 | if err != nil { 24 | return nil, err 25 | } 26 | 27 | var results []File 28 | for _, file := range files { 29 | //fmt.Println(dirPath, file.Name()) 30 | if file.IsDir() { 31 | subFiles, err := ReadDirRecursively(filepath.Join(dirPath, file.Name())) 32 | if err != nil { 33 | return nil, err 34 | } 35 | results = append(results, subFiles...) 36 | } else { 37 | if file.Size() >= (int64(viper.GetInt("minfilesize") * 1000000)) { 38 | foundFile := File{} 39 | foundFile.Path = filepath.Join(dirPath, file.Name()) 40 | foundFile.BytesSize = file.Size() 41 | foundFile.PrettyBytesSize = common.PrettyBytes(file.Size()) 42 | 43 | results = append(results, foundFile) 44 | } 45 | 46 | } 47 | } 48 | 49 | sort.Slice(results, func(i, j int) bool { 50 | return results[i].BytesSize > results[j].BytesSize 51 | }) 52 | 53 | return results, nil 54 | } 55 | 56 | func PrintResults(files []File) { 57 | fmt.Println() 58 | common.PrintColor("forestgreen", "background", fmt.Sprintf("Largest files in: %s", viper.GetString("path"))) 59 | fmt.Println("----------------------------------------------------------") 60 | fmt.Println() 61 | 62 | spacing := make(map[string]int) 63 | highWaterMark := 0 64 | 65 | for _, file := range files { 66 | if len(file.Path) > highWaterMark { 67 | highWaterMark = len(file.Path) 68 | } 69 | 70 | spacing[file.Path] = len(file.Path) 71 | } 72 | 73 | for _, file := range files { 74 | padding := strconv.Itoa(highWaterMark + 2) 75 | 76 | if file.BytesSize >= int64(viper.GetInt("highlight")*1000000) { 77 | color.HEXStyle("000", common.AllHex["yellow1"]).Printf("%-"+padding+"s %10s\n", file.Path, file.PrettyBytesSize) 78 | } else { 79 | color.HEXStyle(common.AllHex["steelblue2"]).Printf("%-"+padding+"s %10s\n", file.Path, file.PrettyBytesSize) 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/mwiater/golangcliscaffold 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/go-playground/colors v1.3.1 7 | github.com/gookit/color v1.5.3 8 | github.com/sirupsen/logrus v1.9.3 9 | github.com/spf13/cobra v1.7.0 10 | github.com/spf13/viper v1.16.0 11 | ) 12 | 13 | require ( 14 | github.com/fsnotify/fsnotify v1.6.0 // indirect 15 | github.com/hashicorp/hcl v1.0.0 // indirect 16 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 17 | github.com/magiconair/properties v1.8.7 // indirect 18 | github.com/mitchellh/mapstructure v1.5.0 // indirect 19 | github.com/pelletier/go-toml/v2 v2.0.8 // indirect 20 | github.com/spf13/afero v1.9.5 // indirect 21 | github.com/spf13/cast v1.5.1 // indirect 22 | github.com/spf13/jwalterweatherman v1.1.0 // indirect 23 | github.com/spf13/pflag v1.0.5 // indirect 24 | github.com/subosito/gotenv v1.4.2 // indirect 25 | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect 26 | golang.org/x/sys v0.8.0 // indirect 27 | golang.org/x/text v0.9.0 // indirect 28 | gopkg.in/ini.v1 v1.67.0 // indirect 29 | gopkg.in/yaml.v3 v3.0.1 // indirect 30 | ) 31 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 6 | cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 7 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 8 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 9 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= 10 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= 11 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= 12 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= 13 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= 14 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= 15 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= 16 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= 17 | cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= 18 | cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= 19 | cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= 20 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 21 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= 22 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= 23 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= 24 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= 25 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 26 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 27 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= 28 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 29 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 30 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= 31 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= 32 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 33 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= 34 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 35 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= 36 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= 37 | cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= 38 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 39 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 40 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 41 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 42 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 43 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 44 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 45 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 46 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 47 | github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 48 | github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 49 | github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 50 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 51 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 52 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 53 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 54 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 55 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 56 | github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= 57 | github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 58 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 59 | github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= 60 | github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= 61 | github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= 62 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 63 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 64 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 65 | github.com/go-playground/colors v1.3.1 h1:MSxzNRpTqaJrmrnChv78je4nLEMW7Tyibh0Dfy1N+as= 66 | github.com/go-playground/colors v1.3.1/go.mod h1:5rTAoESUkprj1EHZvzGti8xkb8XwAGYzYEFmW18B8es= 67 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 68 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 69 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 70 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 71 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 72 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 73 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 74 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 75 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 76 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 77 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 78 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 79 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 80 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 81 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 82 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 83 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 84 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 85 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 86 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 87 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 88 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 89 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 90 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 91 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 92 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 93 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 94 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 95 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 96 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 97 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 98 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 99 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 100 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 101 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 102 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 103 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 104 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 105 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 106 | github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 107 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 108 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 109 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 110 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 111 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 112 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 113 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 114 | github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 115 | github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 116 | github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 117 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 118 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 119 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 120 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 121 | github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= 122 | github.com/gookit/color v1.5.3 h1:twfIhZs4QLCtimkP7MOxlF3A0U/5cDPseRT9M/+2SCE= 123 | github.com/gookit/color v1.5.3/go.mod h1:NUzwzeehUfl7GIb36pqId+UGmRfQcU/WiiyTTeNjHtE= 124 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 125 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 126 | github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= 127 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 128 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 129 | github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 130 | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 131 | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 132 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 133 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 134 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 135 | github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 136 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 137 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 138 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 139 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 140 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 141 | github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= 142 | github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= 143 | github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= 144 | github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 145 | github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= 146 | github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= 147 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 148 | github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= 149 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 150 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 151 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 152 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 153 | github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= 154 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 155 | github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= 156 | github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 157 | github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= 158 | github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= 159 | github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= 160 | github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= 161 | github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= 162 | github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 163 | github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= 164 | github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= 165 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 166 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 167 | github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= 168 | github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= 169 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 170 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 171 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 172 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 173 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 174 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 175 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 176 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 177 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 178 | github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= 179 | github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 180 | github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= 181 | github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= 182 | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= 183 | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= 184 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 185 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 186 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 187 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 188 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 189 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 190 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 191 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 192 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 193 | go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= 194 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 195 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 196 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 197 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 198 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 199 | golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= 200 | golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 201 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 202 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 203 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 204 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 205 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 206 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 207 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 208 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 209 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= 210 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 211 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 212 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 213 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 214 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 215 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 216 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 217 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 218 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 219 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 220 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 221 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 222 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 223 | golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 224 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 225 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 226 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 227 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 228 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 229 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 230 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 231 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 232 | golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 233 | golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 234 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 235 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 236 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 237 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 238 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 239 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 240 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 241 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 242 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 243 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 244 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 245 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 246 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 247 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 248 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 249 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 250 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 251 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 252 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 253 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 254 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 255 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 256 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 257 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 258 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 259 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 260 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 261 | golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 262 | golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 263 | golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 264 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 265 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 266 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 267 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 268 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 269 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 270 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 271 | golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 272 | golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 273 | golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 274 | golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 275 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 276 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 277 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 278 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 279 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 280 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 281 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 282 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 283 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 284 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 285 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 286 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 287 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 288 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 289 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 290 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 291 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 292 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 293 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 294 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 295 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 296 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 297 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 298 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 299 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 300 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 301 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 302 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 303 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 304 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 305 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 306 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 307 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 308 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 309 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 310 | golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 311 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 312 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 313 | golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 314 | golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 315 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 316 | golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 317 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 318 | golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 319 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 320 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 321 | golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 322 | golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= 323 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 324 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 325 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 326 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 327 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 328 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 329 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 330 | golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 331 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 332 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 333 | golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= 334 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 335 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 336 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 337 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 338 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 339 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 340 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 341 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 342 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 343 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 344 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 345 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 346 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 347 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 348 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 349 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 350 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 351 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 352 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 353 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 354 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 355 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 356 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 357 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 358 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 359 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 360 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 361 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 362 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 363 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 364 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 365 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 366 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 367 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 368 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 369 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 370 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= 371 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 372 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 373 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 374 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 375 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 376 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 377 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 378 | golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= 379 | golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 380 | golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 381 | golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 382 | golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 383 | golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 384 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 385 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 386 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 387 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 388 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 389 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 390 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 391 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 392 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 393 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 394 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 395 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 396 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 397 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 398 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 399 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 400 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 401 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 402 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 403 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= 404 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= 405 | google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= 406 | google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= 407 | google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= 408 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 409 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 410 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 411 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 412 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 413 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 414 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 415 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 416 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 417 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 418 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 419 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 420 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 421 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 422 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 423 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 424 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 425 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 426 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 427 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 428 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 429 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= 430 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 431 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 432 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 433 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 434 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 435 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 436 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 437 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 438 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= 439 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 440 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= 441 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 442 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 443 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 444 | google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 445 | google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 446 | google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 447 | google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 448 | google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 449 | google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 450 | google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 451 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 452 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 453 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 454 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 455 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 456 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 457 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 458 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 459 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= 460 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 461 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 462 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 463 | google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 464 | google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= 465 | google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= 466 | google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 467 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 468 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 469 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 470 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 471 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 472 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 473 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 474 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 475 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 476 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 477 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 478 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 479 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 480 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 481 | gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= 482 | gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 483 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 484 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 485 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 486 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 487 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 488 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 489 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 490 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 491 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 492 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 493 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 494 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 495 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= 496 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 497 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "github.com/mwiater/golangcliscaffold/cmd" 4 | 5 | func main() { 6 | cmd.Execute() 7 | } 8 | -------------------------------------------------------------------------------- /playground/dirScan.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "sort" 8 | ) 9 | 10 | type FileInfo struct { 11 | Name string 12 | Size int64 13 | IsDir bool 14 | FileCount int 15 | } 16 | 17 | func getLargestFilesAndDirectories(path string, n int) ([]FileInfo, []FileInfo, error) { 18 | var files []FileInfo 19 | var dirs []FileInfo 20 | 21 | err := filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error { 22 | if err != nil { 23 | return err 24 | } 25 | 26 | if !info.IsDir() { 27 | files = append(files, FileInfo{ 28 | Name: filePath, 29 | Size: info.Size(), 30 | IsDir: false, 31 | FileCount: 0, 32 | }) 33 | } else { 34 | dirSize, err := calculateDirectorySize(filePath) 35 | if err != nil { 36 | return err 37 | } 38 | dirs = append(dirs, FileInfo{ 39 | Name: filePath, 40 | Size: dirSize, 41 | IsDir: true, 42 | FileCount: 0, 43 | }) 44 | } 45 | 46 | return nil 47 | }) 48 | 49 | if err != nil { 50 | return nil, nil, err 51 | } 52 | 53 | sort.Slice(files, func(i, j int) bool { 54 | return files[i].Size > files[j].Size 55 | }) 56 | 57 | if len(files) > n { 58 | files = files[:n] 59 | } 60 | 61 | sort.Slice(dirs, func(i, j int) bool { 62 | return dirs[i].Size > dirs[j].Size 63 | }) 64 | 65 | if len(dirs) > n { 66 | dirs = dirs[:n] 67 | } 68 | 69 | for i := range dirs { 70 | fileCount, err := countFiles(dirs[i].Name) 71 | if err != nil { 72 | return nil, nil, err 73 | } 74 | 75 | dirs[i].FileCount = fileCount 76 | } 77 | 78 | return files, dirs, nil 79 | } 80 | 81 | func calculateDirectorySize(dirPath string) (int64, error) { 82 | var size int64 83 | 84 | err := filepath.Walk(dirPath, func(filePath string, info os.FileInfo, err error) error { 85 | if err != nil { 86 | return err 87 | } 88 | 89 | if !info.IsDir() { 90 | size += info.Size() 91 | } 92 | 93 | return nil 94 | }) 95 | 96 | if err != nil { 97 | return 0, err 98 | } 99 | 100 | return size, nil 101 | } 102 | 103 | func countFiles(path string) (int, error) { 104 | fileCount := 0 105 | 106 | err := filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error { 107 | if err != nil { 108 | return err 109 | } 110 | 111 | if !info.IsDir() { 112 | fileCount++ 113 | } 114 | 115 | return nil 116 | }) 117 | 118 | if err != nil { 119 | return 0, err 120 | } 121 | 122 | return fileCount, nil 123 | } 124 | 125 | func main() { 126 | path := "/home/matt/projects" 127 | n := 10 128 | 129 | files, dirs, err := getLargestFilesAndDirectories(path, n) 130 | if err != nil { 131 | fmt.Println("Error:", err) 132 | return 133 | } 134 | 135 | fmt.Println("Largest Files:", len(files)) 136 | for _, file := range files { 137 | fmt.Printf("Name: %s, Size: %d\n", file.Name, file.Size) 138 | } 139 | 140 | fmt.Println("\nLargest Directories:", len(dirs)) 141 | for _, dir := range dirs { 142 | fmt.Printf("Name: %s, Size: %d, File Count: %d\n", dir.Name, dir.Size, dir.FileCount) 143 | } 144 | } 145 | --------------------------------------------------------------------------------