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  }