github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/util/configv3/load_config.go (about)

     1  package configv3
     2  
     3  import (
     4  	"encoding/json"
     5  	"io/ioutil"
     6  	"math"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"code.cloudfoundry.org/cli/command/translatableerror"
    11  	"golang.org/x/crypto/ssh/terminal"
    12  )
    13  
    14  // LoadConfig loads the config from the .cf/config.json and os.ENV. If the
    15  // config.json does not exists, it will use a default config in it's place.
    16  // Takes in an optional FlagOverride, will only use the first one passed, that
    17  // can override the given flag values.
    18  //
    19  // The '.cf' directory will be read in one of the following locations on UNIX
    20  // Systems:
    21  //   1. $CF_HOME/.cf if $CF_HOME is set
    22  //   2. $HOME/.cf as the default
    23  //
    24  // The '.cf' directory will be read in one of the following locations on
    25  // Windows Systems:
    26  //   1. CF_HOME\.cf if CF_HOME is set
    27  //   2. HOMEDRIVE\HOMEPATH\.cf if HOMEDRIVE or HOMEPATH is set
    28  //   3. USERPROFILE\.cf as the default
    29  func LoadConfig(flags ...FlagOverride) (*Config, error) {
    30  	err := removeOldTempConfigFiles()
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  
    35  	configFilePath := ConfigFilePath()
    36  
    37  	config := Config{
    38  		ConfigFile: JSONConfig{
    39  			ConfigVersion: 3,
    40  			Target:        DefaultTarget,
    41  			ColorEnabled:  DefaultColorEnabled,
    42  			PluginRepositories: []PluginRepository{{
    43  				Name: DefaultPluginRepoName,
    44  				URL:  DefaultPluginRepoURL,
    45  			}},
    46  		},
    47  	}
    48  
    49  	var jsonError error
    50  
    51  	if _, err = os.Stat(configFilePath); err == nil || !os.IsNotExist(err) {
    52  		var file []byte
    53  		file, err = ioutil.ReadFile(configFilePath)
    54  		if err != nil {
    55  			return nil, err
    56  		}
    57  
    58  		if len(file) == 0 {
    59  			// TODO: change this to not use translatableerror
    60  			jsonError = translatableerror.EmptyConfigError{FilePath: configFilePath}
    61  		} else {
    62  			var configFile JSONConfig
    63  			err = json.Unmarshal(file, &configFile)
    64  			if err != nil {
    65  				return nil, err
    66  			}
    67  			config.ConfigFile = configFile
    68  		}
    69  	}
    70  
    71  	if config.ConfigFile.SSHOAuthClient == "" {
    72  		config.ConfigFile.SSHOAuthClient = DefaultSSHOAuthClient
    73  	}
    74  
    75  	if config.ConfigFile.UAAOAuthClient == "" {
    76  		config.ConfigFile.UAAOAuthClient = DefaultUAAOAuthClient
    77  		config.ConfigFile.UAAOAuthClientSecret = DefaultUAAOAuthClientSecret
    78  	}
    79  
    80  	config.ENV = EnvOverride{
    81  		BinaryName:       filepath.Base(os.Args[0]),
    82  		CFColor:          os.Getenv("CF_COLOR"),
    83  		CFDialTimeout:    os.Getenv("CF_DIAL_TIMEOUT"),
    84  		CFLogLevel:       os.Getenv("CF_LOG_LEVEL"),
    85  		CFPluginHome:     os.Getenv("CF_PLUGIN_HOME"),
    86  		CFStagingTimeout: os.Getenv("CF_STAGING_TIMEOUT"),
    87  		CFStartupTimeout: os.Getenv("CF_STARTUP_TIMEOUT"),
    88  		CFTrace:          os.Getenv("CF_TRACE"),
    89  		DockerPassword:   os.Getenv("CF_DOCKER_PASSWORD"),
    90  		Experimental:     os.Getenv("CF_CLI_EXPERIMENTAL"),
    91  		ForceTTY:         os.Getenv("FORCE_TTY"),
    92  		HTTPSProxy:       os.Getenv("https_proxy"),
    93  		Lang:             os.Getenv("LANG"),
    94  		LCAll:            os.Getenv("LC_ALL"),
    95  	}
    96  
    97  	pluginFilePath := filepath.Join(config.PluginHome(), "config.json")
    98  	if _, err = os.Stat(pluginFilePath); os.IsNotExist(err) {
    99  		config.pluginsConfig = PluginsConfig{
   100  			Plugins: make(map[string]Plugin),
   101  		}
   102  	} else {
   103  		var file []byte
   104  		file, err = ioutil.ReadFile(pluginFilePath)
   105  		if err != nil {
   106  			return nil, err
   107  		}
   108  
   109  		err = json.Unmarshal(file, &config.pluginsConfig)
   110  		if err != nil {
   111  			return nil, err
   112  		}
   113  
   114  		for name, plugin := range config.pluginsConfig.Plugins {
   115  			plugin.Name = name
   116  			config.pluginsConfig.Plugins[name] = plugin
   117  		}
   118  	}
   119  
   120  	if len(flags) > 0 {
   121  		config.Flags = flags[0]
   122  	}
   123  
   124  	pwd, err := os.Getwd()
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  
   129  	// Developer Note: The following is untested! Change at your own risk.
   130  	isTTY := terminal.IsTerminal(int(os.Stdout.Fd()))
   131  	terminalWidth := math.MaxInt32
   132  
   133  	if isTTY {
   134  		var err error
   135  		terminalWidth, _, err = terminal.GetSize(int(os.Stdout.Fd()))
   136  		if err != nil {
   137  			return nil, err
   138  		}
   139  	}
   140  
   141  	config.detectedSettings = detectedSettings{
   142  		currentDirectory: pwd,
   143  		terminalWidth:    terminalWidth,
   144  		tty:              isTTY,
   145  	}
   146  
   147  	return &config, jsonError
   148  }
   149  
   150  func removeOldTempConfigFiles() error {
   151  	oldTempFileNames, err := filepath.Glob(filepath.Join(configDirectory(), "temp-config?*"))
   152  	if err != nil {
   153  		return err
   154  	}
   155  
   156  	for _, oldTempFileName := range oldTempFileNames {
   157  		err = os.Remove(oldTempFileName)
   158  		if err != nil {
   159  			return err
   160  		}
   161  	}
   162  
   163  	return nil
   164  }