github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/src/cmd/common/viper.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: 2021-Present The Jackal Authors 3 4 // Package common handles command configuration across all commands 5 package common 6 7 import ( 8 "os" 9 "strings" 10 11 "github.com/Racer159/jackal/src/config" 12 "github.com/Racer159/jackal/src/config/lang" 13 "github.com/Racer159/jackal/src/pkg/message" 14 "github.com/spf13/viper" 15 ) 16 17 // Constants for use when loading configurations from viper config files 18 const ( 19 20 // Root config keys 21 22 VLogLevel = "log_level" 23 VArchitecture = "architecture" 24 VNoLogFile = "no_log_file" 25 VNoProgress = "no_progress" 26 VNoColor = "no_color" 27 VJackalCache = "jackal_cache" 28 VTmpDir = "tmp_dir" 29 VInsecure = "insecure" 30 31 // Init config keys 32 33 VInitComponents = "init.components" 34 VInitStorageClass = "init.storage_class" 35 36 // Init Git config keys 37 38 VInitGitURL = "init.git.url" 39 VInitGitPushUser = "init.git.push_username" 40 VInitGitPushPass = "init.git.push_password" 41 VInitGitPullUser = "init.git.pull_username" 42 VInitGitPullPass = "init.git.pull_password" 43 44 // Init Registry config keys 45 46 VInitRegistryURL = "init.registry.url" 47 VInitRegistryNodeport = "init.registry.nodeport" 48 VInitRegistrySecret = "init.registry.secret" 49 VInitRegistryPushUser = "init.registry.push_username" 50 VInitRegistryPushPass = "init.registry.push_password" 51 VInitRegistryPullUser = "init.registry.pull_username" 52 VInitRegistryPullPass = "init.registry.pull_password" 53 54 // Init Package config keys 55 56 VInitArtifactURL = "init.artifact.url" 57 VInitArtifactPushUser = "init.artifact.push_username" 58 VInitArtifactPushToken = "init.artifact.push_token" 59 60 // Package config keys 61 62 VPkgOCIConcurrency = "package.oci_concurrency" 63 VPkgPublicKey = "package.public_key" 64 65 // Package create config keys 66 67 VPkgCreateSet = "package.create.set" 68 VPkgCreateOutput = "package.create.output" 69 VPkgCreateSbom = "package.create.sbom" 70 VPkgCreateSbomOutput = "package.create.sbom_output" 71 VPkgCreateSkipSbom = "package.create.skip_sbom" 72 VPkgCreateMaxPackageSize = "package.create.max_package_size" 73 VPkgCreateSigningKey = "package.create.signing_key" 74 VPkgCreateSigningKeyPassword = "package.create.signing_key_password" 75 VPkgCreateDifferential = "package.create.differential" 76 VPkgCreateRegistryOverride = "package.create.registry_override" 77 VPkgCreateFlavor = "package.create.flavor" 78 79 // Package deploy config keys 80 81 VPkgDeploySet = "package.deploy.set" 82 VPkgDeployComponents = "package.deploy.components" 83 VPkgDeployShasum = "package.deploy.shasum" 84 VPkgDeploySget = "package.deploy.sget" 85 VPkgDeploySkipWebhooks = "package.deploy.skip_webhooks" 86 VPkgDeployTimeout = "package.deploy.timeout" 87 VPkgRetries = "package.deploy.retries" 88 89 // Package publish config keys 90 91 VPkgPublishSigningKey = "package.publish.signing_key" 92 VPkgPublishSigningKeyPassword = "package.publish.signing_key_password" 93 94 // Package pull config keys 95 96 VPkgPullOutputDir = "package.pull.output_directory" 97 98 // Dev deploy config keys 99 100 VDevDeployNoYolo = "dev.deploy.no_yolo" 101 ) 102 103 var ( 104 // Viper instance used by commands 105 v *viper.Viper 106 107 // Viper configuration error 108 vConfigError error 109 ) 110 111 // InitViper initializes the viper singleton for the CLI 112 func InitViper() *viper.Viper { 113 // Already initialized by some other command 114 if v != nil { 115 return v 116 } 117 118 v = viper.New() 119 120 // Skip for vendor-only commands or the version command 121 if CheckVendorOnlyFromArgs() || isVersionCmd() { 122 return v 123 } 124 125 // Specify an alternate config file 126 cfgFile := os.Getenv("JACKAL_CONFIG") 127 128 // Don't forget to read config either from cfgFile or from home directory! 129 if cfgFile != "" { 130 // Use config file from the flag. 131 v.SetConfigFile(cfgFile) 132 } else { 133 // Search config paths in the current directory and $HOME/.jackal. 134 v.AddConfigPath(".") 135 v.AddConfigPath("$HOME/.jackal") 136 v.SetConfigName("jackal-config") 137 } 138 139 // E.g. JACKAL_LOG_LEVEL=debug 140 v.SetEnvPrefix("jackal") 141 v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) 142 v.AutomaticEnv() 143 144 // Optional, so ignore errors 145 vConfigError = v.ReadInConfig() 146 147 // Set default values for viper 148 setDefaults() 149 150 return v 151 } 152 153 // GetViper returns the viper singleton 154 func GetViper() *viper.Viper { 155 return v 156 } 157 158 func isVersionCmd() bool { 159 args := os.Args 160 return len(args) > 1 && (args[1] == "version" || args[1] == "v") 161 } 162 163 func printViperConfigUsed() { 164 // Only print config info if viper is initialized. 165 vInitialized := v != nil 166 if !vInitialized { 167 return 168 } 169 170 // Optional, so ignore file not found errors 171 if vConfigError != nil { 172 // Config file not found; ignore 173 if _, ok := vConfigError.(viper.ConfigFileNotFoundError); !ok { 174 message.WarnErrf(vConfigError, lang.CmdViperErrLoadingConfigFile, vConfigError.Error()) 175 } 176 } else { 177 message.Notef(lang.CmdViperInfoUsingConfigFile, v.ConfigFileUsed()) 178 } 179 } 180 181 func setDefaults() { 182 // Root defaults that are non-zero values 183 v.SetDefault(VLogLevel, "info") 184 v.SetDefault(VJackalCache, config.JackalDefaultCachePath) 185 186 // Package defaults that are non-zero values 187 v.SetDefault(VPkgOCIConcurrency, 3) 188 v.SetDefault(VPkgRetries, config.JackalDefaultRetries) 189 190 // Deploy opts that are non-zero values 191 v.SetDefault(VPkgDeployTimeout, config.JackalDefaultTimeout) 192 }