func WriteConfig(c *Config) error {
	rawConfig, err := json.MarshalIndent(c.ConfigFile, "", "  ")
	if err != nil {
		return err
	}
	dir := configDirectory()
	err = os.MkdirAll(dir, 0700)
	if err != nil {
		return err
	}
	sig := make(chan os.Signal, 10)
	signal.Notify(sig, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGQUIT, syscall.SIGTERM, os.Interrupt)
	defer signal.Stop(sig)
	tempConfigFile, err := ioutil.TempFile(dir, "temp-config")
	if err != nil {
		return err
	}
	tempConfigFile.Close()
	tempConfigFileName := tempConfigFile.Name()
	go catchSignal(sig, tempConfigFileName)
	err = ioutil.WriteFile(tempConfigFileName, rawConfig, 0600)
	if err != nil {
		return err
	}
	return os.Rename(tempConfigFileName, ConfigFilePath())
}
WriteConfig creates the .cf directory and then writes the config.json. The
location of .cf directory is written in the same way LoadConfig reads .cf
directory.
package configv3
import (
	"encoding/json"
	"io/ioutil"
	"math"
	"os"
	"os/signal"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
	"time"
	"golang.org/x/crypto/ssh/terminal"
	"code.cloudfoundry.org/cli/command/translatableerror"
	"code.cloudfoundry.org/cli/version"
)
const (
	DefaultDialTimeout = 5 * time.Second
	DefaultNOAARetryCount = 5
	DefaultOverallPollingTimeout = time.Duration(1 << 62)
	DefaultPollingInterval = 3 * time.Second
	DefaultStagingTimeout = 15 * time.Minute
	DefaultStartupTimeout = 5 * time.Minute
	DefaultTarget = ""
	DefaultSSHOAuthClient = "ssh-proxy"
	DefaultUAAOAuthClient = "cf"
	DefaultUAAOAuthClientSecret = ""
	DefaultRetryCount = 2
)
func LoadConfig(flags ...FlagOverride) (*Config, error) {
	err := removeOldTempConfigFiles()
	if err != nil {
		return nil, err
	}
	configFilePath := ConfigFilePath()
	config := Config{
		ConfigFile: CFConfig{
			ConfigVersion: 3,
			Target:        DefaultTarget,
			ColorEnabled:  DefaultColorEnabled,
			PluginRepositories: []PluginRepository{{
				Name: DefaultPluginRepoName,
				URL:  DefaultPluginRepoURL,
			}},
		},
	}
	var jsonError error
	if _, err = os.Stat(configFilePath); err == nil || !os.IsNotExist(err) {
		var file []byte
		file, err = ioutil.ReadFile(configFilePath)
		if err != nil {
			return nil, err
		}
		if len(file) == 0 {
			jsonError = translatableerror.EmptyConfigError{FilePath: configFilePath}
		} else {
			var configFile CFConfig
			err = json.Unmarshal(file, &configFile)
			if err != nil {
				return nil, err
			}
			config.ConfigFile = configFile
		}
	}
	if config.ConfigFile.SSHOAuthClient == "" {
		config.ConfigFile.SSHOAuthClient = DefaultSSHOAuthClient
	}
	if config.ConfigFile.UAAOAuthClient == "" {
		config.ConfigFile.UAAOAuthClient = DefaultUAAOAuthClient
		config.ConfigFile.UAAOAuthClientSecret = DefaultUAAOAuthClientSecret
	}
	config.ENV = EnvOverride{
		BinaryName:       filepath.Base(os.Args[0]),
		CFColor:          os.Getenv("CF_COLOR"),
		CFDialTimeout:    os.Getenv("CF_DIAL_TIMEOUT"),
		CFLogLevel:       os.Getenv("CF_LOG_LEVEL"),
		CFPluginHome:     os.Getenv("CF_PLUGIN_HOME"),
		CFStagingTimeout: os.Getenv("CF_STAGING_TIMEOUT"),
		CFStartupTimeout: os.Getenv("CF_STARTUP_TIMEOUT"),
		CFTrace:          os.Getenv("CF_TRACE"),
		DockerPassword:   os.Getenv("CF_DOCKER_PASSWORD"),
		Experimental:     os.Getenv("CF_CLI_EXPERIMENTAL"),
		ForceTTY:         os.Getenv("FORCE_TTY"),
		HTTPSProxy:       os.Getenv("https_proxy"),
		Lang:             os.Getenv("LANG"),
		LCAll:            os.Getenv("LC_ALL"),
	}
	pluginFilePath := filepath.Join(config.PluginHome(), "config.json")
	if _, err = os.Stat(pluginFilePath); os.IsNotExist(err) {
		config.pluginsConfig = PluginsConfig{
			Plugins: make(map[string]Plugin),
		}
	} else {
		var file []byte
		file, err = ioutil.ReadFile(pluginFilePath)
		if err != nil {
			return nil, err
		}
		err = json.Unmarshal(file, &config.pluginsConfig)
		if err != nil {
			return nil, err
		}
		for name, plugin := range config.pluginsConfig.Plugins {
			plugin.Name = name
			config.pluginsConfig.Plugins[name] = plugin
		}
	}
	if len(flags) > 0 {
		config.Flags = flags[0]
	}
	pwd, err := os.Getwd()
	if err != nil {
		return nil, err
	}
	isTTY := terminal.IsTerminal(int(os.Stdout.Fd()))
	terminalWidth := math.MaxInt32
	if isTTY {
		var err error
		terminalWidth, _, err = terminal.GetSize(int(os.Stdout.Fd()))
		if err != nil {
			return nil, err
		}
	}
	config.detectedSettings = detectedSettings{
		currentDirectory: pwd,
		terminalWidth:    terminalWidth,
		tty:              isTTY,
	}
	return &config, jsonError
}
func removeOldTempConfigFiles() error {
	oldTempFileNames, err := filepath.Glob(filepath.Join(configDirectory(), "temp-config?*"))
	if err != nil {
		return err
	}
	for _, oldTempFileName := range oldTempFileNames {
		err = os.Remove(oldTempFileName)
		if err != nil {
			return err
		}
	}
	return nil
}