Skip to content

Commit 64d507f

Browse files
committed
Draft: automate exporting CV spec
1 parent b7717cb commit 64d507f

File tree

3 files changed

+160
-0
lines changed

3 files changed

+160
-0
lines changed

tools/importcvspec/importcvspec.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"go/ast"
6+
"go/build"
7+
"go/importer"
8+
"go/parser"
9+
"go/token"
10+
"go/types"
11+
"log"
12+
13+
"golang.org/x/exp/maps"
14+
)
15+
16+
func main() {
17+
fset := token.NewFileSet()
18+
19+
pkg := parseWithTypes(fset)
20+
fmt.Println("Package parsed and type checked", pkg.Name())
21+
22+
cvs := pkg.Scope().Lookup("ClusterVersionSpec")
23+
if cvs == nil {
24+
log.Fatal("ClusterVersionSpec not found")
25+
}
26+
fmt.Println("ClusterVersionSpec found")
27+
fmt.Println(types.ObjectString(cvs, types.RelativeTo(pkg)))
28+
str, ok := cvs.Type().Underlying().(*types.Struct)
29+
if !ok {
30+
log.Fatal("ClusterVersionSpec is not a struct")
31+
}
32+
33+
toExport := extractNamed([]types.Object{cvs}, str)
34+
35+
fmt.Println("####################")
36+
37+
for _, obj := range toExport {
38+
fmt.Println(types.ObjectString(obj, types.RelativeTo(pkg)))
39+
}
40+
41+
fmt.Println("####################")
42+
43+
}
44+
45+
func extractNamed(toExport []types.Object, cvs types.Type) []types.Object {
46+
switch t := cvs.(type) {
47+
case *types.Named:
48+
fmt.Println("Named type", t.Obj())
49+
toExport = append(toExport, t.Obj())
50+
toExport = extractNamed(toExport, t.Underlying())
51+
case *types.Basic:
52+
case *types.Pointer:
53+
toExport = extractNamed(toExport, t.Elem())
54+
case *types.Array:
55+
toExport = extractNamed(toExport, t.Elem())
56+
case *types.Slice:
57+
toExport = extractNamed(toExport, t.Elem())
58+
case *types.Map:
59+
toExport = extractNamed(toExport, t.Key())
60+
toExport = extractNamed(toExport, t.Elem())
61+
case *types.Struct:
62+
for i := 0; i < t.NumFields(); i++ {
63+
field := t.Field(i)
64+
fmt.Printf("%s (%T)\n", field.String(), field.Type())
65+
toExport = extractNamed(toExport, field.Type())
66+
}
67+
default:
68+
log.Fatalf("Type not yet supported %T", t)
69+
}
70+
return toExport
71+
}
72+
73+
func parseWithTypes(fset *token.FileSet) *types.Package {
74+
imp, err := build.Import("github.com/openshift/api/config/v1", "", build.FindOnly)
75+
if err != nil {
76+
log.Fatal(err)
77+
}
78+
fmt.Println("Import from: ", imp.Dir)
79+
rawPkgs, err := parser.ParseDir(fset, imp.Dir, nil, parser.SkipObjectResolution)
80+
if err != nil {
81+
log.Fatal(err)
82+
}
83+
rawPkg := rawPkgs["v1"]
84+
info := types.Info{
85+
Types: make(map[ast.Expr]types.TypeAndValue),
86+
Defs: make(map[*ast.Ident]types.Object),
87+
Uses: make(map[*ast.Ident]types.Object),
88+
}
89+
conf := types.Config{
90+
Importer: importer.ForCompiler(fset, "source", nil),
91+
}
92+
pkg, err := conf.Check(imp.Dir, fset, maps.Values(rawPkg.Files), &info)
93+
if err != nil {
94+
log.Fatal(err)
95+
}
96+
return pkg
97+
}

tools/impt/impt_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package impt_test
2+
3+
import (
4+
"fmt"
5+
"go/ast"
6+
"go/build"
7+
"go/importer"
8+
"go/parser"
9+
"go/token"
10+
"go/types"
11+
"log"
12+
"testing"
13+
14+
"golang.org/x/exp/maps"
15+
)
16+
17+
func TestImport(t *testing.T) {
18+
fset := token.NewFileSet()
19+
pt := parseWithTypes(fset)
20+
fmt.Println("Package parsed and type checked", pt.Name())
21+
fmt.Println("Package path", pt)
22+
}
23+
24+
func parseWithTypes(fset *token.FileSet) *types.Package {
25+
imp, err := build.Import("github.com/appuio/openshift-upgrade-controller/tools/toimp", "", build.FindOnly)
26+
if err != nil {
27+
log.Fatal(err)
28+
}
29+
fmt.Println("Import from: ", imp.Dir)
30+
rawPkgs, err := parser.ParseDir(fset, imp.Dir, nil, parser.SkipObjectResolution)
31+
if err != nil {
32+
log.Fatal(err)
33+
}
34+
rawPkg := rawPkgs["toimp"]
35+
info := types.Info{
36+
Types: make(map[ast.Expr]types.TypeAndValue),
37+
Defs: make(map[*ast.Ident]types.Object),
38+
Uses: make(map[*ast.Ident]types.Object),
39+
}
40+
conf := types.Config{
41+
Importer: importer.ForCompiler(fset, "source", nil),
42+
}
43+
pkg, err := conf.Check(imp.Dir, fset, maps.Values(rawPkg.Files), &info)
44+
if err != nil {
45+
log.Fatal(err)
46+
}
47+
return pkg
48+
}

tools/toimp/toimp.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package toimp
2+
3+
import configv1 "github.com/openshift/api/config/v1"
4+
5+
type ClusterID string
6+
7+
type LocalSpec struct {
8+
ClusterID ClusterID `json:"clusterID"`
9+
}
10+
11+
func Convert(ls LocalSpec) configv1.ClusterVersionSpec {
12+
cvs := configv1.ClusterVersionSpec{}
13+
cvs.ClusterID = configv1.ClusterID(ls.ClusterID)
14+
return cvs
15+
}

0 commit comments

Comments
 (0)