internal/cmd/root.go (106 lines of code) (raw):

/* * Copyright 2021-2024 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package cmd import ( "fmt" "os" "github.com/JetBrains/qodana-cli/internal/core" "github.com/JetBrains/qodana-cli/internal/platform/msg" "github.com/JetBrains/qodana-cli/internal/platform/qdenv" "github.com/JetBrains/qodana-cli/internal/platform/version" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) // isHelpOrVersion checks if only help was requested. func isHelpOrVersion(args []string) bool { return len(args) == 2 && (args[1] == "--help" || args[1] == "-h" || args[1] == "help" || args[1] == "--version" || args[1] == "-v") } func isCompletionRequested(args []string) bool { return len(args) >= 2 && args[1] == "completion" } // isCommandRequested checks if any command is requested. func isCommandRequested(commands []*cobra.Command, args []string) string { for _, c := range commands { for _, a := range args { if c.Name() == a { return c.Name() } } } return "" } // setDefaultCommandIfNeeded sets default scan command if no other command is requested. func setDefaultCommandIfNeeded(rootCmd *cobra.Command, args []string) { if !isHelpOrVersion(args) && isCommandRequested( rootCmd.Commands(), args[1:], ) == "" && !isCompletionRequested(args) { newArgs := append([]string{"scan"}, args[1:]...) rootCmd.SetArgs(newArgs) } } // Execute is a main CLI entrypoint: handles user interrupt, CLI start and everything else. func Execute() { if !qdenv.IsContainer() && os.Geteuid() == 0 { msg.WarningMessage("Running the tool as root is dangerous: please run it as a regular user") } go core.CheckForUpdates(version.Version) if !msg.IsInteractive() || os.Getenv("NO_COLOR") != "" { // http://no-color.org msg.DisableColor() } setDefaultCommandIfNeeded(rootCommand, os.Args) if err := rootCommand.Execute(); err != nil { core.CheckForUpdates(version.Version) _, err = fmt.Fprintf(os.Stderr, "error running command: %s\n", err) if err != nil { return } os.Exit(1) } core.CheckForUpdates(version.Version) } // newRootCommand constructs root command. func newRootCommand() *cobra.Command { rootCmd := &cobra.Command{ Use: "qodana", Short: "Run Qodana CLI", Long: msg.InfoString(version.Version), Version: version.Version, PersistentPreRun: func(cmd *cobra.Command, args []string) { logLevel, err := log.ParseLevel(viper.GetString("log-level")) if err != nil { log.Fatal(err) } log.SetLevel(logLevel) }, Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { err := cmd.Help() if err != nil { return } } }, } rootCmd.PersistentFlags().String("log-level", "error", "Set log-level for output") rootCmd.PersistentFlags().BoolVar( &core.DisableCheckUpdates, "disable-update-checks", false, "Disable check for updates", ) if err := viper.BindPFlag("log-level", rootCmd.PersistentFlags().Lookup("log-level")); err != nil { log.Fatal(err) } return rootCmd } var rootCommand = newRootCommand() // InitCli adds all child commands to the root command. func InitCli() { rootCommand.AddCommand( newInitCommand(), newScanCommand(), newShowCommand(), newSendCommand(), newPullCommand(), newViewCommand(), newContributorsCommand(), newClocCommand(), ) } // InitWithCustomCommands adds custom commands to the root command. func InitWithCustomCommands(commands []*cobra.Command) { rootCommand.AddCommand(commands...) }