Skip to content

Commit 0300a34

Browse files
committed
go-to-protobuf: sort topological by imports
1 parent 45b0d9b commit 0300a34

File tree

2 files changed

+84
-2
lines changed
  • staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protobuf

2 files changed

+84
-2
lines changed

staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/BUILD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ go_library(
2323
"//staging/src/k8s.io/code-generator/pkg/util:go_default_library",
2424
"//staging/src/k8s.io/code-generator/third_party/forked/golang/reflect:go_default_library",
2525
"//vendor/github.com/spf13/pflag:go_default_library",
26+
"//vendor/gonum.org/v1/gonum/graph:go_default_library",
27+
"//vendor/gonum.org/v1/gonum/graph/simple:go_default_library",
28+
"//vendor/gonum.org/v1/gonum/graph/topo:go_default_library",
2629
"//vendor/k8s.io/gengo/args:go_default_library",
2730
"//vendor/k8s.io/gengo/generator:go_default_library",
2831
"//vendor/k8s.io/gengo/namer:go_default_library",

staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/cmd.go

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,20 @@ import (
2525
"os"
2626
"os/exec"
2727
"path/filepath"
28+
"sort"
2829
"strings"
2930

31+
flag "github.com/spf13/pflag"
32+
"gonum.org/v1/gonum/graph"
33+
"gonum.org/v1/gonum/graph/simple"
34+
"gonum.org/v1/gonum/graph/topo"
35+
3036
"k8s.io/code-generator/pkg/util"
3137
"k8s.io/gengo/args"
3238
"k8s.io/gengo/generator"
3339
"k8s.io/gengo/namer"
3440
"k8s.io/gengo/parser"
3541
"k8s.io/gengo/types"
36-
37-
flag "github.com/spf13/pflag"
3842
)
3943

4044
type Generator struct {
@@ -202,6 +206,18 @@ func Run(g *Generator) {
202206
c.Verify = g.Common.VerifyOnly
203207
c.FileTypes["protoidl"] = NewProtoFile()
204208

209+
// order package by imports, importees first
210+
deps := deps(c, protobufNames.packages)
211+
order, err := importOrder(deps)
212+
if err != nil {
213+
log.Fatalf("Failed to order packages by imports: %v", err)
214+
}
215+
topologicalPos := map[string]int{}
216+
for i, p := range order {
217+
topologicalPos[p] = i
218+
}
219+
sort.Sort(positionOrder{topologicalPos, protobufNames.packages})
220+
205221
var vendoredOutputPackages, localOutputPackages generator.Packages
206222
for _, p := range protobufNames.packages {
207223
if _, ok := nonOutputPackages[p.Name()]; ok {
@@ -347,3 +363,66 @@ func Run(g *Generator) {
347363
}
348364
}
349365
}
366+
367+
func deps(c *generator.Context, pkgs []*protobufPackage) map[string][]string {
368+
ret := map[string][]string{}
369+
for _, p := range pkgs {
370+
for _, d := range c.Universe[p.PackagePath].Imports {
371+
ret[p.PackagePath] = append(ret[p.PackagePath], d.Path)
372+
}
373+
}
374+
return ret
375+
}
376+
377+
func importOrder(deps map[string][]string) ([]string, error) {
378+
nodes := map[string]graph.Node{}
379+
names := map[int64]string{}
380+
g := simple.NewDirectedGraph()
381+
for pkg, imports := range deps {
382+
for _, imp := range imports {
383+
if _, found := nodes[pkg]; !found {
384+
n := g.NewNode()
385+
g.AddNode(n)
386+
nodes[pkg] = n
387+
names[n.ID()] = pkg
388+
}
389+
if _, found := nodes[imp]; !found {
390+
n := g.NewNode()
391+
g.AddNode(n)
392+
nodes[imp] = n
393+
names[n.ID()] = imp
394+
}
395+
g.SetEdge(g.NewEdge(nodes[imp], nodes[pkg]))
396+
}
397+
}
398+
399+
ret := []string{}
400+
sorted, err := topo.Sort(g)
401+
if err != nil {
402+
return nil, err
403+
}
404+
for _, n := range sorted {
405+
ret = append(ret, names[n.ID()])
406+
fmt.Println("topological order", names[n.ID()])
407+
}
408+
return ret, nil
409+
}
410+
411+
type positionOrder struct {
412+
pos map[string]int
413+
elements []*protobufPackage
414+
}
415+
416+
func (o positionOrder) Len() int {
417+
return len(o.elements)
418+
}
419+
420+
func (o positionOrder) Less(i, j int) bool {
421+
return o.pos[o.elements[i].PackagePath] < o.pos[o.elements[j].PackagePath]
422+
}
423+
424+
func (o positionOrder) Swap(i, j int) {
425+
x := o.elements[i]
426+
o.elements[i] = o.elements[j]
427+
o.elements[j] = x
428+
}

0 commit comments

Comments
 (0)