this repo has no description
0
fork

Configure Feed

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

encoding/gocode: don't require output to be stable

gocode generates a Go variable cuegenInstanceData whose value is a
string containing CUE values encoded via Runtime.Marshal.
Said Marshal method encodes data via encoding/gob
and then compresses the encoded gob with compress/gzip.

This is perfectly fine, but the result isn't guaranteed to be stable
byte-by-byte between Go versions, since the gob format evolves
and gzip may get better at compressing data over time.

In particular, in Go 1.21, https://go.dev/cl/460543 changed the encoding
slightly by having the first user type be registered in encoding/gob
with type id 64 rather than 65. Given that encoding/gob had had
a constant `const firstUserId = 64` for a long time,
we assume that user types starting with type ID 65 was a minor mistake.

That upstream change shouldn't break any reasonable gob user.
However, we were expecting encoding/gob's output to be perfectly stable,
which is certainly not reasonable to do.

The tests in gen_test.go already import generated Go code in testdata,
so we do cover whether the generated code does what we expect it to.
We thus don't really need to check the output is stable,
we just need a way to update the output files in testdata as needed.
For that purpose, `go generate` is perfectly fine.

Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
Change-Id: I24b85c8c648a573ccca3c670f320f7e91278046e
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1167483
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Paul Jolly <paul@myitcv.io>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>

