• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

abice / go-enum / 16393245158

19 Jul 2025 10:13PM UTC coverage: 64.871% (-26.9%) from 91.721%
16393245158

Pull #258

github

abice
chore: convert to options struct
Pull Request #258: chore: update go versions

92 of 144 new or added lines in 3 files covered. (63.89%)

17 existing lines in 1 file now uncovered.

578 of 891 relevant lines covered (64.87%)

1007.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

2.96
/main.go
1
package main
2

3
import (
4
        "fmt"
5
        "log"
6
        "os"
7
        "path/filepath"
8
        "strings"
9

10
        "github.com/abice/go-enum/generator"
11
        "github.com/labstack/gommon/color"
12
        "github.com/urfave/cli/v2"
13
)
14

15
var (
16
        version string
17
        commit  string
18
        date    string
19
        builtBy string
20
)
21

22
type rootT struct {
23
        FileNames         cli.StringSlice
24
        NoPrefix          bool
25
        Lowercase         bool
26
        NoCase            bool
27
        Marshal           bool
28
        SQL               bool
29
        SQLInt            bool
30
        Flag              bool
31
        JsonPkg           string
32
        Prefix            string
33
        Names             bool
34
        Values            bool
35
        LeaveSnakeCase    bool
36
        SQLNullStr        bool
37
        SQLNullInt        bool
38
        Ptr               bool
39
        TemplateFileNames cli.StringSlice
40
        Aliases           cli.StringSlice
41
        BuildTags         cli.StringSlice
42
        MustParse         bool
43
        ForceLower        bool
44
        ForceUpper        bool
45
        NoComments        bool
46
        OutputSuffix      string
47
}
48

