func (c *Config) ConfigSaveWriter(w io.Writer) error {
	out, err := json.MarshalIndent(c, "", "  ")
	if err != nil {
		return err
	}
	_, err = w.Write(out)
	return err
}
ConfigSaveWriter writes formatted json to the writer
package main
import (
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"os"
	"os/user"
	"path/filepath"
	"github.com/regclient/regclient/regclient"
)
var (
	ConfigFilename = "config.json"
	ConfigDir = ".regctl"
	ConfigEnv = "REGCTL_CONFIG"
)
type Config struct {
	Filename      string                 `json:"-"`                  
	Version       int                    `json:"version,omitempty"`  
	Hosts         map[string]*ConfigHost `json:"hosts"`
	IncDockerCred *bool                  `json:"incDockerCred,omitempty"`
	IncDockerCert *bool                  `json:"incDockerCert,omitempty"`
}
type ConfigHost struct {
	Name       string            `json:"-"`
	TLS        regclient.TLSConf `json:"tls,omitempty"`
	RegCert    string            `json:"regcert,omitempty"`
	ClientCert string            `json:"clientcert,omitempty"`
	ClientKey  string            `json:"clientkey,omitempty"`
	Hostname   string            `json:"hostname,omitempty"`
	User       string            `json:"user,omitempty"`
	Pass       string            `json:"pass,omitempty"`
	Token      string            `json:"token,omitempty"`
	PathPrefix string            `json:"pathPrefix,omitempty"`  
	Mirrors    []string          `json:"mirrors,omitempty"`     
	Priority   uint              `json:"priority,omitempty"`    
	API        string            `json:"api,omitempty"`         
	BlobChunk  int64             `json:"blobChunk,omitempty"`   
	BlobMax    int64             `json:"blobMax,omitempty"`     
}
func ConfigHostNew() *ConfigHost {
	h := ConfigHost{
		TLS: regclient.TLSEnabled,
	}
	return &h
}
func getConfigFilename() string {
	cf := os.Getenv(ConfigEnv)
	if cf == "" {
		return filepath.Join(getHomeDir(), ConfigDir, ConfigFilename)
	}
	return cf
}
func getHomeDir() string {
	h := os.Getenv("HOME")
	if h == "" {
		if u, err := user.Current(); err == nil {
			return u.HomeDir
		}
	}
	return h
}
func ConfigNew() *Config {
	c := Config{
		Hosts: map[string]*ConfigHost{},
	}
	return &c
}
func ConfigLoadReader(r io.Reader) (*Config, error) {
	c := ConfigNew()
	if err := json.NewDecoder(r).Decode(c); err != nil && !errors.Is(err, io.EOF) {
		return nil, err
	}
	if c.Version > 1 {
		return c, ErrUnsupportedConfigVersion
	}
	for h := range c.Hosts {
		if c.Hosts[h].Name == "" {
			c.Hosts[h].Name = h
		}
		if c.Hosts[h].Hostname == "" {
			c.Hosts[h].Hostname = h
		}
		if c.Hosts[h].TLS == regclient.TLSUndefined {
			c.Hosts[h].TLS = regclient.TLSEnabled
		}
		if h == regclient.DockerRegistryDNS || h == regclient.DockerRegistry {
			c.Hosts[h].Name = regclient.DockerRegistry
			if c.Hosts[h].Hostname == h {
				c.Hosts[h].Hostname = regclient.DockerRegistryDNS
			}
		}
		if c.Hosts[h].Name != h {
			c.Hosts[c.Hosts[h].Name] = c.Hosts[h]
			delete(c.Hosts, h)
		}
	}
	return c, nil
}
func ConfigLoadFile(filename string) (*Config, error) {
	_, err := os.Stat(filename)
	if err == nil {
		file, err := os.Open(filename)
		if err != nil {
			return nil, err
		}
		defer file.Close()
		c, err := ConfigLoadReader(file)
		if err != nil {
			return nil, err
		}
		c.Filename = filename
		return c, nil
	}
	return nil, err
}
func ConfigLoadDefault() (*Config, error) {
	filename := getConfigFilename()
	c, err := ConfigLoadFile(filename)
	if err != nil && os.IsNotExist(err) {
		c = ConfigNew()
		c.Filename = filename
		return c, nil
	}
	return c, err
}