| 
									
										
										
										
											2021-04-19 03:41:13 +08:00
										 |  |  |  | // Copyright (c) 2015-2021 MinIO, Inc.
 | 
					
						
							|  |  |  |  | //
 | 
					
						
							|  |  |  |  | // This file is part of MinIO Object Storage stack
 | 
					
						
							|  |  |  |  | //
 | 
					
						
							|  |  |  |  | // This program is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  |  | //
 | 
					
						
							|  |  |  |  | // This program is distributed in the hope that it will be useful
 | 
					
						
							|  |  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  |  | //
 | 
					
						
							|  |  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  |  | // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | package cmd | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2022-06-17 07:10:48 +08:00
										 |  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2022-06-29 07:37:40 +08:00
										 |  |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2017-06-09 14:28:45 +08:00
										 |  |  |  | 	"path/filepath" | 
					
						
							| 
									
										
										
										
											2022-06-03 09:40:53 +08:00
										 |  |  |  | 	"runtime" | 
					
						
							| 
									
										
										
										
											2022-09-23 02:57:27 +08:00
										 |  |  |  | 	"runtime/debug" | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 	"sort" | 
					
						
							| 
									
										
										
										
											2024-03-09 11:07:08 +08:00
										 |  |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2022-06-29 07:37:40 +08:00
										 |  |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2024-03-09 11:07:08 +08:00
										 |  |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 	"github.com/minio/cli" | 
					
						
							| 
									
										
										
										
											2022-06-17 07:10:48 +08:00
										 |  |  |  | 	"github.com/minio/minio/internal/color" | 
					
						
							| 
									
										
										
										
											2022-09-23 02:57:27 +08:00
										 |  |  |  | 	"github.com/minio/minio/internal/logger" | 
					
						
							| 
									
										
										
										
											2024-05-25 07:05:23 +08:00
										 |  |  |  | 	"github.com/minio/pkg/v3/console" | 
					
						
							|  |  |  |  | 	"github.com/minio/pkg/v3/env" | 
					
						
							|  |  |  |  | 	"github.com/minio/pkg/v3/trie" | 
					
						
							|  |  |  |  | 	"github.com/minio/pkg/v3/words" | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-10 22:57:42 +08:00
										 |  |  |  | // GlobalFlags - global flags for minio.
 | 
					
						
							|  |  |  |  | var GlobalFlags = []cli.Flag{ | 
					
						
							| 
									
										
										
										
											2020-04-13 09:08:27 +08:00
										 |  |  |  | 	// Deprecated flag, so its hidden now - existing deployments will keep working.
 | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 	cli.StringFlag{ | 
					
						
							| 
									
										
										
										
											2020-04-13 09:08:27 +08:00
										 |  |  |  | 		Name:   "config-dir, C", | 
					
						
							|  |  |  |  | 		Value:  defaultConfigDir.Get(), | 
					
						
							|  |  |  |  | 		Usage:  "[DEPRECATED] path to legacy configuration directory", | 
					
						
							|  |  |  |  | 		Hidden: true, | 
					
						
							| 
									
										
										
										
											2019-01-03 02:05:16 +08:00
										 |  |  |  | 	}, | 
					
						
							|  |  |  |  | 	cli.StringFlag{ | 
					
						
							|  |  |  |  | 		Name:  "certs-dir, S", | 
					
						
							|  |  |  |  | 		Value: defaultCertsDir.Get(), | 
					
						
							| 
									
										
										
										
											2019-05-09 09:35:40 +08:00
										 |  |  |  | 		Usage: "path to certs directory", | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 	}, | 
					
						
							|  |  |  |  | 	cli.BoolFlag{ | 
					
						
							|  |  |  |  | 		Name:  "quiet", | 
					
						
							| 
									
										
										
										
											2022-03-04 05:21:16 +08:00
										 |  |  |  | 		Usage: "disable startup and info messages", | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2018-12-19 08:08:11 +08:00
										 |  |  |  | 	cli.BoolFlag{ | 
					
						
							|  |  |  |  | 		Name:  "anonymous", | 
					
						
							| 
									
										
										
										
											2019-05-09 09:35:40 +08:00
										 |  |  |  | 		Usage: "hide sensitive information from logging", | 
					
						
							| 
									
										
										
										
											2018-12-19 08:08:11 +08:00
										 |  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  |  | 	cli.BoolFlag{ | 
					
						
							|  |  |  |  | 		Name:  "json", | 
					
						
							| 
									
										
										
										
											2022-03-04 05:21:16 +08:00
										 |  |  |  | 		Usage: "output logs in JSON format", | 
					
						
							| 
									
										
										
										
											2019-05-09 09:35:40 +08:00
										 |  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2020-04-13 09:08:27 +08:00
										 |  |  |  | 	// Deprecated flag, so its hidden now, existing deployments will keep working.
 | 
					
						
							| 
									
										
										
										
											2019-05-09 09:35:40 +08:00
										 |  |  |  | 	cli.BoolFlag{ | 
					
						
							| 
									
										
										
										
											2020-04-13 09:08:27 +08:00
										 |  |  |  | 		Name:   "compat", | 
					
						
							|  |  |  |  | 		Usage:  "enable strict S3 compatibility by turning off certain performance optimizations", | 
					
						
							|  |  |  |  | 		Hidden: true, | 
					
						
							|  |  |  |  | 	}, | 
					
						
							|  |  |  |  | 	// This flag is hidden and to be used only during certain performance testing.
 | 
					
						
							|  |  |  |  | 	cli.BoolFlag{ | 
					
						
							|  |  |  |  | 		Name:   "no-compat", | 
					
						
							|  |  |  |  | 		Usage:  "disable strict S3 compatibility by turning on certain performance optimizations", | 
					
						
							|  |  |  |  | 		Hidden: true, | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | // Help template for minio.
 | 
					
						
							|  |  |  |  | var minioHelpTemplate = `NAME: | 
					
						
							|  |  |  |  |   {{.Name}} - {{.Usage}} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | DESCRIPTION: | 
					
						
							|  |  |  |  |   {{.Description}} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | USAGE: | 
					
						
							| 
									
										
										
										
											2017-02-16 09:45:08 +08:00
										 |  |  |  |   {{.HelpName}} {{if .VisibleFlags}}[FLAGS] {{end}}COMMAND{{if .VisibleFlags}}{{end}} [ARGS...] | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | COMMANDS: | 
					
						
							| 
									
										
										
										
											2017-02-15 18:25:38 +08:00
										 |  |  |  |   {{range .VisibleCommands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} | 
					
						
							|  |  |  |  |   {{end}}{{if .VisibleFlags}} | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | FLAGS: | 
					
						
							| 
									
										
										
										
											2017-02-15 18:25:38 +08:00
										 |  |  |  |   {{range .VisibleFlags}}{{.}} | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  |   {{end}}{{end}} | 
					
						
							|  |  |  |  | VERSION: | 
					
						
							| 
									
										
										
										
											2020-02-27 01:39:08 +08:00
										 |  |  |  |   {{.Version}} | 
					
						
							| 
									
										
										
										
											2020-01-02 22:48:32 +08:00
										 |  |  |  | ` | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 14:28:45 +08:00
										 |  |  |  | func newApp(name string) *cli.App { | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 	// Collection of minio commands currently supported are.
 | 
					
						
							|  |  |  |  | 	commands := []cli.Command{} | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 	// Collection of minio commands currently supported in a trie tree.
 | 
					
						
							|  |  |  |  | 	commandsTree := trie.NewTrie() | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 	// registerCommand registers a cli command.
 | 
					
						
							|  |  |  |  | 	registerCommand := func(command cli.Command) { | 
					
						
							| 
									
										
										
										
											2024-07-31 06:59:48 +08:00
										 |  |  |  | 		// avoid registering commands which are not being built (via
 | 
					
						
							|  |  |  |  | 		// go:build tags)
 | 
					
						
							|  |  |  |  | 		if command.Name == "" { | 
					
						
							|  |  |  |  | 			return | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 		commands = append(commands, command) | 
					
						
							|  |  |  |  | 		commandsTree.Insert(command.Name) | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 	findClosestCommands := func(command string) []string { | 
					
						
							|  |  |  |  | 		var closestCommands []string | 
					
						
							| 
									
										
										
										
											2020-09-21 16:18:13 +08:00
										 |  |  |  | 		closestCommands = append(closestCommands, commandsTree.PrefixMatch(command)...) | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 		sort.Strings(closestCommands) | 
					
						
							|  |  |  |  | 		// Suggest other close commands - allow missed, wrongly added and
 | 
					
						
							|  |  |  |  | 		// even transposed characters
 | 
					
						
							|  |  |  |  | 		for _, value := range commandsTree.Walk(commandsTree.Root()) { | 
					
						
							| 
									
										
										
										
											2020-09-21 16:18:13 +08:00
										 |  |  |  | 			if sort.SearchStrings(closestCommands, value) < len(closestCommands) { | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 				continue | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 			// 2 is arbitrary and represents the max
 | 
					
						
							|  |  |  |  | 			// allowed number of typed errors
 | 
					
						
							| 
									
										
										
										
											2020-09-21 16:18:13 +08:00
										 |  |  |  | 			if words.DamerauLevenshteinDistance(command, value) < 2 { | 
					
						
							|  |  |  |  | 				closestCommands = append(closestCommands, value) | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		return closestCommands | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// Register all commands.
 | 
					
						
							|  |  |  |  | 	registerCommand(serverCmd) | 
					
						
							| 
									
										
										
										
											2024-07-31 06:59:48 +08:00
										 |  |  |  | 	registerCommand(fmtGenCmd) | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// Set up app.
 | 
					
						
							| 
									
										
										
										
											2017-02-20 12:46:06 +08:00
										 |  |  |  | 	cli.HelpFlag = cli.BoolFlag{ | 
					
						
							|  |  |  |  | 		Name:  "help, h", | 
					
						
							| 
									
										
										
										
											2019-05-09 09:35:40 +08:00
										 |  |  |  | 		Usage: "show help", | 
					
						
							| 
									
										
										
										
											2017-02-20 12:46:06 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-06-17 07:10:48 +08:00
										 |  |  |  | 	cli.VersionPrinter = printMinIOVersion | 
					
						
							| 
									
										
										
										
											2022-06-03 09:40:53 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 	app := cli.NewApp() | 
					
						
							| 
									
										
										
										
											2017-06-09 14:28:45 +08:00
										 |  |  |  | 	app.Name = name | 
					
						
							| 
									
										
										
										
											2019-04-10 02:39:42 +08:00
										 |  |  |  | 	app.Author = "MinIO, Inc." | 
					
						
							| 
									
										
										
										
											2022-06-17 07:10:48 +08:00
										 |  |  |  | 	app.Version = ReleaseTag | 
					
						
							| 
									
										
										
										
											2019-11-14 09:38:05 +08:00
										 |  |  |  | 	app.Usage = "High Performance Object Storage" | 
					
						
							|  |  |  |  | 	app.Description = `Build high performance data infrastructure for machine learning, analytics and application data workloads with MinIO` | 
					
						
							| 
									
										
										
										
											2022-06-17 07:10:48 +08:00
										 |  |  |  | 	app.Flags = GlobalFlags | 
					
						
							| 
									
										
										
										
											2017-02-20 12:46:06 +08:00
										 |  |  |  | 	app.HideHelpCommand = true // Hide `help, h` command, we already have `minio --help`.
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 	app.Commands = commands | 
					
						
							|  |  |  |  | 	app.CustomAppHelpTemplate = minioHelpTemplate | 
					
						
							|  |  |  |  | 	app.CommandNotFound = func(ctx *cli.Context, command string) { | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 		console.Printf("‘%s’ is not a minio sub-command. See ‘minio --help’.\n", command) | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 		closestCommands := findClosestCommands(command) | 
					
						
							|  |  |  |  | 		if len(closestCommands) > 0 { | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 			console.Println() | 
					
						
							|  |  |  |  | 			console.Println("Did you mean one of these?") | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 			for _, cmd := range closestCommands { | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 				console.Printf("\t‘%s’\n", cmd) | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 		os.Exit(1) | 
					
						
							| 
									
										
										
										
											2016-11-29 04:15:36 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | 	return app | 
					
						
							| 
									
										
										
										
											2016-11-29 04:15:36 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-29 07:37:40 +08:00
										 |  |  |  | func startupBanner(banner io.Writer) { | 
					
						
							| 
									
										
										
										
											2024-03-09 11:07:08 +08:00
										 |  |  |  | 	CopyrightYear = strconv.Itoa(time.Now().Year()) | 
					
						
							| 
									
										
										
										
											2022-06-29 07:37:40 +08:00
										 |  |  |  | 	fmt.Fprintln(banner, color.Blue("Copyright:")+color.Bold(" 2015-%s MinIO, Inc.", CopyrightYear)) | 
					
						
							| 
									
										
										
										
											2024-03-09 11:07:08 +08:00
										 |  |  |  | 	fmt.Fprintln(banner, color.Blue("License:")+color.Bold(" "+MinioLicense)) | 
					
						
							| 
									
										
										
										
											2022-07-01 04:58:09 +08:00
										 |  |  |  | 	fmt.Fprintln(banner, color.Blue("Version:")+color.Bold(" %s (%s %s/%s)", ReleaseTag, runtime.Version(), runtime.GOOS, runtime.GOARCH)) | 
					
						
							| 
									
										
										
										
											2022-06-29 07:37:40 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func versionBanner(c *cli.Context) io.Reader { | 
					
						
							|  |  |  |  | 	banner := &strings.Builder{} | 
					
						
							|  |  |  |  | 	fmt.Fprintln(banner, color.Bold("%s version %s (commit-id=%s)", c.App.Name, c.App.Version, CommitID)) | 
					
						
							| 
									
										
										
										
											2022-07-01 04:58:09 +08:00
										 |  |  |  | 	fmt.Fprintln(banner, color.Blue("Runtime:")+color.Bold(" %s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH)) | 
					
						
							| 
									
										
										
										
											2024-05-02 01:57:52 +08:00
										 |  |  |  | 	fmt.Fprintln(banner, color.Blue("License:")+color.Bold(" GNU AGPLv3 - https://www.gnu.org/licenses/agpl-3.0.html")) | 
					
						
							| 
									
										
										
										
											2022-07-01 04:58:09 +08:00
										 |  |  |  | 	fmt.Fprintln(banner, color.Blue("Copyright:")+color.Bold(" 2015-%s MinIO, Inc.", CopyrightYear)) | 
					
						
							| 
									
										
										
										
											2022-06-29 07:37:40 +08:00
										 |  |  |  | 	return strings.NewReader(banner.String()) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-17 07:10:48 +08:00
										 |  |  |  | func printMinIOVersion(c *cli.Context) { | 
					
						
							| 
									
										
										
										
											2022-06-29 07:37:40 +08:00
										 |  |  |  | 	io.Copy(c.App.Writer, versionBanner(c)) | 
					
						
							| 
									
										
										
										
											2022-06-03 09:40:53 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-20 01:12:20 +08:00
										 |  |  |  | var debugNoExit = env.Get("_MINIO_DEBUG_NO_EXIT", "") != "" | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-29 04:15:36 +08:00
										 |  |  |  | // Main main for minio server.
 | 
					
						
							| 
									
										
										
										
											2017-03-07 11:35:26 +08:00
										 |  |  |  | func Main(args []string) { | 
					
						
							| 
									
										
										
										
											2017-06-13 08:33:21 +08:00
										 |  |  |  | 	// Set the minio app name.
 | 
					
						
							|  |  |  |  | 	appName := filepath.Base(args[0]) | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-20 01:12:20 +08:00
										 |  |  |  | 	if debugNoExit { | 
					
						
							| 
									
										
										
										
											2022-09-23 02:57:27 +08:00
										 |  |  |  | 		freeze := func(_ int) { | 
					
						
							|  |  |  |  | 			// Infinite blocking op
 | 
					
						
							|  |  |  |  | 			<-make(chan struct{}) | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// Override the logger os.Exit()
 | 
					
						
							|  |  |  |  | 		logger.ExitFunc = freeze | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		defer func() { | 
					
						
							|  |  |  |  | 			if err := recover(); err != nil { | 
					
						
							|  |  |  |  | 				fmt.Println("panic:", err) | 
					
						
							|  |  |  |  | 				fmt.Println("") | 
					
						
							|  |  |  |  | 				fmt.Println(string(debug.Stack())) | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 			freeze(-1) | 
					
						
							|  |  |  |  | 		}() | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | 	// Run the app - exit on error.
 | 
					
						
							| 
									
										
										
										
											2017-06-13 08:33:21 +08:00
										 |  |  |  | 	if err := newApp(appName).Run(args); err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-23 02:57:27 +08:00
										 |  |  |  | 		os.Exit(1) //nolint:gocritic
 | 
					
						
							| 
									
										
										
										
											2017-01-27 07:22:41 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  |  | } |