66 "compress/gzip"
77 "crypto/sha256"
88 "encoding/gob"
9- "encoding/json"
109 "fmt"
1110 "go/build"
1211 "io"
@@ -21,10 +20,9 @@ import (
2120// Cacheable defines methods to serialize and deserialize cachable objects.
2221// This object should represent a package's build artifact.
2322//
24- // The encode and decode functions are typically wrappers around gob or json
25- // Encoder.Encode and Decoder.Decode, but other formats are possible as well,
26- // the same way as FileSet.Write and FileSet.Read work with any encode/decode
27- // functions.
23+ // The encode and decode functions are typically wrappers around gob.Encoder.Encode
24+ // and gob.Decoder.Decode, but other formats are possible as well, the same way
25+ // as FileSet.Write and FileSet.Read work with any encode/decode functions.
2826type Cacheable interface {
2927 Write (encode func (any ) error ) error
3028 Read (decode func (any ) error ) error
@@ -115,18 +113,33 @@ type BuildCache struct {
115113
116114 // Version should be set to compiler.Version
117115 Version string
118- }
119116
120- const encoding = `json`
117+ // TestedPackage is the import path of the package being tested, or
118+ // empty when not building for tests. The package under test is built
119+ // with *_test.go sources included so we should always skip reading
120+ // and writing cache in that case. Since we are caching prior to
121+ // type-checking for generics, any package importing the package under
122+ // test should be unaffected.
123+ TestedPackage string
124+ }
121125
122126func (bc BuildCache ) String () string {
123127 return fmt .Sprintf ("%#v" , bc )
124128}
125129
130+ func (bc * BuildCache ) isTestPackage (importPath string ) bool {
131+ return bc != nil && len (importPath ) > 0 &&
132+ (importPath == bc .TestedPackage || importPath == bc .TestedPackage + "_test" )
133+ }
134+
126135func (bc * BuildCache ) Store (c Cacheable , importPath string , buildTime time.Time ) bool {
127136 if bc == nil {
128137 return false // Caching is disabled.
129138 }
139+ if bc .isTestPackage (importPath ) {
140+ log .Infof ("Skipped storing cache of test package for %q." , importPath )
141+ return false // Don't use cache when building the package under test.
142+ }
130143
131144 start := time .Now ()
132145 path := cachedPath (bc .packageKey (importPath ))
@@ -158,32 +171,14 @@ func (bc *BuildCache) Store(c Cacheable, importPath string, buildTime time.Time)
158171 return true
159172}
160173
161- func (bc * BuildCache ) getEncode (w io.Writer ) func (any ) error {
162- switch encoding {
163- case `gob` :
164- return gob .NewEncoder (w ).Encode
165- case `json` :
166- return json .NewEncoder (w ).Encode
167- default :
168- panic (fmt .Errorf (`unexpected encoding for encoder: %q` , encoding ))
169- }
170- }
171-
172- func (bc * BuildCache ) getDecode (r io.Reader ) func (any ) error {
173- switch encoding {
174- case `gob` :
175- return gob .NewDecoder (r ).Decode
176- case `json` :
177- return json .NewDecoder (r ).Decode
178- default :
179- panic (fmt .Errorf (`unexpected encoding for decoder: %q` , encoding ))
180- }
181- }
182-
183174func (bc * BuildCache ) Load (c Cacheable , importPath string , srcModTime time.Time ) bool {
184175 if bc == nil {
185176 return false // Caching is disabled.
186177 }
178+ if bc .isTestPackage (importPath ) {
179+ log .Infof ("Skipped loading cache of test package for %q." , importPath )
180+ return false // Don't use cache when building the package under test.
181+ }
187182
188183 start := time .Now ()
189184 path := cachedPath (bc .packageKey (importPath ))
@@ -220,11 +215,11 @@ func (bc *BuildCache) serialize(c Cacheable, buildTime time.Time, w io.Writer) (
220215 }
221216 }()
222217
223- encode := bc . getEncode ( w )
224- if err := encode (buildTime ); err != nil {
218+ ge := gob . NewEncoder ( zw )
219+ if err := ge . Encode (buildTime ); err != nil {
225220 return err
226221 }
227- return c .Write (encode )
222+ return c .Write (ge . Encode )
228223}
229224
230225func (bc * BuildCache ) deserialize (c Cacheable , srcModTime time.Time , r io.Reader ) (buildTime time.Time , old bool , err error ) {
@@ -239,14 +234,14 @@ func (bc *BuildCache) deserialize(c Cacheable, srcModTime time.Time, r io.Reader
239234 }
240235 }()
241236
242- decode := bc . getDecode ( r )
243- if err := decode (& buildTime ); err != nil {
237+ gd := gob . NewDecoder ( zr )
238+ if err := gd . Decode (& buildTime ); err != nil {
244239 return buildTime , false , err
245240 }
246241 if srcModTime .After (buildTime ) {
247242 return buildTime , true , nil // Package is out-of-date, cache miss.
248243 }
249- return buildTime , false , c .Read (decode )
244+ return buildTime , false , c .Read (gd . Decode )
250245}
251246
252247// commonKey returns a part of the cache key common for all artifacts generated
0 commit comments