trpc.group/trpc-go/trpc-cmdline@v1.0.9/cmd/root.go (about)

     1  // Tencent is pleased to support the open source community by making tRPC available.
     2  //
     3  // Copyright (C) 2023 THL A29 Limited, a Tencent company.
     4  // All rights reserved.
     5  //
     6  // If you have downloaded a copy of the tRPC source code from Tencent,
     7  // please note that tRPC source code is licensed under the  Apache 2.0 License,
     8  // A copy of the Apache 2.0 License is included in this file.
     9  
    10  // Package cmd provides commands to help developer generating project, testing, etc.
    11  package cmd
    12  
    13  import (
    14  	"fmt"
    15  	"os"
    16  	"path/filepath"
    17  
    18  	"github.com/spf13/cobra"
    19  	"github.com/spf13/viper"
    20  
    21  	"trpc.group/trpc-go/trpc-cmdline/cmd/apidocs"
    22  	"trpc.group/trpc-go/trpc-cmdline/cmd/completion"
    23  	"trpc.group/trpc-go/trpc-cmdline/cmd/create"
    24  	"trpc.group/trpc-go/trpc-cmdline/cmd/setup"
    25  	"trpc.group/trpc-go/trpc-cmdline/cmd/version"
    26  	"trpc.group/trpc-go/trpc-cmdline/config"
    27  	"trpc.group/trpc-go/trpc-cmdline/util/log"
    28  )
    29  
    30  // Execute adds all child commands to the root command and sets flags appropriately.
    31  // This is called by main.main(). It only needs to happen once to the rootCmd.
    32  func Execute() {
    33  	if err := rootCmd.Execute(); err != nil {
    34  		fmt.Printf(`Execution err:
    35  	%+v
    36  Please run "trpc -h" or "trpc create -h" (or "trpc {some-other-subcommand} -h") for help messages.
    37  `, err)
    38  		os.Exit(1) // Exist with non-zero errcode to indicate failure.
    39  	}
    40  }
    41  
    42  var (
    43  	cfgFile     string
    44  	verboseFlag bool
    45  )
    46  
    47  // rootCmd represents the base command when called without any subcommands
    48  var rootCmd = &cobra.Command{
    49  	Use:   "trpc",
    50  	Short: "trpc is an efficiency tool for convenient trpc service development",
    51  	Long: `trpc is an efficiency tool for convenient trpc service development.
    52  
    53  For example:
    54  - Generate a complete project or corresponding RPC stub by specifying the pb file
    55  - Send RPC test requests to the target service
    56  
    57  Try using trpc framework + trpc tool to write your next trpc service!
    58  `,
    59  	SilenceErrors: true,
    60  	SilenceUsage:  true,
    61  }
    62  
    63  const defaultConfigFile = "path/to/trpc.yaml"
    64  
    65  func init() {
    66  	cobra.OnInitialize(func() {
    67  		if err := initConfig(); err != nil {
    68  			panic(err)
    69  		}
    70  	})
    71  
    72  	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", defaultConfigFile,
    73  		"Path to the configuration file (automatically calculated)")
    74  	rootCmd.PersistentFlags().BoolVarP(&verboseFlag, "verbose", "v", false, "Display detailed log information")
    75  
    76  	rootCmd.AddCommand(create.CMD())
    77  	rootCmd.AddCommand(setup.CMD())
    78  	rootCmd.AddCommand(completion.CMD())
    79  	rootCmd.AddCommand(apidocs.CMD())
    80  	rootCmd.AddCommand(version.CMD())
    81  }
    82  
    83  // initConfig reads in config file and ENV variables if set.
    84  func initConfig() error {
    85  	log.SetVerbose(verboseFlag)
    86  
    87  	d, err := config.Init()
    88  	if err != nil {
    89  		return fmt.Errorf("config init err: %w", err)
    90  	}
    91  
    92  	if cfgFile == defaultConfigFile {
    93  		cfgFile = filepath.Join(d, "trpc.yaml")
    94  	}
    95  	if cfgFile != "" {
    96  		// Use config file from the flag.
    97  		log.Debug("using config from %s", cfgFile)
    98  		viper.SetConfigFile(cfgFile)
    99  	}
   100  
   101  	viper.AutomaticEnv() // Read in environment variables that matched.
   102  
   103  	// If a config file is found, read it in.
   104  	if err := viper.ReadInConfig(); err != nil {
   105  		return fmt.Errorf("viper read in config: %w", err)
   106  	}
   107  
   108  	return nil
   109  }