github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/cmd/root.go (about) 1 package cmd 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 8 "github.com/mattn/go-isatty" 9 "github.com/spf13/cobra" 10 "github.com/spf13/viper" 11 filehelpers "github.com/turbot/go-kit/files" 12 "github.com/turbot/steampipe/pkg/constants" 13 "github.com/turbot/steampipe/pkg/error_helpers" 14 "github.com/turbot/steampipe/pkg/filepaths" 15 "github.com/turbot/steampipe/pkg/statushooks" 16 "github.com/turbot/steampipe/pkg/utils" 17 "github.com/turbot/steampipe/pkg/version" 18 ) 19 20 var exitCode int 21 22 // rootCmd represents the base command when called without any subcommands 23 var rootCmd = &cobra.Command{ 24 Use: "steampipe [--version] [--help] COMMAND [args]", 25 Version: version.SteampipeVersion.String(), 26 Short: "Query cloud resources using SQL", 27 Long: `Steampipe: select * from cloud; 28 29 Dynamically query APIs, code and more with SQL. 30 Zero-ETL from 140+ data sources. 31 32 Common commands: 33 34 # Interactive SQL query console 35 steampipe query 36 37 # Install a plugin from the hub - https://hub.steampipe.io 38 steampipe plugin install aws 39 40 # Execute a defined SQL query 41 steampipe query "select * from aws_s3_bucket" 42 43 # Get help for a command 44 steampipe help query 45 46 Documentation: https://steampipe.io/docs 47 `, 48 } 49 50 func InitCmd() { 51 utils.LogTime("cmd.root.InitCmd start") 52 defer utils.LogTime("cmd.root.InitCmd end") 53 54 defaultInstallDir, err := filehelpers.Tildefy(filepaths.DefaultInstallDir) 55 error_helpers.FailOnError(err) 56 rootCmd.SetVersionTemplate(fmt.Sprintf("Steampipe v%s\n", version.SteampipeVersion.String())) 57 58 // global flags 59 rootCmd.PersistentFlags().String(constants.ArgWorkspaceProfile, "default", "The workspace profile to use") // workspace profile profile is a global flag since install-dir(global) can be set through the workspace profile 60 rootCmd.PersistentFlags().String(constants.ArgInstallDir, defaultInstallDir, "Path to the Config Directory") 61 rootCmd.PersistentFlags().Bool(constants.ArgSchemaComments, true, "Include schema comments when importing connection schemas") 62 63 error_helpers.FailOnError(viper.BindPFlag(constants.ArgInstallDir, rootCmd.PersistentFlags().Lookup(constants.ArgInstallDir))) 64 error_helpers.FailOnError(viper.BindPFlag(constants.ArgWorkspaceProfile, rootCmd.PersistentFlags().Lookup(constants.ArgWorkspaceProfile))) 65 error_helpers.FailOnError(viper.BindPFlag(constants.ArgSchemaComments, rootCmd.PersistentFlags().Lookup(constants.ArgSchemaComments))) 66 67 AddCommands() 68 69 // disable auto completion generation, since we don't want to support 70 // powershell yet - and there's no way to disable powershell in the default generator 71 rootCmd.CompletionOptions.DisableDefaultCmd = true 72 rootCmd.Flags().BoolP(constants.ArgHelp, "h", false, "Help for steampipe") 73 rootCmd.Flags().BoolP(constants.ArgVersion, "v", false, "Version for steampipe") 74 75 hideRootFlags(constants.ArgSchemaComments) 76 77 // tell OS to reclaim memory immediately 78 os.Setenv("GODEBUG", "madvdontneed=1") 79 80 } 81 82 func hideRootFlags(flags ...string) { 83 for _, flag := range flags { 84 rootCmd.Flag(flag).Hidden = true 85 } 86 } 87 88 func AddCommands() { 89 // explicitly initialise commands here rather than in init functions to allow us to handle errors from the config load 90 rootCmd.AddCommand( 91 pluginCmd(), 92 queryCmd(), 93 checkCmd(), 94 serviceCmd(), 95 modCmd(), 96 generateCompletionScriptsCmd(), 97 pluginManagerCmd(), 98 dashboardCmd(), 99 variableCmd(), 100 loginCmd(), 101 ) 102 } 103 104 func Execute() int { 105 utils.LogTime("cmd.root.Execute start") 106 defer utils.LogTime("cmd.root.Execute end") 107 108 ctx := createRootContext() 109 110 rootCmd.ExecuteContext(ctx) 111 return exitCode 112 } 113 114 // create the root context - add a status renderer 115 func createRootContext() context.Context { 116 statusRenderer := statushooks.NullHooks 117 // if the client is a TTY, inject a status spinner 118 if isatty.IsTerminal(os.Stdout.Fd()) { 119 statusRenderer = statushooks.NewStatusSpinnerHook() 120 } 121 122 ctx := statushooks.AddStatusHooksToContext(context.Background(), statusRenderer) 123 return ctx 124 }