podman

Форк
0
/
generator.go 
189 строк · 4.2 Кб
1
//go:build ignore
2

3
package main
4

5
// This program generates *_options_.go files to be used by the bindings calls to API service.
6
// It can be invoked by running go generate
7

8
import (
9
	"errors"
10
	"fmt"
11
	"go/ast"
12
	"go/parser"
13
	"go/token"
14
	"os"
15
	"os/exec"
16
	"strings"
17
	"text/template"
18
	"unicode"
19
	"unicode/utf8"
20
)
21

22
var bodyTmpl = `// Code generated by go generate; DO NOT EDIT.
23
package {{.PackageName}}
24

25
import (
26
{{range $import := .Imports}}	{{$import}}
27
{{end}}
28
)
29

30
// Changed returns true if named field has been set
31
func (o *{{.StructName}}) Changed(fieldName string) bool {
32
	return util.Changed(o, fieldName)
33
}
34

35
// ToParams formats struct fields to be passed to API service
36
func (o *{{.StructName}}) ToParams() (url.Values, error) {
37
	return util.ToParams(o)
38
}
39

40
{{range $field := .Fields}}
41
// With{{.Name}} set {{if .Comment}}{{.Comment}}{{else}}field {{.Name}} to given value{{end}}
42
func(o *{{.StructName}}) With{{.Name}}(value {{.Type}}) *{{.StructName}} {
43
	o.{{.Name}} = {{if not .Composite}}&{{end}}value
44
	return o
45
}
46

47
// Get{{.Name}} returns value of {{if .Comment}}{{.Comment}}{{else}}field {{.Name}}{{end}}
48
func(o *{{.StructName}}) Get{{.Name}}() {{.Type}} {
49
	if o.{{.Name}} == nil {
50
		var z {{.Type}}
51
		return z
52
	}
53
    return {{if not .Composite}}*{{end}}o.{{.Name}}
54
}
55
{{end}}
56
`
57

58
type fieldStruct struct {
59
	Comment    string
60
	Composite  bool
61
	Name       string
62
	StructName string
63
	Type       string
64
}
65

66
func main() {
67
	var (
68
		closed       bool
69
		fieldStructs []fieldStruct
70
	)
71
	srcFile := os.Getenv("GOFILE")
72
	inputStructName := os.Args[1]
73
	b, err := os.ReadFile(srcFile)
74
	if err != nil {
75
		panic(err)
76
	}
77
	fset := token.NewFileSet() // positions are relative to fset
78
	f, err := parser.ParseFile(fset, "", b, parser.ParseComments)
79
	if err != nil {
80
		panic(err)
81
	}
82

83
	// always add reflect
84
	imports := []string{"\"reflect\"", "\"github.com/containers/podman/v5/pkg/bindings/internal/util\""}
85
	for _, imp := range f.Imports {
86
		imports = append(imports, imp.Path.Value)
87
	}
88

89
	out, err := os.Create(strings.TrimRight(srcFile, ".go") + "_" + strings.Replace(strings.ToLower(inputStructName), "options", "_options", 1) + ".go")
90
	if err != nil {
91
		panic(err)
92
	}
93
	defer func() {
94
		if !closed {
95
			out.Close()
96
		}
97
	}()
98

99
	body := template.Must(template.New("body").Parse(bodyTmpl))
100

101
	ast.Inspect(f, func(n ast.Node) bool {
102
		ref, refOK := n.(*ast.TypeSpec)
103
		if !(refOK && ref.Name.Name == inputStructName) {
104
			return true
105
		}
106

107
		x := ref.Type.(*ast.StructType)
108
		for _, field := range x.Fields.List {
109
			var name string
110
			if len(field.Names) > 0 {
111
				name = field.Names[0].Name
112
				if len(name) < 1 {
113
					panic(errors.New("bad name"))
114
				}
115
			}
116

117
			var composite bool
118
			switch field.Type.(type) {
119
			case *ast.MapType, *ast.StructType, *ast.ArrayType:
120
				composite = true
121
			}
122

123
			//sub := "*"
124
			typeExpr := field.Type
125
			start := typeExpr.Pos() - 1
126
			end := typeExpr.End() - 1
127
			fieldType := strings.Replace(string(b[start:end]), "*", "", 1)
128

129
			fieldStructs = append(fieldStructs, fieldStruct{
130
				Comment:    fmtComment(field.Comment.Text()),
131
				Composite:  composite,
132
				Name:       name,
133
				StructName: inputStructName,
134
				Type:       fieldType,
135
			})
136
		} // for
137

138
		bodyStruct := struct {
139
			PackageName string
140
			Imports     []string
141
			StructName  string
142
			Fields      []fieldStruct
143
		}{
144
			PackageName: os.Getenv("GOPACKAGE"),
145
			Imports:     imports,
146
			StructName:  inputStructName,
147
			Fields:      fieldStructs,
148
		}
149

150
		// create the body
151
		if err := body.Execute(out, bodyStruct); err != nil {
152
			fmt.Println(err)
153
			os.Exit(1)
154
		}
155

156
		// close out file
157
		if err := out.Close(); err != nil {
158
			fmt.Println(err)
159
			os.Exit(1)
160
		}
161
		closed = true
162

163
		// go fmt file
164
		gofmt := exec.Command("go", "fmt", out.Name())
165
		gofmt.Stderr = os.Stdout
166
		if err := gofmt.Run(); err != nil {
167
			fmt.Println(err)
168
			os.Exit(1)
169
		}
170

171
		// go import file
172
		goimport := exec.Command("../../../test/tools/build/goimports", "-w", out.Name())
173
		goimport.Stderr = os.Stdout
174
		if err := goimport.Run(); err != nil {
175
			fmt.Println(err)
176
			os.Exit(1)
177
		}
178
		return true
179
	})
180
}
181

182
func fmtComment(comment string) string {
183
	r, n := utf8.DecodeRuneInString(comment)
184
	if r != utf8.RuneError {
185
		comment = string(unicode.ToLower(r)) + comment[n:]
186
	}
187
	comment = strings.TrimSpace(comment)
188
	return comment
189
}
190

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.