This repository has been archived by the owner on Jun 19, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
127 lines (108 loc) · 3.87 KB
/
main.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
package main
import (
"fmt"
"go/token"
"os"
"time"
"github.com/enescakir/emoji"
validation "github.com/go-ozzo/ozzo-validation/v4"
"github.com/gookit/color"
"github.com/lmittmann/tint"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"golang.org/x/exp/slog"
"github.com/totvs-cloud/pflagstruct/internal/code"
scanfld "github.com/totvs-cloud/pflagstruct/internal/scan/fld"
scanpkg "github.com/totvs-cloud/pflagstruct/internal/scan/pkg"
scanproj "github.com/totvs-cloud/pflagstruct/internal/scan/proj"
scanst "github.com/totvs-cloud/pflagstruct/internal/scan/st"
"github.com/totvs-cloud/pflagstruct/internal/syntree"
)
var (
directory, pkgPath, structName, destination string
debug bool
)
func NewCommand() (*cobra.Command, error) {
const (
directoryFlagName = "directory"
packageFlagName = "package"
structNameFlagName = "struct-name"
destinationFlagName = "destination"
debugFlagName = "debug"
)
cmd := &cobra.Command{
Use: "flagstruct",
SilenceErrors: true,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
flags := map[string]string{
"--" + directoryFlagName: directory,
"--" + packageFlagName: pkgPath,
"--" + structNameFlagName: structName,
"--" + destinationFlagName: destination,
}
err := validation.Validate(flags,
validation.Map(
validation.Key("--"+directoryFlagName),
validation.Key("--"+packageFlagName, validation.Required.When(directory == "").Error(fmt.Sprintf("either %s or %s is required.", "--"+packageFlagName, "--"+directoryFlagName))),
validation.Key("--"+structNameFlagName, validation.Required),
validation.Key("--"+destinationFlagName, validation.Required),
),
)
if err != nil {
return errors.WithStack(err)
}
scanner := syntree.NewScanner(token.NewFileSet())
projects := scanproj.NewFinder(scanner)
packages := scanpkg.NewFinder(scanner, projects)
structs := scanst.NewFinder(scanner, projects, packages)
fields := scanfld.NewFinder(packages, projects, structs)
if directory == "" {
proj, err := projects.FindProjectByDirectory(destination)
if err != nil {
return err
}
pkg, err := packages.FindPackageByPathAndProject(pkgPath, proj)
if err != nil {
return err
}
directory = pkg.Directory
}
filepath, err := code.NewGenerator(fields, packages, projects, structs).Generate(directory, structName, destination)
if err != nil {
return err
}
fmt.Printf("%s Code generated successfully! Find it at: %s\n", emoji.CheckMark, filepath)
return nil
},
}
cmd.Flags().StringVar(&structName, structNameFlagName, "", "specifies the name of the struct. This flag is required to generate code based on the provided struct")
cmd.Flags().StringVar(&pkgPath, packageFlagName, "", "specifies the package path of the struct definition. This flag is required if the --directory flag is not informed")
cmd.Flags().StringVar(&directory, directoryFlagName, "", "specifies the path where the source file containing the struct definition is located. This flag is required if the --package flag is not informed")
cmd.Flags().StringVar(&destination, destinationFlagName, ".", "specifies the path where the generated code will be saved")
cmd.Flags().BoolVar(&debug, debugFlagName, false, "enables debug mode, which provides additional output for debugging purposes")
return cmd, nil
}
func fatal(err error) {
if debug {
color.Redf("%s %+v\n", emoji.CrossMark, err)
os.Exit(1)
}
color.Redf("%s %s\n", emoji.CrossMark, err)
os.Exit(1)
}
func main() {
options := &tint.Options{TimeFormat: time.Kitchen}
if debug {
options.AddSource = true
options.Level = slog.LevelDebug
}
slog.SetDefault(slog.New(tint.NewHandler(os.Stderr, options)))
cmd, err := NewCommand()
if err != nil {
fatal(err)
}
if err = cmd.Execute(); err != nil {
fatal(err)
}
}