49
func main() {
×
50
        var argv rootT
×
51

×
52
        clr := color.New()
×
53
        out := func(format string, args ...interface{}) {
×
54
                _, _ = fmt.Fprintf(clr.Output(), format, args...)
×
55
        }
×
56

57
        app := &cli.App{
×
58
                Name:            "go-enum",
×
59
                Usage:           "An enum generator for go",
×
60
                HideHelpCommand: true,
×
61
                Version:         version,
×
62
                Flags: []cli.Flag{
×
63
                        &cli.StringSliceFlag{
×
64
                                Name:        "file",
×
65
                                Aliases:     []string{"f"},
×
66
                                EnvVars:     []string{"GOFILE"},
×
67
                                Usage:       "The file(s) to generate enums.  Use more than one flag for more files.",
×
68
                                Required:    true,
×
69
                                Destination: &argv.FileNames,
×
70
                        },
×
71
                        &cli.BoolFlag{
×
72
                                Name:        "noprefix",
×
73
                                Usage:       "Prevents the constants generated from having the Enum as a prefix.",
×
74
                                Destination: &argv.NoPrefix,
×
75
                        },
×
76
                        &cli.BoolFlag{
×
77
                                Name:        "lower",
×
78
                                Usage:       "Adds lowercase variants of the enum strings for lookup.",
×
79
                                Destination: &argv.Lowercase,
×
80
                        },
×
81
                        &cli.BoolFlag{
×
82
                                Name:        "nocase",
×
83
                                Usage:       "Adds case insensitive parsing to the enumeration (forces lower flag).",
×
84
                                Destination: &argv.NoCase,
×
85
                        },
×
86
                        &cli.BoolFlag{
×
87
                                Name:        "marshal",
×
88
                                Usage:       "Adds text (and inherently json) marshalling functions.",
×
89
                                Destination: &argv.Marshal,
×
90
                        },
×
91
                        &cli.BoolFlag{
×
92
                                Name:        "sql",
×
93
                                Usage:       "Adds SQL database scan and value functions.",
×
94
                                Destination: &argv.SQL,
×
95
                        },
×
96
                        &cli.BoolFlag{
×
97
                                Name:        "sqlint",
×
98
                                Usage:       "Tells the generator that a string typed enum should be stored in sql as an integer value.",
×
99
                                Destination: &argv.SQLInt,
×
100
                        },
×
101
                        &cli.BoolFlag{
×
102
                                Name:        "flag",
×
103
                                Usage:       "Adds golang flag functions.",
×
104
                                Destination: &argv.Flag,
×
105
                        },
×
106
                        &cli.StringFlag{
×
107
                                Name:        "jsonpkg",
×
108
                                Usage:       "Custom json package for imports instead encoding/json.",
×
109
                                Destination: &argv.JsonPkg,
×
110
                        },
×
111
                        &cli.StringFlag{
×
112
                                Name:        "prefix",
×
113
                                Usage:       "Adds a prefix with a user one. If you would like to replace the prefix, then combine this option with --noprefix.",
×
114
                                Destination: &argv.Prefix,
×
115
                        },
×
116
                        &cli.BoolFlag{
×
117
                                Name:        "names",
×
118
                                Usage:       "Generates a 'Names() []string' function, and adds the possible enum values in the error response during parsing",
×
119
                                Destination: &argv.Names,
×
120
                        },
×
121
                        &cli.BoolFlag{
×
122
                                Name:        "values",
×
123
                                Usage:       "Generates a 'Values() []{{ENUM}}' function.",
×
124
                                Destination: &argv.Values,
×
125
                        },
×
126
                        &cli.BoolFlag{
×
127
                                Name:        "nocamel",
×
128
                                Usage:       "Removes the snake_case to CamelCase name changing",
×
129
                                Destination: &argv.LeaveSnakeCase,
×
130
                        },
×
131
                        &cli.BoolFlag{
×
132
                                Name:        "ptr",
×
133
                                Usage:       "Adds a pointer method to get a pointer from const values",
×
134
                                Destination: &argv.Ptr,
×
135
                        },
×
136
                        &cli.BoolFlag{
×
137
                                Name:        "sqlnullint",
×
138
                                Usage:       "Adds a Null{{ENUM}} type for marshalling a nullable int value to sql",
×
139
                                Destination: &argv.SQLNullInt,
×
140
                        },
×
141
                        &cli.BoolFlag{
×
142
                                Name:        "sqlnullstr",
×
143
                                Usage:       "Adds a Null{{ENUM}} type for marshalling a nullable string value to sql.  If sqlnullint is specified too, it will be Null{{ENUM}}Str",
×
144
                                Destination: &argv.SQLNullStr,
×
145
                        },
×
146
                        &cli.StringSliceFlag{
×
147
                                Name:        "template",
×
148
                                Aliases:     []string{"t"},
×
149
                                Usage:       "Additional template file(s) to generate enums.  Use more than one flag for more files. Templates will be executed in alphabetical order.",
×
150
                                Destination: &argv.TemplateFileNames,
×
151
                        },
×
152
                        &cli.StringSliceFlag{
×
153
                                Name:        "alias",
×
154
                                Aliases:     []string{"a"},
×
155
                                Usage:       "Adds or replaces aliases for a non alphanumeric value that needs to be accounted for. [Format should be \"key:value,key2:value2\", or specify multiple entries, or both!]",
×
156
                                Destination: &argv.Aliases,
×
157
                        },
×
158
                        &cli.BoolFlag{
×
159
                                Name:        "mustparse",
×
160
                                Usage:       "Adds a Must version of the Parse that will panic on failure.",
×
161
                                Destination: &argv.MustParse,
×
162
                        },
×
163
                        &cli.BoolFlag{
×
164
                                Name:        "forcelower",
×
165
                                Usage:       "Forces a camel cased comment to generate lowercased names.",
×
166
                                Destination: &argv.ForceLower,
×
167
                        },
×
168
                        &cli.BoolFlag{
×
169
                                Name:        "forceupper",
×
170
                                Usage:       "Forces a camel cased comment to generate uppercased names.",
×
171
                                Destination: &argv.ForceUpper,
×
172
                        },
×
173
                        &cli.BoolFlag{
×
174
                                Name:        "nocomments",
×
175
                                Usage:       "Removes auto generated comments.  If you add your own comments, these will still be created.",
×
176
                                Destination: &argv.NoComments,
×
177
                        },
×
178
                        &cli.StringSliceFlag{
×
179
                                Name:        "buildtag",
×
180
                                Aliases:     []string{"b"},
×
181
                                Usage:       "Adds build tags to a generated enum file.",
×
182
                                Destination: &argv.BuildTags,
×
183
                        },
×
184
                        &cli.StringFlag{
×
185
                                Name:        "output-suffix",
×
186
                                Usage:       "Changes the default filename suffix of _enum to something else.  `.go` will be appended to the end of the string no matter what, so that `_test.go` cases can be accommodated ",
×
187
                                Destination: &argv.OutputSuffix,
×
188
                        },
×
189
                },
×
190
                Action: func(ctx *cli.Context) error {
×
191
                        aliases, err := generator.ParseAliases(argv.Aliases.Value())
×
192
                        if err != nil {
×
193
                                return err
×
194
                        }
×
195
                        for _, fileOption := range argv.FileNames.Value() {
×
196

×
NEW
197
                                // Collect all options
×
NEW
198
                                var options []generator.Option
×
199

×
NEW
200
                                options = append(options, generator.WithBuildTags(argv.BuildTags.Value()...))
×
NEW
201
                                options = append(options, generator.WithAliases(aliases))
×
202

×
203
                                if argv.NoPrefix {
×
NEW
204
                                        options = append(options, generator.WithNoPrefix())
×
205
                                }
×
206
                                if argv.Lowercase {
×
NEW
207
                                        options = append(options, generator.WithLowercaseVariant())
×
208
                                }
×
209
                                if argv.NoCase {
×
NEW
210
                                        options = append(options, generator.WithCaseInsensitiveParse())
×
211
                                }
×
212
                                if argv.Marshal {
×
NEW
213
                                        options = append(options, generator.WithMarshal())
×
214
                                }
×
215
                                if argv.SQL {
×
NEW
216
                                        options = append(options, generator.WithSQLDriver())
×
217
                                }
×
218
                                if argv.SQLInt {
×
NEW
219
                                        options = append(options, generator.WithSQLInt())
×
220
                                }
×
221
                                if argv.Flag {
×
NEW
222
                                        options = append(options, generator.WithFlag())
×
223
                                }
×
224
                                if argv.Names {
×
NEW
225
                                        options = append(options, generator.WithNames())
×
226
                                }
×
227
                                if argv.Values {
×
NEW
228
                                        options = append(options, generator.WithValues())
×
229
                                }
×
230
                                if argv.LeaveSnakeCase {
×
NEW
231
                                        options = append(options, generator.WithoutSnakeToCamel())
×
232
                                }
×
233
                                if argv.JsonPkg != "" {
×
NEW
234
                                        options = append(options, generator.WithJsonPkg(argv.JsonPkg))
×
235
                                }
×
236
                                if argv.Prefix != "" {
×
NEW
237
                                        options = append(options, generator.WithPrefix(argv.Prefix))
×
238
                                }
×
239
                                if argv.Ptr {
×
NEW
240
                                        options = append(options, generator.WithPtr())
×
241
                                }
×
242
                                if argv.SQLNullInt {
×
NEW
243
                                        options = append(options, generator.WithSQLNullInt())
×
244
                                }
×
245
                                if argv.SQLNullStr {
×
NEW
246
                                        options = append(options, generator.WithSQLNullStr())
×
247
                                }
×
248
                                if argv.MustParse {
×
NEW
249
                                        options = append(options, generator.WithMustParse())
×
250
                                }
×
251
                                if argv.ForceLower {
×
NEW
252
                                        options = append(options, generator.WithForceLower())
×
253
                                }
×
254
                                if argv.ForceUpper {
×
NEW
255
                                        options = append(options, generator.WithForceUpper())
×
256
                                }
×
257
                                if argv.NoComments {
×
NEW
258
                                        options = append(options, generator.WithNoComments())
×
259
                                }
×
260
                                if templates := []string(argv.TemplateFileNames.Value()); len(templates) > 0 {
×
261
                                        for _, t := range templates {
×
262
                                                if fn, err := globFilenames(t); err != nil {
×
263
                                                        return err
×
264
                                                } else {
×
NEW
265
                                                        options = append(options, generator.WithTemplates(fn...))
×
266
                                                }
×
267
                                        }
268
                                }
269

270
                                // Create generator with all options
NEW
271
                                g := generator.NewGenerator(options...)
×
NEW
272
                                g.Version = version
×
NEW
273
                                g.Revision = commit
×
NEW
274
                                g.BuildDate = date
×
NEW
275
                                g.BuiltBy = builtBy
×
NEW
276

×
277
                                var filenames []string
×
278
                                if fn, err := globFilenames(fileOption); err != nil {
×
279
                                        return err
×
280
                                } else {
×
281
                                        filenames = fn
×
282
                                }
×
283

284
                                outputSuffix := `_enum`
×
285
                                if argv.OutputSuffix != "" {
×
286
                                        outputSuffix = argv.OutputSuffix
×
287
                                }
×
288

289
                                for _, fileName := range filenames {
×
290
                                        originalName := fileName
×
291

×
292
                                        out("go-enum started. file: %s\n", color.Cyan(originalName))
×
293
                                        fileName, _ = filepath.Abs(fileName)
×
294

×
295
                                        outFilePath := fmt.Sprintf("%s%s.go", strings.TrimSuffix(fileName, filepath.Ext(fileName)), outputSuffix)
×
296
                                        if strings.HasSuffix(fileName, "_test.go") {
×
297
                                                outFilePath = strings.Replace(outFilePath, "_test"+outputSuffix+".go", outputSuffix+"_test.go", 1)
×
298
                                        }
×
299

300
                                        // Parse the file given in arguments
301
                                        raw, err := g.GenerateFromFile(fileName)
×
302
                                        if err != nil {
×
303
                                                return fmt.Errorf("failed generating enums\nInputFile=%s\nError=%s", color.Cyan(fileName), color.RedBg(err))
×
304
                                        }
×
305

306
                                        // Nothing was generated, ignore the output and don't create a file.
307
                                        if len(raw) < 1 {
×
308
                                                out(color.Yellow("go-enum ignored. file: %s\n"), color.Cyan(originalName))
×
309
                                                continue
×
310
                                        }
311

312
                                        mode := int(0o644)
×
313
                                        err = os.WriteFile(outFilePath, raw, os.FileMode(mode))
×
314
                                        if err != nil {
×
315
                                                return fmt.Errorf("failed writing to file %s: %s", color.Cyan(outFilePath), color.Red(err))
×
316
                                        }
×
317
                                        out("go-enum finished. file: %s\n", color.Cyan(originalName))
×
318
                                }
319
                        }
320

321
                        return nil
×
322
                },
323
        }
324

325
        if err := app.Run(os.Args); err != nil {
×
326
                log.Fatal(err)
×
327
        }
×
328
}
329

330
// globFilenames gets a list of filenames matching the provided filename.
331
// In order to maintain existing capabilities, only glob when a * is in the path.
332
// Leave execution on par with old method in case there are bad patterns in use that somehow
333
// work without the Glob method.
334
func globFilenames(filename string) ([]string, error) {
33✔
335
        if strings.Contains(filename, "*") {
48✔
336
                matches, err := filepath.Glob(filename)
15✔
337
                if err != nil {
15✔
338
                        return []string{}, fmt.Errorf("failed parsing glob filepath\nInputFile=%s\nError=%s", color.Cyan(filename), color.RedBg(err))
×
339
                }
×
340
                return matches, nil
15✔
341
        } else {
18✔
342
                return []string{filename}, nil
18✔
343
        }
18✔
344
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc