Skip to content

Commit 450752d

Browse files
committed
chore: configuration v2 cloner
1 parent 519820a commit 450752d

File tree

16 files changed

+1193
-0
lines changed

16 files changed

+1193
-0
lines changed

.golangci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ linters:
171171
linters: [gosec]
172172
text: "G306: Expect WriteFile permissions to be 0600 or less"
173173

174+
# Related to migration command.
175+
- path: pkg/commands/internal/migrate/two/
176+
linters:
177+
- lll
178+
174179
formatters:
175180
enable:
176181
- gofmt

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ fast_check_generated:
6060
git checkout -- go.mod go.sum # can differ between go1.16 and go1.17
6161
git diff --exit-code # check no changes
6262

63+
# Migration
64+
65+
clone_config:
66+
go run ./pkg/commands/internal/migrate/cloner/
67+
6368
# Benchmark
6469

6570
# Benchmark with a local version
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"go/ast"
7+
"go/parser"
8+
"go/printer"
9+
"go/token"
10+
"log"
11+
"os"
12+
"path/filepath"
13+
"reflect"
14+
"strings"
15+
16+
"golang.org/x/tools/imports"
17+
)
18+
19+
const newPkgName = "two"
20+
21+
const (
22+
srcDir = "./pkg/config"
23+
dstDir = "./pkg/commands/internal/migrate/two"
24+
)
25+
26+
func main() {
27+
stat, err := os.Stat(srcDir)
28+
if err != nil {
29+
log.Fatal(err)
30+
}
31+
32+
if !stat.IsDir() {
33+
log.Fatalf("%s is not a directory", srcDir)
34+
}
35+
36+
_ = os.RemoveAll(dstDir)
37+
38+
err = processPackage(srcDir, dstDir)
39+
if err != nil {
40+
log.Fatalf("Processing package error: %v", err)
41+
}
42+
}
43+
44+
func processPackage(srcDir, dstDir string) error {
45+
return filepath.Walk(srcDir, func(srcPath string, _ os.FileInfo, err error) error {
46+
if err != nil {
47+
return err
48+
}
49+
50+
if skipFile(srcPath) {
51+
return nil
52+
}
53+
54+
fset := token.NewFileSet()
55+
56+
file, err := parser.ParseFile(fset, srcPath, nil, parser.AllErrors)
57+
if err != nil {
58+
return fmt.Errorf("parsing %s: %w", srcPath, err)
59+
}
60+
61+
processFile(file)
62+
63+
return writeNewFile(fset, file, srcPath, dstDir)
64+
})
65+
}
66+
67+
func skipFile(path string) bool {
68+
if !strings.HasSuffix(path, ".go") || strings.HasSuffix(path, "_test.go") {
69+
return true
70+
}
71+
72+
if filepath.Base(path) == "base_loader.go" {
73+
return true
74+
}
75+
76+
if filepath.Base(path) == "loader.go" {
77+
return true
78+
}
79+
80+
return false
81+
}
82+
83+
func processFile(file *ast.File) {
84+
file.Name.Name = newPkgName
85+
86+
var newDecls []ast.Decl
87+
for _, decl := range file.Decls {
88+
switch d := decl.(type) {
89+
case *ast.FuncDecl:
90+
continue
91+
92+
case *ast.GenDecl:
93+
switch d.Tok {
94+
case token.CONST, token.VAR:
95+
continue
96+
case token.TYPE:
97+
for _, spec := range d.Specs {
98+
typeSpec, ok := spec.(*ast.TypeSpec)
99+
if !ok {
100+
continue
101+
}
102+
103+
structType, ok := typeSpec.Type.(*ast.StructType)
104+
if !ok {
105+
continue
106+
}
107+
108+
processStructFields(structType)
109+
}
110+
default:
111+
// noop
112+
}
113+
114+
newDecls = append(newDecls, decl)
115+
}
116+
}
117+
118+
file.Decls = newDecls
119+
}
120+
121+
func processStructFields(structType *ast.StructType) {
122+
var newFields []*ast.Field
123+
124+
for _, field := range structType.Fields.List {
125+
if len(field.Names) > 0 && !field.Names[0].IsExported() {
126+
continue
127+
}
128+
129+
if field.Tag == nil {
130+
continue
131+
}
132+
133+
field.Type = convertType(field.Type)
134+
field.Tag.Value = convertStructTag(field.Tag.Value)
135+
136+
newFields = append(newFields, field)
137+
}
138+
139+
structType.Fields.List = newFields
140+
}
141+
142+
func convertType(expr ast.Expr) ast.Expr {
143+
ident, ok := expr.(*ast.Ident)
144+
if !ok {
145+
return expr
146+
}
147+
148+
switch ident.Name {
149+
case "bool", "string", "int", "int8", "int16", "int32", "int64", "float32", "float64":
150+
return &ast.StarExpr{X: ident}
151+
152+
default:
153+
return expr
154+
}
155+
}
156+
157+
func convertStructTag(value string) string {
158+
structTag := reflect.StructTag(strings.Trim(value, "`"))
159+
160+
key := structTag.Get("mapstructure")
161+
162+
if key == ",squash" {
163+
return wrapStructTag(`yaml:",inline"`)
164+
}
165+
166+
return wrapStructTag(fmt.Sprintf(`yaml:"%[1]s,omitempty" toml:"%[1]s,omitempty"`, key))
167+
}
168+
169+
func wrapStructTag(s string) string {
170+
return "`" + s + "`"
171+
}
172+
173+
func writeNewFile(fset *token.FileSet, file *ast.File, srcPath, dstDir string) error {
174+
var buf bytes.Buffer
175+
176+
err := printer.Fprint(&buf, fset, file)
177+
if err != nil {
178+
return fmt.Errorf("printing %s: %w", srcPath, err)
179+
}
180+
181+
dstPath := filepath.Join(dstDir, filepath.Base(srcPath))
182+
183+
_ = os.MkdirAll(filepath.Dir(dstPath), os.ModePerm)
184+
185+
formatted, err := imports.Process(dstPath, buf.Bytes(), nil)
186+
if err != nil {
187+
return fmt.Errorf("formatting %s: %w", dstPath, err)
188+
}
189+
190+
//nolint:gosec,mnd // The permission is right.
191+
err = os.WriteFile(dstPath, formatted, 0o644)
192+
if err != nil {
193+
return fmt.Errorf("writing file %s: %w", dstPath, err)
194+
}
195+
196+
return nil
197+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package ptr
2+
3+
func Deref[T any](v *T) T {
4+
if v == nil {
5+
var zero T
6+
return zero
7+
}
8+
9+
return *v
10+
}
11+
12+
func Pointer[T any](v T) *T { return &v }
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package two
2+
3+
type BaseRule struct {
4+
Linters []string `yaml:"linters,omitempty" toml:"linters,omitempty"`
5+
Path *string `yaml:"path,omitempty" toml:"path,omitempty"`
6+
PathExcept *string `yaml:"path-except,omitempty" toml:"path-except,omitempty"`
7+
Text *string `yaml:"text,omitempty" toml:"text,omitempty"`
8+
Source *string `yaml:"source,omitempty" toml:"source,omitempty"`
9+
10+
InternalReference *string `yaml:"-,omitempty" toml:"-,omitempty"`
11+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package two
2+
3+
type Config struct {
4+
Version *string `yaml:"version,omitempty" toml:"version,omitempty"`
5+
6+
Run Run `yaml:"run,omitempty" toml:"run,omitempty"`
7+
8+
Output Output `yaml:"output,omitempty" toml:"output,omitempty"`
9+
10+
Linters Linters `yaml:"linters,omitempty" toml:"linters,omitempty"`
11+
12+
Issues Issues `yaml:"issues,omitempty" toml:"issues,omitempty"`
13+
Severity Severity `yaml:"severity,omitempty" toml:"severity,omitempty"`
14+
15+
Formatters Formatters `yaml:"formatters,omitempty" toml:"formatters,omitempty"`
16+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package two
2+
3+
type Formatters struct {
4+
Enable []string `yaml:"enable,omitempty" toml:"enable,omitempty"`
5+
Settings FormatterSettings `yaml:"settings,omitempty" toml:"settings,omitempty"`
6+
Exclusions FormatterExclusions `yaml:"exclusions,omitempty" toml:"exclusions,omitempty"`
7+
}
8+
9+
type FormatterExclusions struct {
10+
Generated *string `yaml:"generated,omitempty" toml:"generated,omitempty"`
11+
Paths []string `yaml:"paths,omitempty" toml:"paths,omitempty"`
12+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package two
2+
3+
type FormatterSettings struct {
4+
Gci GciSettings `yaml:"gci,omitempty" toml:"gci,omitempty"`
5+
GoFmt GoFmtSettings `yaml:"gofmt,omitempty" toml:"gofmt,omitempty"`
6+
GoFumpt GoFumptSettings `yaml:"gofumpt,omitempty" toml:"gofumpt,omitempty"`
7+
GoImports GoImportsSettings `yaml:"goimports,omitempty" toml:"goimports,omitempty"`
8+
GoLines GoLinesSettings `yaml:"golines,omitempty" toml:"golines,omitempty"`
9+
}
10+
11+
type GciSettings struct {
12+
Sections []string `yaml:"sections,omitempty" toml:"sections,omitempty"`
13+
NoInlineComments *bool `yaml:"no-inline-comments,omitempty" toml:"no-inline-comments,omitempty"`
14+
NoPrefixComments *bool `yaml:"no-prefix-comments,omitempty" toml:"no-prefix-comments,omitempty"`
15+
CustomOrder *bool `yaml:"custom-order,omitempty" toml:"custom-order,omitempty"`
16+
NoLexOrder *bool `yaml:"no-lex-order,omitempty" toml:"no-lex-order,omitempty"`
17+
}
18+
19+
type GoFmtSettings struct {
20+
Simplify *bool `yaml:"simplify,omitempty" toml:"simplify,omitempty"`
21+
RewriteRules []GoFmtRewriteRule `yaml:"rewrite-rules,omitempty" toml:"rewrite-rules,omitempty"`
22+
}
23+
24+
type GoFmtRewriteRule struct {
25+
Pattern *string `yaml:"pattern,omitempty" toml:"pattern,omitempty"`
26+
Replacement *string `yaml:"replacement,omitempty" toml:"replacement,omitempty"`
27+
}
28+
29+
type GoFumptSettings struct {
30+
ModulePath *string `yaml:"module-path,omitempty" toml:"module-path,omitempty"`
31+
ExtraRules *bool `yaml:"extra-rules,omitempty" toml:"extra-rules,omitempty"`
32+
33+
LangVersion *string `yaml:"-,omitempty" toml:"-,omitempty"`
34+
}
35+
36+
type GoImportsSettings struct {
37+
LocalPrefixes []string `yaml:"local-prefixes,omitempty" toml:"local-prefixes,omitempty"`
38+
}
39+
40+
type GoLinesSettings struct {
41+
MaxLen *int `yaml:"max-len,omitempty" toml:"max-len,omitempty"`
42+
TabLen *int `yaml:"tab-len,omitempty" toml:"tab-len,omitempty"`
43+
ShortenComments *bool `yaml:"shorten-comments,omitempty" toml:"shorten-comments,omitempty"`
44+
ReformatTags *bool `yaml:"reformat-tags,omitempty" toml:"reformat-tags,omitempty"`
45+
ChainSplitDots *bool `yaml:"chain-split-dots,omitempty" toml:"chain-split-dots,omitempty"`
46+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package two
2+
3+
type Issues struct {
4+
MaxIssuesPerLinter *int `yaml:"max-issues-per-linter,omitempty" toml:"max-issues-per-linter,omitempty"`
5+
MaxSameIssues *int `yaml:"max-same-issues,omitempty" toml:"max-same-issues,omitempty"`
6+
UniqByLine *bool `yaml:"uniq-by-line,omitempty" toml:"uniq-by-line,omitempty"`
7+
8+
DiffFromRevision *string `yaml:"new-from-rev,omitempty" toml:"new-from-rev,omitempty"`
9+
DiffFromMergeBase *string `yaml:"new-from-merge-base,omitempty" toml:"new-from-merge-base,omitempty"`
10+
DiffPatchFilePath *string `yaml:"new-from-patch,omitempty" toml:"new-from-patch,omitempty"`
11+
WholeFiles *bool `yaml:"whole-files,omitempty" toml:"whole-files,omitempty"`
12+
Diff *bool `yaml:"new,omitempty" toml:"new,omitempty"`
13+
14+
NeedFix *bool `yaml:"fix,omitempty" toml:"fix,omitempty"`
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package two
2+
3+
type Linters struct {
4+
Default *string `yaml:"default,omitempty" toml:"default,omitempty"`
5+
Enable []string `yaml:"enable,omitempty" toml:"enable,omitempty"`
6+
Disable []string `yaml:"disable,omitempty" toml:"disable,omitempty"`
7+
FastOnly *bool `yaml:"fast-only,omitempty" toml:"fast-only,omitempty"`
8+
9+
Settings LintersSettings `yaml:"settings,omitempty" toml:"settings,omitempty"`
10+
11+
Exclusions LinterExclusions `yaml:"exclusions,omitempty" toml:"exclusions,omitempty"`
12+
}

0 commit comments

Comments
 (0)