internal/shape/build.go
Ref: Size: 1.1 KiB History
package shape
import (
"sort"
"strings"
)
// Build converts a raw `go list` package set into the deterministic Model:
// module prefix stripped, plane classified, doc synopsized, internal imports
// kept (stdlib/external dropped). Every slice is sorted so identical input —
// in any order — yields byte-identical output.
func Build(raw []rawPackage) Model {
pkgs := make([]Package, 0, len(raw))
for _, r := range raw {
rel := strings.TrimPrefix(r.ImportPath, module+"/")
// Non-nil so a package with no internal imports marshals to [] not
// null — the viewer's JS iterates this field and would crash on null.
imps := make([]string, 0, len(r.Imports))
for _, imp := range r.Imports {
if after, ok := strings.CutPrefix(imp, module+"/"); ok {
imps = append(imps, after)
}
}
sort.Strings(imps)
pkgs = append(pkgs, Package{
ImportPath: rel,
Plane: Classify(rel),
Synopsis: synopsis(r.Doc),
Imports: imps,
})
}
sort.Slice(pkgs, func(i, j int) bool { return pkgs[i].ImportPath < pkgs[j].ImportPath })
return Model{Module: module, Packages: pkgs}
}