Skip to content

Commit

Permalink
pkg: swap go/build for go/packages in gen.go
Browse files Browse the repository at this point in the history
This is the first step towards using go/types to load type information
such as constant values and function signatures without handling ASTs.

No changes in the generated output.

Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
Change-Id: Ie28990b225c6cf5c39bb06da76686837d02c5113
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/557327
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>
  • Loading branch information
mvdan committed Sep 4, 2023
1 parent bf3ac20 commit e9a412d
Showing 1 changed file with 35 additions and 18 deletions.
53 changes: 35 additions & 18 deletions pkg/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"flag"
"fmt"
"go/ast"
gobuild "go/build"
"go/constant"
"go/format"
"go/parser"
Expand All @@ -43,6 +42,8 @@ import (
"strings"
"text/template"

"golang.org/x/tools/go/packages"

"cuelang.org/go/cue"
"cuelang.org/go/cue/build"
"cuelang.org/go/cue/errors"
Expand All @@ -56,8 +57,6 @@ const genFile = "pkg.go"
//go:embed packages.txt
var packagesStr string

var packages = strings.Fields(packagesStr)

type headerParams struct {
GoPkg string
CUEPkg string
Expand Down Expand Up @@ -89,19 +88,35 @@ var _ = adt.TopKind // in case the adt package isn't used
{{end}}
`))

const pkgParent = "cuelang.org/go/pkg"

func main() {
flag.Parse()
log.SetFlags(log.Lshortfile)
log.SetOutput(os.Stdout)

for _, pkg := range packages {
var packagesList []string
for _, pkg := range strings.Fields(packagesStr) {
if pkg == "path" {
// TODO remove this special case. Currently the path
// pkg.go file cannot be generated automatically but that
// will be possible when we can attach arbitrary signatures
// to builtin functions.
continue
}
packagesList = append(packagesList, path.Join(pkgParent, pkg))
}

cfg := &packages.Config{Mode: packages.NeedName | packages.NeedFiles}
pkgs, err := packages.Load(cfg, packagesList...)
if err != nil {
fmt.Fprintf(os.Stderr, "load: %v\n", err)
os.Exit(1)
}
if packages.PrintErrors(pkgs) > 0 {
os.Exit(1)
}
for _, pkg := range pkgs {
if err := generate(pkg); err != nil {
log.Fatalf("%s: %v", pkg, err)
}
Expand All @@ -116,32 +131,32 @@ type generator struct {
first bool
}

func generate(cuePkgPath string) error {
goPkgPath := path.Join("cuelang.org/go/pkg", cuePkgPath)
pkg, err := gobuild.Import(goPkgPath, "", 0)
if err != nil {
return err
}

func generate(pkg *packages.Package) error {
// go/packages supports multiple build systems, including some which don't keep
// a Go package entirely within a single directory.
// However, we know for certain that CUE uses modules, so it is the case here.
// We can figure out the directory from the first Go file.
pkgDir := filepath.Dir(pkg.GoFiles[0])
cuePkg := strings.TrimPrefix(pkg.PkgPath, pkgParent+"/")
g := generator{
dir: pkg.Dir,
cuePkgPath: cuePkgPath,
dir: pkgDir,
cuePkgPath: cuePkg,
w: &bytes.Buffer{},
fset: token.NewFileSet(),
}

params := headerParams{
GoPkg: pkg.Name,
CUEPkg: cuePkgPath,
CUEPkg: cuePkg,
}
// As a special case, the "tool" package cannot be imported from CUE.
skipRegister := params.CUEPkg == "tool"
if skipRegister {
params.CUEPkg = ""
}

if doc, err := os.ReadFile(filepath.Join(pkg.Dir, "doc.txt")); err == nil {
defs, err := os.ReadFile(filepath.Join(pkg.Dir, pkg.Name+".cue"))
if doc, err := os.ReadFile(filepath.Join(pkgDir, "doc.txt")); err == nil {
defs, err := os.ReadFile(filepath.Join(pkgDir, pkg.Name+".cue"))
if err != nil {
return err
}
Expand All @@ -164,7 +179,9 @@ func generate(cuePkgPath string) error {
if filename == genFile {
continue
}
g.processGo(filepath.Join(pkg.Dir, filename))
if err := g.processGo(filename); err != nil {
return err
}
}
fmt.Fprintf(g.w, "},\n")
if err := g.processCUE(); err != nil {
Expand All @@ -178,7 +195,7 @@ func generate(cuePkgPath string) error {
b = g.w.Bytes() // write the unformatted source
}

filename := filepath.Join(pkg.Dir, genFile)
filename := filepath.Join(pkgDir, genFile)

if err := os.WriteFile(filename, b, 0666); err != nil {
return err
Expand Down

0 comments on commit e9a412d

Please sign in to comment.