func (rules *ClientConfigLoadingRules) Migrate() error {
	if rules.MigrationRules == nil {
		return nil
	}
	for destination, source := range rules.MigrationRules {
		if _, err := os.Stat(destination); err == nil {
			continue
		} else if !os.IsNotExist(err) {
			return err
		}
		if sourceInfo, err := os.Stat(source); err != nil {
			if os.IsNotExist(err) {
				continue
			}
			return err
		} else if sourceInfo.IsDir() {
			return fmt.Errorf("cannot migrate %v to %v because it is a directory", source, destination)
		}
		in, err := os.Open(source)
		if err != nil {
			return err
		}
		defer in.Close()
		out, err := os.Create(destination)
		if err != nil {
			return err
		}
		defer out.Close()
		if _, err = io.Copy(out, in); err != nil {
			return err
		}
	}
	return nil
}
Migrate uses the MigrationRules map.  If a destination file is not present, then the source file is checked.
If the source file is present, then it is copied to the destination file BEFORE any further loading happens.
package clientcmd
import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"
	"github.com/golang/glog"
	"github.com/imdario/mergo"
	"k8s.io/kubernetes/pkg/api/unversioned"
	clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
	clientcmdlatest "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/latest"
	"k8s.io/kubernetes/pkg/runtime"
	utilerrors "k8s.io/kubernetes/pkg/util/errors"
)
const (
	RecommendedConfigPathFlag   = "kubeconfig"
	RecommendedConfigPathEnvVar = "KUBECONFIG"
	RecommendedHomeDir          = ".kube"
	RecommendedFileName         = "config"
	RecommendedSchemaName       = "schema"
)
var OldRecommendedHomeFile = path.Join(os.Getenv("HOME"), "/.kube/.kubeconfig")
var RecommendedHomeFile = path.Join(os.Getenv("HOME"), RecommendedHomeDir, RecommendedFileName)
var RecommendedSchemaFile = path.Join(os.Getenv("HOME"), RecommendedHomeDir, RecommendedSchemaName)
type ClientConfigLoadingRules struct {
	ExplicitPath string
	Precedence   []string
	MigrationRules map[string]string
	DoNotResolvePaths bool
}
func NewDefaultClientConfigLoadingRules() *ClientConfigLoadingRules {
	chain := []string{}
	migrationRules := map[string]string{}
	envVarFiles := os.Getenv(RecommendedConfigPathEnvVar)
	if len(envVarFiles) != 0 {
		chain = append(chain, filepath.SplitList(envVarFiles)...)
	} else {
		chain = append(chain, RecommendedHomeFile)
		migrationRules[RecommendedHomeFile] = OldRecommendedHomeFile
	}
	return &ClientConfigLoadingRules{
		Precedence:     chain,
		MigrationRules: migrationRules,
	}
}
func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) {
	if err := rules.Migrate(); err != nil {
		return nil, err
	}
	errlist := []error{}
	kubeConfigFiles := []string{}
	if len(rules.ExplicitPath) > 0 {
		if _, err := os.Stat(rules.ExplicitPath); os.IsNotExist(err) {
			return nil, err
		}
		kubeConfigFiles = append(kubeConfigFiles, rules.ExplicitPath)
	} else {
		kubeConfigFiles = append(kubeConfigFiles, rules.Precedence...)
	}
	kubeconfigs := []*clientcmdapi.Config{}
	for _, filename := range kubeConfigFiles {
		if len(filename) == 0 {
			continue
		}
		config, err := LoadFromFile(filename)
		if os.IsNotExist(err) {
			continue
		}
		if err != nil {
			errlist = append(errlist, fmt.Errorf("Error loading config file \"%s\": %v", filename, err))
			continue
		}
		kubeconfigs = append(kubeconfigs, config)
	}
	mapConfig := clientcmdapi.NewConfig()
	for _, kubeconfig := range kubeconfigs {
		mergo.Merge(mapConfig, kubeconfig)
	}
	nonMapConfig := clientcmdapi.NewConfig()
	for i := len(kubeconfigs) - 1; i >= 0; i-- {
		kubeconfig := kubeconfigs[i]
		mergo.Merge(nonMapConfig, kubeconfig)
	}
	config := clientcmdapi.NewConfig()
	mergo.Merge(config, mapConfig)
	mergo.Merge(config, nonMapConfig)
	if rules.ResolvePaths() {
		if err := ResolveLocalPaths(config); err != nil {
			errlist = append(errlist, err)
		}
	}
	return config, utilerrors.NewAggregate(errlist)
}