Skip to content

Commit 51c1edd

Browse files
authored
refactor: consolidate code and improve maintainability (#386)
1 parent c8d5f65 commit 51c1edd

File tree

14 files changed

+231
-488
lines changed

14 files changed

+231
-488
lines changed

.golangci.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ linters:
3434
- whitespace
3535

3636
linters-settings:
37+
revive:
38+
rules:
39+
- name: exported
40+
disabled: true
3741
gocognit:
3842
min-complexity: 25
3943
goconst:

Taskfile.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,12 @@ tasks:
4040
cmds:
4141
- for: [service_types, integration_types, integration_endpoint_types]
4242
cmd: "curl -so ./pkg/dist/{{.ITEM}}.yml https://raw.githubusercontent.com/aiven/go-api-schemas/refs/heads/main/pkg/dist/{{.ITEM}}.yml"
43+
fmt-imports:
44+
desc: Remove blank lines in Go import blocks and run goimports
45+
cmds:
46+
- find . -type f -name '*.go' -exec sed -i'' -e '/^import ($/,/^)$/{/^[[:space:]]*$/d;}' {} +
47+
- goimports -local "github.com/aiven/go-api-schemas" -w .
48+
fmt:
49+
desc: Format code
50+
cmds:
51+
- task: fmt-imports

cmd/root.go

Lines changed: 84 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,140 @@
1-
// Package cmd is the package that contains the commands of the application.
21
package cmd
32

43
import (
5-
"errors"
4+
"fmt"
5+
"log"
66
"os"
7-
"strings"
7+
"path/filepath"
88

99
"github.com/spf13/cobra"
10-
"github.com/spf13/pflag"
10+
"gopkg.in/yaml.v3"
1111

1212
"github.com/aiven/go-api-schemas/internal/diff"
1313
"github.com/aiven/go-api-schemas/internal/gen"
14-
"github.com/aiven/go-api-schemas/internal/pkg/types"
15-
"github.com/aiven/go-api-schemas/internal/pkg/util"
16-
"github.com/aiven/go-api-schemas/internal/reader"
17-
"github.com/aiven/go-api-schemas/internal/writer"
14+
"github.com/aiven/go-api-schemas/internal/types"
1815
)
1916

20-
// logger is the logger of the application.
21-
var logger = &util.Logger{}
22-
23-
// NewCmdRoot returns a pointer to the root command.
24-
func NewCmdRoot(l *util.Logger) *cobra.Command {
17+
func NewCmdRoot() *cobra.Command {
2518
cmd := &cobra.Command{
2619
Use: "go-api-schemas foo.json bar.json baz.json",
2720
Short: "go-api-schemas is a tool for generating and persisting user configuration option schemas from " +
2821
"Aiven APIs.",
29-
Run: run,
22+
RunE: run,
3023
Args: cobra.MinimumNArgs(1),
3124
}
3225

33-
cmd.Flags().StringP("output-dir", "o", "", "the output directory for the generated files")
34-
35-
cmd.Flags().BoolP("regenerate", "r", false, "regenerates the files in the output directory")
36-
37-
logger = l
38-
26+
cmd.Flags().StringP("output-dir", "o", "pkg/dist", "the output directory for the generated files")
27+
cmd.Flags().BoolP(
28+
"regenerate", "r", false,
29+
"regenerate files without comparing against existing files (useful for removing deprecations)",
30+
)
3931
return cmd
4032
}
4133

42-
// setupOutputDir sets up the output directory.
43-
func setupOutputDir(flags *pflag.FlagSet) error {
44-
outputDir, err := flags.GetString("output-dir")
34+
func run(cmd *cobra.Command, fileNames []string) error {
35+
outputDir, err := cmd.Flags().GetString("output-dir")
4536
if err != nil {
46-
return err
37+
return fmt.Errorf("error getting output directory: %w", err)
4738
}
4839

49-
if outputDir == "" {
50-
var wd string
51-
52-
wd, err = os.Getwd()
53-
if err != nil {
54-
return err
55-
}
40+
regenerate, err := cmd.Flags().GetBool("regenerate")
41+
if err != nil {
42+
return fmt.Errorf("error getting regeneration flag: %w", err)
43+
}
5644

57-
outputDir = strings.Join([]string{wd, "pkg/dist"}, string(os.PathSeparator))
45+
generationResult, err := gen.Run(fileNames...)
46+
if err != nil {
47+
return fmt.Errorf("error generating: %w", err)
48+
}
5849

59-
err = flags.Set("output-dir", outputDir)
50+
readResult := make(types.ReadResult)
51+
if !regenerate {
52+
readResult, err = read(outputDir)
6053
if err != nil {
61-
return err
54+
return fmt.Errorf("error reading files: %w", err)
6255
}
6356
}
6457

65-
fi, err := os.Stat(outputDir)
58+
diffResult, err := diff.Diff(readResult, generationResult)
6659
if err != nil {
67-
return err
60+
return fmt.Errorf("error diffing schemas: %w", err)
6861
}
6962

70-
if !fi.IsDir() {
71-
return errors.New("output directory is not a directory")
63+
err = write(outputDir, diffResult)
64+
if err != nil {
65+
return fmt.Errorf("error writing files: %w", err)
7266
}
73-
7467
return nil
7568
}
7669

77-
// setup sets up the application.
78-
func setup(flags *pflag.FlagSet) {
79-
logger.Info.Println("go-api-schemas tool started")
80-
81-
logger.Info.Println("setting up output directory")
82-
83-
if err := setupOutputDir(flags); err != nil {
84-
logger.Error.Fatalf("error setting up output directory: %s", err)
70+
func read(outputDir string) (types.ReadResult, error) {
71+
result := make(types.ReadResult)
72+
for k, v := range getSchemaFilenames() {
73+
result[k] = make(map[string]*types.UserConfigSchema)
74+
filePath := filepath.Join(outputDir, v)
75+
err := readFile(filePath, result[k])
76+
if err != nil && !os.IsNotExist(err) {
77+
return nil, fmt.Errorf("%q: %w", filePath, err)
78+
}
8579
}
8680

87-
logger.Info.Println("setting up environment variables")
81+
return result, nil
8882
}
8983

90-
// run is the function that is called when the rootCmd is executed.
91-
func run(cmd *cobra.Command, args []string) {
92-
flags := cmd.Flags()
84+
func readFile(filePath string, schema map[string]*types.UserConfigSchema) error {
85+
f, err := os.Open(filepath.Clean(filePath))
86+
if err != nil {
87+
return err
88+
}
9389

94-
setup(flags)
90+
defer withLogError(f.Close)
91+
return yaml.NewDecoder(f).Decode(schema)
92+
}
9593

96-
shouldRegenerate, err := flags.GetBool("regenerate")
97-
if err != nil {
98-
logger.Error.Fatalf("error getting regeneration flag: %s", err)
94+
func write(outputDir string, result types.DiffResult) error {
95+
for k, v := range getSchemaFilenames() {
96+
p := filepath.Join(outputDir, v)
97+
err := writeFile(p, result[k])
98+
if err != nil {
99+
return fmt.Errorf("%q: %w", p, err)
100+
}
99101
}
100102

101-
logger.Info.Println("generating")
103+
return nil
104+
}
102105

103-
gr, err := gen.Run(args...)
106+
func writeFile(filePath string, schema map[string]*types.UserConfigSchema) error {
107+
f, err := os.Create(filepath.Clean(filePath))
104108
if err != nil {
105-
logger.Error.Fatalf("error generating: %s", err)
109+
return err
106110
}
107111

108-
rr := make(types.ReadResult)
112+
defer withLogError(f.Close)
109113

110-
if !shouldRegenerate {
111-
logger.Info.Println("reading files")
114+
e := yaml.NewEncoder(f)
115+
defer withLogError(e.Close)
112116

113-
rr, err = reader.Run(logger, flags)
114-
if err != nil && !os.IsNotExist(err) {
115-
logger.Error.Fatalf("error reading files: %s", err)
116-
}
117-
}
117+
const indentSpaces = 2
118+
e.SetIndent(indentSpaces)
119+
return e.Encode(schema)
120+
}
118121

119-
logger.Info.Println("diffing")
120-
dr, err := diff.Run(rr, gr)
121-
if err != nil {
122-
logger.Error.Fatalf("error diffing: %s", err)
123-
}
122+
const (
123+
serviceSchemaFilename = "service_types.yml"
124+
integrationSchemaFilename = "integration_types.yml"
125+
integrationEndpointSchemaFilename = "integration_endpoint_types.yml"
126+
)
124127

125-
logger.Info.Println("writing files")
126-
if err = writer.Run(logger, flags, dr); err != nil {
127-
logger.Error.Fatalf("error writing files: %s", err)
128+
func getSchemaFilenames() map[types.SchemaType]string {
129+
return map[types.SchemaType]string{
130+
types.ServiceSchemaType: serviceSchemaFilename,
131+
types.IntegrationSchemaType: integrationSchemaFilename,
132+
types.IntegrationEndpointSchemaType: integrationEndpointSchemaFilename,
128133
}
134+
}
129135

130-
logger.Info.Println("done")
136+
func withLogError(f func() error) {
137+
if err := f(); err != nil {
138+
log.Println("[ERROR]: " + err.Error())
139+
}
131140
}

go.mod

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
module github.com/aiven/go-api-schemas
22

3-
go 1.24
3+
go 1.24.0
44

55
require (
6-
github.com/google/go-cmp v0.7.0
76
github.com/huandu/xstrings v1.5.0
87
github.com/spf13/cobra v1.10.1
9-
github.com/spf13/pflag v1.0.10
10-
github.com/stretchr/testify v1.11.1
11-
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8
8+
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
129
gopkg.in/yaml.v3 v3.0.1
1310
)
1411

1512
require (
16-
github.com/davecgh/go-spew v1.1.1 // indirect
1713
github.com/inconshreveable/mousetrap v1.1.0 // indirect
18-
github.com/pmezard/go-difflib v1.0.0 // indirect
14+
github.com/kr/pretty v0.3.1 // indirect
15+
github.com/rogpeppe/go-internal v1.14.1 // indirect
16+
github.com/spf13/pflag v1.0.10 // indirect
17+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
1918
)

go.sum

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
2-
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3-
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4-
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
5-
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
2+
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
63
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
74
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
85
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
96
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
10-
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
11-
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
7+
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
8+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
9+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
10+
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
11+
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
12+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
13+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
14+
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
15+
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
16+
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
17+
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
1218
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
1319
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
1420
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
1521
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
1622
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
1723
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
18-
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
19-
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
20-
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM=
21-
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
22-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
24+
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
25+
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
2326
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
27+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
28+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
2429
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
2530
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 commit comments

Comments
 (0)