Test Failed
Pull Request — master (#17)
by Frank
06:05 queued 03:32
created

config.*Settings.prepareOutputPath   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
package config
2
3
import (
4
	"fmt"
5
	"os"
6
	"path/filepath"
7
)
8
9
// DbType represents a type of a database.
10
type DbType string
11
12
// String is the implementation of the Stringer interface needed for flag.Value interface.
13
func (db DbType) String() string {
14
	return string(db)
15
}
16
17
// Set sets the datatype for the custom type for the flag package.
18
func (db *DbType) Set(s string) error {
19
	*db = DbType(s)
20
	if *db == "" {
21
		*db = DbTypePostgresql
22
	}
23
	if !SupportedDbTypes[*db] {
24
		return fmt.Errorf("type of database %q not supported! supported: %v", *db, SprintfSupportedDbTypes())
25
	}
26
	return nil
27
}
28
29
// These database types are supported.
30
const (
31
	DbTypePostgresql DbType = "pg"
32
	DbTypeMySQL      DbType = "mysql"
33
)
34
35
// NullType represents a null type.
36
type NullType string
37
38
// String is the implementation of the Stringer interface needed for flag.Value interface.
39
func (t NullType) String() string {
40
	return string(t)
41
}
42
43
// Set sets the datatype for the custom type for the flag package.
44
func (t *NullType) Set(s string) error {
45
	*t = NullType(s)
46
	if *t == "" {
47
		*t = NullTypeSQL
48
	}
49
	if !supportedNullTypes[*t] {
50
		return fmt.Errorf("null type %q not supported! supported: %v", *t, SupportedNullTypes())
51
	}
52
	return nil
53
}
54
55
// These null types are supported. The types native and primitive map to the same
56
// underlying builtin golang type.
57
const (
58
	NullTypeSQL       NullType = "sql"
59
	NullTypeNative    NullType = "native"
60
	NullTypePrimitive NullType = "primitive"
61
)
62
63
// OutputFormat represents a output format option.
64
type OutputFormat string
65
66
// String is the implementation of the Stringer interface needed for flag.Value interface.
67
func (of OutputFormat) String() string {
68
	return string(of)
69
}
70
71
// Set sets the datatype for the custom type for the flag package.
72
func (of *OutputFormat) Set(s string) error {
73
	*of = OutputFormat(s)
74
	if *of == "" {
75
		*of = OutputFormatCamelCase
76
	}
77
	if !supportedOutputFormats[*of] {
78
		return fmt.Errorf("output format %q not supported", *of)
79
	}
80
	return nil
81
}
82
83
// These are the output format command line parameter.
84
const (
85
	OutputFormatCamelCase OutputFormat = "c"
86
	OutputFormatOriginal  OutputFormat = "o"
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
// NewSettings constructs settings with default values
151
func NewSettings() *Settings {
152
153
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
154
	if err != nil {
155
		dir = "."
156
	}
157
158
	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
	if err = settings.verifyOutputPath(); err != nil {
192
		return err
193
	}
194
195
	if settings.OutputFilePath, err = settings.prepareOutputPath(); err != nil {
196
		return err
197
	}
198
199
	if settings.Port == "" {
200
		settings.Port = dbDefaultPorts[settings.DbType]
201
	}
202
203
	if settings.PackageName == "" {
204
		return fmt.Errorf("name of package can not be empty")
205
	}
206
207
	if settings.VVerbose {
208
		settings.Verbose = true
209
	}
210
211
	return err
212
}
213
214
func (settings *Settings) verifyOutputPath() (err error) {
215
216
	info, err := os.Stat(settings.OutputFilePath)
217
218
	if os.IsNotExist(err) {
219
		return fmt.Errorf("output file path %q does not exists", settings.OutputFilePath)
220
	}
221
222
	if !info.Mode().IsDir() {
223
		return fmt.Errorf("output file path %q is not a directory", settings.OutputFilePath)
224
	}
225
226
	return err
227
}
228
229
func (settings *Settings) prepareOutputPath() (outputFilePath string, err error) {
230
	outputFilePath, err = filepath.Abs(settings.OutputFilePath)
231
	outputFilePath += string(filepath.Separator)
232
	return outputFilePath, err
233
}
234
235
// SprintfSupportedDbTypes returns a slice of strings as names of the supported database types
236
func SprintfSupportedDbTypes() string {
237
	names := make([]string, 0, len(SupportedDbTypes))
238
	for name := range SupportedDbTypes {
239
		names = append(names, string(name))
240
	}
241
	return fmt.Sprintf("%v", names)
242
}
243
244
// SupportedNullTypes returns a slice of strings as names of the supported null types
245
func SupportedNullTypes() string {
246
	names := make([]string, 0, len(supportedNullTypes))
247
	for name := range supportedNullTypes {
248
		names = append(names, string(name))
249
	}
250
	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
	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
	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
	return settings.OutputFormat == OutputFormatCamelCase
267
}
268