-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.go
162 lines (134 loc) · 3.92 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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package zcmd
import (
"bytes"
"os"
"path/filepath"
"strings"
"github.com/mitchellh/go-homedir"
"github.com/mitchellh/mapstructure"
"github.com/spf13/viper"
"github.com/tcnksm/go-input"
)
type Config struct {
Sync SyncConfig `yaml:"sync,omitempty"`
Backup BackupConfig `yaml:"backup,omitempty"`
Repos ReposConfig `yaml:"repos,omitempty"`
DotFiles DotFilesConfig `yaml:"dotfiles,omitempty"`
Proxy []ProxyConfig `yaml:"proxy,omitempty"`
}
// SyncConfig is sync: config
type SyncConfig struct {
Pull []SyncInfo `yaml:"pull,omitempty"`
Push []SyncInfo `yaml:"push,omitempty"`
}
// SyncInfo is path information for synchronize directories
type SyncInfo struct {
Name string `yaml:"name"`
Source string `yaml:"source"`
Destination string `yaml:"destination"`
Excludes []string `yaml:"excludes,omitempty"`
DisableSudo bool `yaml:"disable_sudo,omitempty"`
}
// BackupConfig is backup: config
type BackupConfig struct {
Destinations []string `yaml:"destinations"`
Includes []string `yaml:"includes"`
Excludes []string `yaml:"excludes,omitempty"`
BackupPrefix string `yaml:"prefix,omitempty"`
}
// ReposConfig is repos: config
type ReposConfig struct {
Root string `yaml:"root"`
}
// nolint[gochecknoglobals]
// defaultDotFilesDir is default dotfiles directory path
var defaultDotFilesDir = filepath.Join(os.Getenv("HOME"), ".zdotfiles")
// DotFilesConfig is dotfiles: config
type DotFilesConfig struct {
Dir string `yaml:"dir,omitempty"`
Hosts []string `yaml:"hosts"`
Files []string `yaml:"files"`
}
// ProxyConfig is proxy: config
type ProxyConfig struct {
Name string `yaml:"name"`
User string `yaml:"user,omitempty"`
Address string `yaml:"address"`
Port int `yaml:"port,omitempty"`
PrivateKey string `yaml:"private_key"`
Forward []ProxyForwardConfig `yaml:"forward"`
}
// ProxyForwardType is ssh forwarding type
type ProxyForwardType string
const (
// DefaultProxyPort is default ssh port
DefaultProxyPort int = 22
// LocalForward is local forwarding
LocalForward ProxyForwardType = "local"
// RemoteForward is remote forwarding
RemoteForward ProxyForwardType = "remote"
// DynamicForward is dynamic forwarding
DynamicForward ProxyForwardType = "dynamic"
)
// ProxyForwardConfig is forward: config in proxy;
type ProxyForwardConfig struct {
Type ProxyForwardType `yaml:"type"`
BindAddress string `yaml:"bind_address,omitempty"`
BindPort int `yaml:"bind_port"`
RemoteAddress string `yaml:"remote_address,omitempty"`
RemotePort int `yaml:"remote_port,omitempty"`
}
// NewConfig returns new Config
func NewConfig(source []byte) (*Config, error) {
cfg := &Config{}
viper.SetConfigType("yaml")
err := viper.ReadConfig(bytes.NewBuffer(source))
if err != nil {
return nil, err
}
yamlTagOption := func(c *mapstructure.DecoderConfig) {
c.TagName = "yaml"
}
err = viper.Unmarshal(&cfg, yamlTagOption)
if err != nil {
return nil, err
}
err = SetDefaultConfigValues(cfg)
if err != nil {
return nil, err
}
return cfg, nil
}
// SetDefaultConfigValues set default values if omitted
func SetDefaultConfigValues(cfg *Config) error {
if len(cfg.DotFiles.Dir) == 0 {
cfg.DotFiles.Dir = defaultDotFilesDir
}
for i := range cfg.Proxy {
if cfg.Proxy[i].Port == 0 {
cfg.Proxy[i].Port = DefaultProxyPort
}
home, err := homedir.Dir()
if err != nil {
return err
}
if strings.HasPrefix(cfg.Proxy[i].PrivateKey, "~/") {
cfg.Proxy[i].PrivateKey = filepath.Join(home, cfg.Proxy[i].PrivateKey[2:])
}
}
return nil
}
func Ask(param *string, query string, hide bool) error {
ui := input.DefaultUI()
ans, err := ui.Ask(query, &input.Options{
Default: *param,
Required: true,
Loop: true,
Hide: hide,
})
if err != nil {
return err
}
*param = strings.TrimSpace(ans)
return nil
}