forked from exercism/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.go
134 lines (120 loc) · 3.17 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package config
import (
"fmt"
"os"
"path/filepath"
"regexp"
"runtime"
"strings"
"github.com/spf13/viper"
)
var (
defaultBaseURL = "https://api.exercism.io/v1"
// DefaultDirName is the default name used for config and workspace directories.
DefaultDirName string
)
// Config lets us inject configuration options into commands.
type Config struct {
OS string
Home string
Dir string
DefaultBaseURL string
DefaultDirName string
UserViperConfig *viper.Viper
Persister Persister
}
// NewConfig provides a configuration with default values.
func NewConfig() Config {
home := userHome()
dir := Dir()
return Config{
OS: runtime.GOOS,
Dir: Dir(),
Home: home,
DefaultBaseURL: defaultBaseURL,
DefaultDirName: DefaultDirName,
Persister: FilePersister{Dir: dir},
}
}
// SetDefaultDirName configures the default directory name based on the name of the binary.
func SetDefaultDirName(binaryName string) {
DefaultDirName = strings.Replace(filepath.Base(binaryName), ".exe", "", 1)
}
// Dir is the configured config home directory.
// All the cli-related config files live in this directory.
func Dir() string {
var dir string
if runtime.GOOS == "windows" {
dir = os.Getenv("APPDATA")
if dir != "" {
return filepath.Join(dir, DefaultDirName)
}
} else {
dir := os.Getenv("EXERCISM_CONFIG_HOME")
if dir != "" {
return dir
}
dir = os.Getenv("XDG_CONFIG_HOME")
if dir == "" {
dir = filepath.Join(os.Getenv("HOME"), ".config")
}
if dir != "" {
return filepath.Join(dir, DefaultDirName)
}
}
// If all else fails, use the current directory.
dir, _ = os.Getwd()
return dir
}
func userHome() string {
var dir string
if runtime.GOOS == "windows" {
dir = os.Getenv("USERPROFILE")
if dir != "" {
return dir
}
dir = filepath.Join(os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH"))
if dir != "" {
return dir
}
} else {
dir = os.Getenv("HOME")
if dir != "" {
return dir
}
}
// If all else fails, use the current directory.
dir, _ = os.Getwd()
return dir
}
// DefaultWorkspaceDir provides a sensible default for the Exercism workspace.
// The default is different depending on the platform, in order to best match
// the conventions for that platform.
// It places the directory in the user's home path.
func DefaultWorkspaceDir(cfg Config) string {
dir := cfg.DefaultDirName
if cfg.OS != "linux" {
dir = strings.Title(dir)
}
return filepath.Join(cfg.Home, dir)
}
// Save persists a viper config of the base name.
func (c Config) Save(basename string) error {
return c.Persister.Save(c.UserViperConfig, basename)
}
// InferSiteURL guesses what the website URL is.
// The basis for the guess is which API we're submitting to.
func InferSiteURL(apiURL string) string {
if apiURL == "" {
apiURL = defaultBaseURL
}
if apiURL == "https://api.exercism.io/v1" {
return "https://exercism.io"
}
re := regexp.MustCompile("^(https?://[^/]*).*")
return re.ReplaceAllString(apiURL, "$1")
}
// SettingsURL provides a link to where the user can find their API token.
func SettingsURL(apiURL string) string {
return fmt.Sprintf("%s%s", InferSiteURL(apiURL), "/my/settings")
}