Passed
Pull Request — master (#30)
by
unknown
01:36
created

pkg/settings/settings.go   A

Size/Duplication

Total Lines 306
Duplicated Lines 0 %

Test Coverage

Coverage 85.94%

Importance

Changes 0
Metric Value
cc 36
eloc 166
dl 0
loc 306
ccs 55
cts 64
cp 0.8594
crap 39.6021
rs 9.52
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
A settings.*DbType.Set 0 9 3
A settings.*NullType.Set 0 9 3
A settings.NullType.String 0 2 1
A settings.OutputFormat.String 0 2 1
A settings.*OutputFormat.Set 0 9 3
A settings.DbType.String 0 2 1
A settings.*FileNameCasing.Set 0 9 3
B settings.*Settings.Verify 0 23 6
A settings.*Settings.verifyOutputPath 0 13 3
A settings.FileNameCasing.String 0 2 1
A settings.*Settings.ShouldInitialism 0 2 1
A settings.SprintfSupportedNullTypes 0 6 2
A settings.SprintfSupportedDbTypes 0 6 2
A settings.*Settings.IsFileNameCasingSnakeCase 0 2 1
A settings.*Settings.IsNullTypeSQL 0 2 1
A settings.*Settings.IsOutputFormatCamelCase 0 2 1
A settings.*Settings.prepareOutputPath 0 4 1
A settings.New 0 36 2
1
package settings
2
3
import (
4
	"fmt"
5
	"os"
6
	"path/filepath"
7
)
8
9
// These database types are supported.
10
const (
11
	DbTypePostgresql DbType = "pg"
12
	DbTypeMySQL      DbType = "mysql"
13
	DbTypeSQLite     DbType = "sqlite3"
14
)
15
16
// DbType represents a type of a database.
17
type DbType string
18
19
// Set sets the datatype for the custom type for the flag package.
20
func (db *DbType) Set(s string) error {
21 1
	*db = DbType(s)
22 1
	if *db == "" {
23 1
		*db = DbTypePostgresql
24
	}
25 1
	if !SupportedDbTypes[*db] {
26 1
		return fmt.Errorf("type of database %q not supported! supported: %v", *db, SprintfSupportedDbTypes())
27
	}
28 1
	return nil
29
}
30
31
// String is the implementation of the Stringer interface needed for flag.Value interface.
32
func (db DbType) String() string {
33 1
	return string(db)
34
}
35
36
// These null types are supported. The types native and primitive map to the same
37
// underlying builtin golang type.
38
const (
39
	NullTypeSQL       NullType = "sql"
40
	NullTypeNative    NullType = "native"
41
	NullTypePrimitive NullType = "primitive"
42
)
43
44
// NullType represents a null type.
45
type NullType string
46
47
// Set sets the datatype for the custom type for the flag package.
48
func (t *NullType) Set(s string) error {
49 1
	*t = NullType(s)
50 1
	if *t == "" {
51 1
		*t = NullTypeSQL
52
	}
53 1
	if !supportedNullTypes[*t] {
54 1
		return fmt.Errorf("null type %q not supported! supported: %v", *t, SprintfSupportedNullTypes())
55
	}
56 1
	return nil
57
}
58
59
// String is the implementation of the Stringer interface needed for flag.Value interface.
60
func (t NullType) String() string {
61 1
	return string(t)
62
}
63
64
// These are the output format command line parameter.
65
const (
66
	OutputFormatCamelCase OutputFormat = "c"
67
	OutputFormatOriginal  OutputFormat = "o"
68
)
69
70
// OutputFormat represents a output format option.
71
type OutputFormat string
72
73
// Set sets the datatype for the custom type for the flag package.
74
func (of *OutputFormat) Set(s string) error {
75 1
	*of = OutputFormat(s)
76 1
	if *of == "" {
77 1
		*of = OutputFormatCamelCase
78
	}
79 1
	if !supportedOutputFormats[*of] {
80 1
		return fmt.Errorf("output format %q not supported", *of)
81
	}
82 1
	return nil
83
}
84
85
// String is the implementation of the Stringer interface needed for flag.Value interface.
86
func (of OutputFormat) String() string {
87 1
	return string(of)
88
}
89
90
const (
91
	FileNameCasingCamelCase = "c"
92
	FileNameCasingSnakeCase = "s"
93
)
94
95
// FileNameCasing represents a output filename casing
96
type FileNameCasing string
97
98
func (of *FileNameCasing) Set(s string) error {
99
	*of = FileNameCasing(s)
100
	if *of == "" {
101
		*of = FileNameCasingCamelCase
102
	}
103
	if !supportedFileNameCasings[*of] {
104
		return fmt.Errorf("output format %q not supported", *of)
105
	}
106
	return nil
107
}
108
109
func (of FileNameCasing) String() string {
110
	return string(of)
111
}
112
113
var (
114
	// SupportedDbTypes represents the supported databases
115
	SupportedDbTypes = map[DbType]bool{
116
		DbTypePostgresql: true,
117
		DbTypeMySQL:      true,
118
		DbTypeSQLite:     true,
119
	}
120
121
	// supportedOutputFormats represents the supported output formats
122
	supportedOutputFormats = map[OutputFormat]bool{
123
		OutputFormatCamelCase: true,
124
		OutputFormatOriginal:  true,
125
	}
126
127
	// dbDefaultPorts maps the database type to the default ports
128
	dbDefaultPorts = map[DbType]string{
129
		DbTypePostgresql: "5432",
130
		DbTypeMySQL:      "3306",
131
		DbTypeSQLite:     "",
132
	}
133
134
	// supportedNullTypes represents the supported types of NULL types
135
	supportedNullTypes = map[NullType]bool{
136
		NullTypeSQL:       true,
137
		NullTypeNative:    true,
138
		NullTypePrimitive: true,
139
	}
140
141
	supportedFileNameCasings = map[FileNameCasing]bool{
142
		FileNameCasingCamelCase: true,
143
		FileNameCasingSnakeCase: true,
144
	}
145
)
146
147
// Settings stores the supported settings / command line arguments
148
type Settings struct {
149
	Verbose  bool
150
	VVerbose bool
151
	Force    bool // continue through errors
152
153
	DbType DbType
154
155
	User   string
156
	Pswd   string
157
	DbName string
158
	Schema string
159
	Host   string
160
	Port   string
161
162
	OutputFilePath string
163
	OutputFormat   OutputFormat
164
165
	FileNameCasing FileNameCasing
166
	PackageName    string
167
	Prefix         string
168
	Suffix         string
169
	Null           NullType
170
171
	NoInitialism bool
172
173
	TagsNoDb bool
174
175
	TagsMastermindStructable       bool
176
	TagsMastermindStructableOnly   bool
177
	IsMastermindStructableRecorder bool
178
179
	// TODO not implemented yet
180
	TagsGorm bool
181
}
182
183
// New constructs settings with default values
184
func New() *Settings {
185
186 1
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
187 1
	if err != nil {
188
		dir = "."
189
	}
190
191 1
	return &Settings{
192
		Verbose:  false,
193
		VVerbose: false,
194
		Force:    false,
195
196
		DbType:         DbTypePostgresql,
197
		User:           "",
198
		Pswd:           "",
199
		DbName:         "postgres",
200
		Schema:         "public",
201
		Host:           "127.0.0.1",
202
		Port:           "", // left blank -> is automatically determined if not set
203
		OutputFilePath: dir,
204
		OutputFormat:   OutputFormatCamelCase,
205
		FileNameCasing: FileNameCasingCamelCase,
206
		PackageName:    "dto",
207
		Prefix:         "",
208
		Suffix:         "",
209
		Null:           NullTypeSQL,
210
211
		NoInitialism: false,
212
213
		TagsNoDb: false,
214
215
		TagsMastermindStructable:       false,
216
		TagsMastermindStructableOnly:   false,
217
		IsMastermindStructableRecorder: false,
218
219
		TagsGorm: false,
220
	}
221
}
222
223
// Verify verifies the settings and checks the given output paths
224
func (settings *Settings) Verify() (err error) {
225
226 1
	if err = settings.verifyOutputPath(); err != nil {
227 1
		return err
228
	}
229
230 1
	if settings.OutputFilePath, err = settings.prepareOutputPath(); err != nil {
231
		return err
232
	}
233
234 1
	if settings.Port == "" {
235 1
		settings.Port = dbDefaultPorts[settings.DbType]
236
	}
237
238 1
	if settings.PackageName == "" {
239 1
		return fmt.Errorf("name of package can not be empty")
240
	}
241
242 1
	if settings.VVerbose {
243 1
		settings.Verbose = true
244
	}
245
246 1
	return err
247
}
248
249
func (settings *Settings) verifyOutputPath() (err error) {
250
251 1
	info, err := os.Stat(settings.OutputFilePath)
252
253 1
	if os.IsNotExist(err) {
254 1
		return fmt.Errorf("output file path %q does not exists", settings.OutputFilePath)
255
	}
256
257 1
	if !info.Mode().IsDir() {
258 1
		return fmt.Errorf("output file path %q is not a directory", settings.OutputFilePath)
259
	}
260
261 1
	return err
262
}
263
264
func (settings *Settings) prepareOutputPath() (outputFilePath string, err error) {
265 1
	outputFilePath, err = filepath.Abs(settings.OutputFilePath)
266 1
	outputFilePath += string(filepath.Separator)
267 1
	return outputFilePath, err
268
}
269
270
// SprintfSupportedDbTypes returns a slice of strings as names of the supported database types
271
func SprintfSupportedDbTypes() string {
272 1
	names := make([]string, 0, len(SupportedDbTypes))
273 1
	for name := range SupportedDbTypes {
274 1
		names = append(names, string(name))
275
	}
276 1
	return fmt.Sprintf("%v", names)
277
}
278
279
// SprintfSupportedNullTypes returns a slice of strings as names of the supported null types
280
func SprintfSupportedNullTypes() string {
281 1
	names := make([]string, 0, len(supportedNullTypes))
282 1
	for name := range supportedNullTypes {
283 1
		names = append(names, string(name))
284
	}
285 1
	return fmt.Sprintf("%v", names)
286
}
287
288
// IsNullTypeSQL returns true if the type given by the command line args is of null type SQL
289
func (settings *Settings) IsNullTypeSQL() bool {
290 1
	return settings.Null == NullTypeSQL
291
}
292
293
// ShouldInitialism returns wheather or not if column names should be converted
294
// to initialisms.
295
func (settings *Settings) ShouldInitialism() bool {
296 1
	return !settings.NoInitialism
297
}
298
299
// IsOutputFormatCamelCase returns if the type given by command line args is of camel-case format.
300
func (settings *Settings) IsOutputFormatCamelCase() bool {
301 1
	return settings.OutputFormat == OutputFormatCamelCase
302
}
303
304
// IsFileNameCasingSnakeCase returns if the type given by the command line args is snake-case format
305
func (settings *Settings) IsFileNameCasingSnakeCase() bool {
306 1
	return settings.FileNameCasing == FileNameCasingSnakeCase
307
}
308