Passed
Pull Request — master (#17)
by Frank
06:11 queued 03:57
created

settings.*Settings.Verify   B

Complexity

Conditions 6

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 6.027

Importance

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