this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

pkg: drop cue/build and pkg/internal from gen.go

The code just needs to parse CUE files to extract the declarations.
There is no need to build instances and values to extract the syntax;
we can parse the syntax directly.

This gives us better results in any case,
as the resulting syntax directly follows the source.
For example, the original source uses octal integer literals
and uses some inline structs for readability, and we keep those now.

As a bonus, as we no longer use the CUE evaluator, `go generate`
drops from ~0.35s to ~0.25s on my laptop.

Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
Change-Id: Id6c03c49421c4b2ead467b523bcd4f25b41c002b
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1201388
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>

+53 -88
+33 -42
pkg/gen.go
··· 50 50 51 51 "golang.org/x/tools/go/packages" 52 52 53 - "cuelang.org/go/cue" 54 - "cuelang.org/go/cue/build" 55 - "cuelang.org/go/cue/errors" 53 + "cuelang.org/go/cue/ast" 56 54 cueformat "cuelang.org/go/cue/format" 55 + "cuelang.org/go/cue/parser" 57 56 "cuelang.org/go/internal" 58 - pkginternal "cuelang.org/go/pkg/internal" 59 57 ) 60 58 61 59 const genFile = "pkg.go" ··· 217 215 // Note: we avoid using the cue/load and the cuecontext packages 218 216 // because they depend on the standard library which is what this 219 217 // command is generating - cyclic dependencies are undesirable in general. 220 - ctx := pkginternal.NewContext() 221 - val, err := loadCUEPackage(ctx, g.dir, g.cuePkgPath) 218 + // We only need to load the declarations from one CUE file if it exists. 219 + expr, err := loadCUEDecls(g.dir) 222 220 if err != nil { 223 - if errors.Is(err, errNoCUEFiles) { 224 - return nil 225 - } 226 - errors.Print(os.Stderr, err, nil) 227 221 return fmt.Errorf("error processing %s: %v", g.cuePkgPath, err) 228 222 } 223 + if expr == nil { // No syntax to add. 224 + return nil 225 + } 226 + b, err := cueformat.Node(expr) 227 + if err != nil { 228 + return err 229 + } 229 230 230 - v := val.Syntax(cue.Raw()) 231 - // fmt.Printf("%T\n", v) 232 - // fmt.Println(astinternal.DebugStr(v)) 233 - n := internal.ToExpr(v) 234 - b, err := cueformat.Node(n) 231 + // Compact the CUE by removing empty lines. This requires re-formatting to align fields. 232 + // TODO(mvdan): provide a "compact" option in cue/format for this purpose? 233 + b = bytes.ReplaceAll(b, []byte("\n\n"), []byte("\n")) 234 + b, err = cueformat.Source(b) 235 235 if err != nil { 236 236 return err 237 237 } 238 - b = bytes.ReplaceAll(b, []byte("\n\n"), []byte("\n")) 238 + b = bytes.TrimSpace(b) // no trailing newline 239 + 239 240 // Try to use a Go string with backquotes, for readability. 240 241 // If not possible due to cueSrc itself having backquotes, 241 242 // use a single-line double-quoted string, removing tabs for brevity. ··· 460 461 return "" 461 462 } 462 463 463 - var errNoCUEFiles = errors.New("no CUE files in directory") 464 - 465 - // loadCUEPackage loads a CUE package as a value. We avoid using cue/load because 466 - // that depends on the standard library and as this generator is generating the standard 467 - // library, we don't want that cyclic dependency. 468 - // It only has to deal with the fairly limited subset of CUE packages that are 469 - // present inside pkg/.... 470 - func loadCUEPackage(ctx *cue.Context, dir string, pkgPath string) (cue.Value, error) { 471 - inst := &build.Instance{ 472 - PkgName: path.Base(pkgPath), 473 - Dir: dir, 474 - DisplayPath: pkgPath, 475 - ImportPath: pkgPath, 476 - } 464 + // loadCUEDecls parses a single CUE file from a directory and returns its contents 465 + // as an expression, typically a struct holding all of a file's declarations. 466 + // If there are no CUE files, it returns (nil, nil). 467 + func loadCUEDecls(dir string) (ast.Expr, error) { 477 468 cuefiles, err := filepath.Glob(filepath.Join(dir, "*.cue")) 478 - if err != nil { 479 - return cue.Value{}, err 469 + if err != nil || len(cuefiles) == 0 { 470 + return nil, err 480 471 } 481 472 if len(cuefiles) == 0 { 482 - return cue.Value{}, errNoCUEFiles 473 + return nil, nil 483 474 } 484 - for _, file := range cuefiles { 485 - if err := inst.AddFile(file, nil); err != nil { 486 - return cue.Value{}, err 487 - } 475 + if len(cuefiles) > 1 { 476 + // Supporting multiple CUE files would require merging declarations. 477 + return nil, fmt.Errorf("multiple CUE files not supported in this generator") 488 478 } 489 - if err := inst.Complete(); err != nil { 490 - return cue.Value{}, err 479 + src, err := os.ReadFile(cuefiles[0]) 480 + if err != nil { 481 + return nil, err 491 482 } 492 - vals, err := ctx.BuildInstances([]*build.Instance{inst}) 483 + file, err := parser.ParseFile(cuefiles[0], src) 493 484 if err != nil { 494 - return cue.Value{}, err 485 + return nil, err 495 486 } 496 - return vals[0], nil 487 + return internal.ToExpr(file), nil 497 488 }
+1 -3
pkg/tool/exec/pkg.go
··· 67 67 $id: *"tool/exec.Run" | "exec" 68 68 cmd: string | [string, ...string] 69 69 dir?: string 70 - env: { 71 - [string]: string 72 - } | [...=~"="] 70 + env: {[string]: string} | [...=~"="] 73 71 stdout: *null | string | bytes 74 72 stderr: *null | string | bytes 75 73 stdin: *null | string | bytes
+3 -3
pkg/tool/file/pkg.go
··· 148 148 Append: { 149 149 $id: "tool/file.Append" 150 150 filename: !="" 151 - permissions: int | *438 151 + permissions: int | *0o666 152 152 contents: bytes | string 153 153 } 154 154 Create: { 155 155 $id: "tool/file.Create" 156 156 filename: !="" 157 - permissions: int | *438 157 + permissions: int | *0o666 158 158 contents: bytes | string 159 159 } 160 160 Glob: { ··· 166 166 $id: "tool/file.Mkdir" 167 167 path: string 168 168 createParents: bool | *false 169 - permissions: int | *511 169 + permissions: int | *0o777 170 170 } 171 171 MkdirAll: Mkdir & { 172 172 createParents: true
+8 -24
pkg/tool/http/pkg.go
··· 65 65 var p = &pkg.Package{ 66 66 Native: []*pkg.Builtin{}, 67 67 CUE: `{ 68 - Get: Do & { 69 - method: "GET" 70 - } 71 - Post: Do & { 72 - method: "POST" 73 - } 74 - Put: Do & { 75 - method: "PUT" 76 - } 77 - Delete: Do & { 78 - method: "DELETE" 79 - } 68 + Get: Do & {method: "GET"} 69 + Post: Do & {method: "POST"} 70 + Put: Do & {method: "PUT"} 71 + Delete: Do & {method: "DELETE"} 80 72 Do: { 81 73 $id: *"tool/http.Do" | "http" 82 74 method: string ··· 87 79 } 88 80 request: { 89 81 body?: bytes | string 90 - header: { 91 - [string]: string | [...string] 92 - } 93 - trailer: { 94 - [string]: string | [...string] 95 - } 82 + header: [string]: string | [...string] 83 + trailer: [string]: string | [...string] 96 84 } 97 85 response: { 98 86 status: string 99 87 statusCode: int 100 88 body: *bytes | string 101 - header: { 102 - [string]: string | [...string] 103 - } 104 - trailer: { 105 - [string]: string | [...string] 106 - } 89 + header: [string]: string | [...string] 90 + trailer: [string]: string | [...string] 107 91 } 108 92 } 109 93 }`,
+3 -9
pkg/tool/os/pkg.go
··· 63 63 Value: bool | number | *string | null 64 64 Name: !="" & !~"^[$]" 65 65 Setenv: { 66 - { 67 - [Name]: Value 68 - } 69 66 $id: "tool/os.Setenv" 67 + {[Name]: Value} 70 68 } 71 69 Getenv: { 72 - { 73 - [Name]: Value 74 - } 75 70 $id: "tool/os.Getenv" 71 + {[Name]: Value} 76 72 } 77 73 Environ: { 78 - { 79 - [Name]: Value 80 - } 81 74 $id: "tool/os.Environ" 75 + {[Name]: Value} 82 76 } 83 77 Clearenv: { 84 78 $id: "tool/os.Clearenv"
+5 -7
pkg/uuid/pkg.go
··· 145 145 X500: "6ba7b814-9dad-11d1-80b4-00c04fd430c8" 146 146 Nil: "00000000-0000-0000-0000-000000000000" 147 147 } 148 - variants: { 149 - Invalid: 0 150 - RFC4122: 1 151 - Reserved: 2 152 - Microsoft: 3 153 - Future: 4 154 - } 148 + variants: Invalid: 0 149 + variants: RFC4122: 1 150 + variants: Reserved: 2 151 + variants: Microsoft: 3 152 + variants: Future: 4 155 153 }`, 156 154 }