+81 -93
+2
encoding/gocode/doc.go
··· 12 12 // See the License for the specific language governing permissions and 13 13 // limitations under the License. 14 14 15 + //go:generate go run testdata/gen.go 16 + 15 17 // Package gocode defines functions for extracting CUE definitions from Go code 16 18 // and generating Go code from CUE values. 17 19 //
+13
encoding/gocode/gen_test.go
··· 17 17 package gocode 18 18 19 19 import ( 20 + "bytes" 21 + "regexp" 20 22 "strings" 21 23 "testing" 22 24 25 + "cuelang.org/go/cue/errors" 23 26 "cuelang.org/go/encoding/gocode/testdata/pkg1" 24 27 "cuelang.org/go/encoding/gocode/testdata/pkg2" 25 28 ) ··· 107 110 }) 108 111 } 109 112 } 113 + 114 + func errStr(err error) string { 115 + if err == nil { 116 + return "nil" 117 + } 118 + buf := &bytes.Buffer{} 119 + errors.Print(buf, err, nil) 120 + r := regexp.MustCompile(`.cue:\d+:\d+`) 121 + return r.ReplaceAllString(buf.String(), ".cue:x:x") 122 + }
-93
encoding/gocode/generator_test.go
··· 1 - // Copyright 2019 CUE Authors 2 - // 3 - // Licensed under the Apache License, Version 2.0 (the "License"); 4 - // you may not use this file except in compliance with the License. 5 - // You may obtain a copy of the License at 6 - // 7 - // http://www.apache.org/licenses/LICENSE-2.0 8 - // 9 - // Unless required by applicable law or agreed to in writing, software 10 - // distributed under the License is distributed on an "AS IS" BASIS, 11 - // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 - // See the License for the specific language governing permissions and 13 - // limitations under the License. 14 - 15 - package gocode 16 - 17 - import ( 18 - "bytes" 19 - "io/ioutil" 20 - "os" 21 - "path/filepath" 22 - "regexp" 23 - "testing" 24 - 25 - "github.com/google/go-cmp/cmp" 26 - 27 - "cuelang.org/go/cue" 28 - "cuelang.org/go/cue/errors" 29 - "cuelang.org/go/cue/load" 30 - "cuelang.org/go/internal/cuetest" 31 - _ "cuelang.org/go/pkg" 32 - ) 33 - 34 - func TestGenerate(t *testing.T) { 35 - dirs, err := ioutil.ReadDir("testdata") 36 - if err != nil { 37 - t.Fatal(err) 38 - } 39 - 40 - cwd, err := os.Getwd() 41 - if err != nil { 42 - t.Fatal(err) 43 - } 44 - 45 - for _, d := range dirs { 46 - if !d.IsDir() { 47 - continue 48 - } 49 - t.Run(d.Name(), func(t *testing.T) { 50 - dir := filepath.Join(cwd, "testdata") 51 - pkg := "." + string(filepath.Separator) + d.Name() 52 - inst := cue.Build(load.Instances([]string{pkg}, &load.Config{ 53 - Dir: dir, 54 - ModuleRoot: dir, 55 - Module: "cuelang.org/go/encoding/gocode/testdata", 56 - }))[0] 57 - if err := inst.Err; err != nil { 58 - t.Fatal(err) 59 - } 60 - 61 - goPkg := "./testdata/" + d.Name() 62 - b, err := Generate(goPkg, inst, nil) 63 - if err != nil { 64 - t.Fatal(errStr(err)) 65 - } 66 - 67 - goFile := filepath.Join("testdata", d.Name(), "cue_gen.go") 68 - if cuetest.UpdateGoldenFiles { 69 - _ = os.WriteFile(goFile, b, 0644) 70 - return 71 - } 72 - 73 - want, err := os.ReadFile(goFile) 74 - if err != nil { 75 - t.Fatal(err) 76 - } 77 - 78 - if d := cmp.Diff(string(want), string(b)); d != "" { 79 - t.Errorf("files differ (-want +got):\n%v", d) 80 - } 81 - }) 82 - } 83 - } 84 - 85 - func errStr(err error) string { 86 - if err == nil { 87 - return "nil" 88 - } 89 - buf := &bytes.Buffer{} 90 - errors.Print(buf, err, nil) 91 - r := regexp.MustCompile(`.cue:\d+:\d+`) 92 - return r.ReplaceAllString(buf.String(), ".cue:x:x") 93 - }
+66
encoding/gocode/testdata/gen.go
··· 1 + // Copyright 2019 CUE Authors 2 + // 3 + // Licensed under the Apache License, Version 2.0 (the "License"); 4 + // you may not use this file except in compliance with the License. 5 + // You may obtain a copy of the License at 6 + // 7 + // http://www.apache.org/licenses/LICENSE-2.0 8 + // 9 + // Unless required by applicable law or agreed to in writing, software 10 + // distributed under the License is distributed on an "AS IS" BASIS, 11 + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 + // See the License for the specific language governing permissions and 13 + // limitations under the License. 14 + 15 + package main 16 + 17 + import ( 18 + "io/ioutil" 19 + "log" 20 + "os" 21 + "path/filepath" 22 + 23 + "cuelang.org/go/cue" 24 + "cuelang.org/go/cue/load" 25 + "cuelang.org/go/encoding/gocode" 26 + _ "cuelang.org/go/pkg" 27 + ) 28 + 29 + func main() { 30 + dirs, err := ioutil.ReadDir("testdata") 31 + if err != nil { 32 + log.Fatal(err) 33 + } 34 + 35 + cwd, err := os.Getwd() 36 + if err != nil { 37 + log.Fatal(err) 38 + } 39 + 40 + for _, d := range dirs { 41 + if !d.IsDir() { 42 + continue 43 + } 44 + dir := filepath.Join(cwd, "testdata") 45 + pkg := "." + string(filepath.Separator) + d.Name() 46 + inst := cue.Build(load.Instances([]string{pkg}, &load.Config{ 47 + Dir: dir, 48 + ModuleRoot: dir, 49 + Module: "cuelang.org/go/encoding/gocode/testdata", 50 + }))[0] 51 + if err := inst.Err; err != nil { 52 + log.Fatal(err) 53 + } 54 + 55 + goPkg := "./testdata/" + d.Name() 56 + b, err := gocode.Generate(goPkg, inst, nil) 57 + if err != nil { 58 + log.Fatal(err) 59 + } 60 + 61 + goFile := filepath.Join("testdata", d.Name(), "cue_gen.go") 62 + if err := os.WriteFile(goFile, b, 0644); err != nil { 63 + log.Fatal(err) 64 + } 65 + } 66 + }