a73x

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}
}