Skip to content

Commit 5eccf9d

Browse files
committed
chore: sync with go1.21.13
1 parent d038061 commit 5eccf9d

19 files changed

+1018
-128
lines changed

.golangci.yml

+2
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ issues:
224224
- internal/cache # extracted from Go code
225225
- internal/robustio # extracted from Go code
226226
- internal/mmap # extracted from Go code
227+
- internal/quoted # extracted from Go code
228+
- internal/testenv # extracted from Go code
227229

228230
run:
229231
timeout: 5m

internal/cache/cache.go

+110-60
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"time"
2424

2525
"github.com/golangci/golangci-lint/internal/mmap"
26+
"github.com/golangci/golangci-lint/internal/robustio"
2627
"github.com/rogpeppe/go-internal/lockedfile"
2728
)
2829

@@ -34,8 +35,50 @@ type ActionID [HashSize]byte
3435
// An OutputID is a cache output key, the hash of an output of a computation.
3536
type OutputID [HashSize]byte
3637

38+
// Cache is the interface as used by the cmd/go.
39+
type Cache interface {
40+
// Get returns the cache entry for the provided ActionID.
41+
// On miss, the error type should be of type *entryNotFoundError.
42+
//
43+
// After a success call to Get, OutputFile(Entry.OutputID) must
44+
// exist on disk for until Close is called (at the end of the process).
45+
Get(ActionID) (Entry, error)
46+
47+
// Put adds an item to the cache.
48+
//
49+
// The seeker is only used to seek to the beginning. After a call to Put,
50+
// the seek position is not guaranteed to be in any particular state.
51+
//
52+
// As a special case, if the ReadSeeker is of type noVerifyReadSeeker,
53+
// the verification from GODEBUG=goverifycache=1 is skipped.
54+
//
55+
// After a success call to Get, OutputFile(Entry.OutputID) must
56+
// exist on disk for until Close is called (at the end of the process).
57+
Put(ActionID, io.ReadSeeker) (_ OutputID, size int64, _ error)
58+
59+
// Close is called at the end of the go process. Implementations can do
60+
// cache cleanup work at this phase, or wait for and report any errors from
61+
// background cleanup work started earlier. Any cache trimming should in one
62+
// process should not violate cause the invariants of this interface to be
63+
// violated in another process. Namely, a cache trim from one process should
64+
// not delete an ObjectID from disk that was recently Get or Put from
65+
// another process. As a rule of thumb, don't trim things used in the last
66+
// day.
67+
Close() error
68+
69+
// OutputFile returns the path on disk where OutputID is stored.
70+
//
71+
// It's only called after a successful get or put call so it doesn't need
72+
// to return an error; it's assumed that if the previous get or put succeeded,
73+
// it's already on disk.
74+
OutputFile(OutputID) string
75+
76+
// FuzzDir returns where fuzz files are stored.
77+
FuzzDir() string
78+
}
79+
3780
// A Cache is a package cache, backed by a file system directory tree.
38-
type Cache struct {
81+
type DiskCache struct {
3982
dir string
4083
now func() time.Time
4184
}
@@ -51,7 +94,7 @@ type Cache struct {
5194
// to share a cache directory (for example, if the directory were stored
5295
// in a network file system). File locking is notoriously unreliable in
5396
// network file systems and may not suffice to protect the cache.
54-
func Open(dir string) (*Cache, error) {
97+
func Open(dir string) (*DiskCache, error) {
5598
info, err := os.Stat(dir)
5699
if err != nil {
57100
return nil, err
@@ -65,15 +108,15 @@ func Open(dir string) (*Cache, error) {
65108
return nil, err
66109
}
67110
}
68-
c := &Cache{
111+
c := &DiskCache{
69112
dir: dir,
70113
now: time.Now,
71114
}
72115
return c, nil
73116
}
74117

75118
// fileName returns the name of the file corresponding to the given id.
76-
func (c *Cache) fileName(id [HashSize]byte, key string) string {
119+
func (c *DiskCache) fileName(id [HashSize]byte, key string) string {
77120
return filepath.Join(c.dir, fmt.Sprintf("%02x", id[0]), fmt.Sprintf("%x", id)+"-"+key)
78121
}
79122

@@ -116,30 +159,34 @@ var errVerifyMode = errors.New("gocacheverify=1")
116159
// DebugTest is set when GODEBUG=gocachetest=1 is in the environment.
117160
var DebugTest = false
118161

119-
func init() { initEnv() }
120-
121-
func initEnv() {
122-
verify = false
123-
debugHash = false
124-
debug := strings.Split(os.Getenv("GODEBUG"), ",")
125-
for _, f := range debug {
126-
if f == "gocacheverify=1" {
127-
verify = true
128-
}
129-
if f == "gocachehash=1" {
130-
debugHash = true
131-
}
132-
if f == "gocachetest=1" {
133-
DebugTest = true
134-
}
135-
}
136-
}
162+
// func init() { initEnv() }
163+
164+
// var (
165+
// goCacheVerify = godebug.New("gocacheverify")
166+
// goDebugHash = godebug.New("gocachehash")
167+
// goCacheTest = godebug.New("gocachetest")
168+
// )
169+
170+
// func initEnv() {
171+
// if goCacheVerify.Value() == "1" {
172+
// goCacheVerify.IncNonDefault()
173+
// verify = true
174+
// }
175+
// if goDebugHash.Value() == "1" {
176+
// goDebugHash.IncNonDefault()
177+
// debugHash = true
178+
// }
179+
// if goCacheTest.Value() == "1" {
180+
// goCacheTest.IncNonDefault()
181+
// DebugTest = true
182+
// }
183+
// }
137184

138185
// Get looks up the action ID in the cache,
139186
// returning the corresponding output ID and file size, if any.
140187
// Note that finding an output ID does not guarantee that the
141188
// saved file for that output ID is still available.
142-
func (c *Cache) Get(id ActionID) (Entry, error) {
189+
func (c *DiskCache) Get(id ActionID) (Entry, error) {
143190
if verify {
144191
return Entry{}, &entryNotFoundError{Err: errVerifyMode}
145192
}
@@ -149,11 +196,11 @@ func (c *Cache) Get(id ActionID) (Entry, error) {
149196
type Entry struct {
150197
OutputID OutputID
151198
Size int64
152-
Time time.Time
199+
Time time.Time // when added to cache
153200
}
154201

155202
// get is Get but does not respect verify mode, so that Put can use it.
156-
func (c *Cache) get(id ActionID) (Entry, error) {
203+
func (c *DiskCache) get(id ActionID) (Entry, error) {
157204
missing := func(reason error) (Entry, error) {
158205
return Entry{}, &entryNotFoundError{Err: reason}
159206
}
@@ -220,17 +267,12 @@ func (c *Cache) get(id ActionID) (Entry, error) {
220267

221268
// GetFile looks up the action ID in the cache and returns
222269
// the name of the corresponding data file.
223-
func (c *Cache) GetFile(id ActionID) (file string, entry Entry, err error) {
270+
func GetFile(c Cache, id ActionID) (file string, entry Entry, err error) {
224271
entry, err = c.Get(id)
225272
if err != nil {
226273
return "", Entry{}, err
227274
}
228-
229-
file, err = c.OutputFile(entry.OutputID)
230-
if err != nil {
231-
return "", Entry{}, err
232-
}
233-
275+
file = c.OutputFile(entry.OutputID)
234276
info, err := os.Stat(file)
235277
if err != nil {
236278
return "", Entry{}, &entryNotFoundError{Err: err}
@@ -244,12 +286,12 @@ func (c *Cache) GetFile(id ActionID) (file string, entry Entry, err error) {
244286
// GetBytes looks up the action ID in the cache and returns
245287
// the corresponding output bytes.
246288
// GetBytes should only be used for data that can be expected to fit in memory.
247-
func (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) {
289+
func GetBytes(c Cache, id ActionID) ([]byte, Entry, error) {
248290
entry, err := c.Get(id)
249291
if err != nil {
250292
return nil, entry, err
251293
}
252-
data, err := c.readFileCGIL(c.OutputFile(entry.OutputID))
294+
data, err := robustio.ReadFile(c.OutputFile(entry.OutputID))
253295
if err != nil {
254296
return nil, entry, err
255297
}
@@ -262,16 +304,12 @@ func (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) {
262304
// GetMmap looks up the action ID in the cache and returns
263305
// the corresponding output bytes.
264306
// GetMmap should only be used for data that can be expected to fit in memory.
265-
func (c *Cache) GetMmap(id ActionID) ([]byte, Entry, error) {
307+
func GetMmap(c Cache, id ActionID) ([]byte, Entry, error) {
266308
entry, err := c.Get(id)
267309
if err != nil {
268310
return nil, entry, err
269311
}
270-
outputFile, err := c.OutputFile(entry.OutputID)
271-
if err != nil {
272-
return nil, entry, err
273-
}
274-
md, err := mmap.Mmap(outputFile)
312+
md, err := mmap.Mmap(c.OutputFile(entry.OutputID))
275313
if err != nil {
276314
return nil, Entry{}, err
277315
}
@@ -282,13 +320,10 @@ func (c *Cache) GetMmap(id ActionID) ([]byte, Entry, error) {
282320
}
283321

284322
// OutputFile returns the name of the cache file storing output with the given OutputID.
285-
func (c *Cache) OutputFile(out OutputID) (string, error) {
323+
func (c *DiskCache) OutputFile(out OutputID) string {
286324
file := c.fileName(out, "d")
287-
err := c.used(file)
288-
if err != nil {
289-
return "", err
290-
}
291-
return file, nil
325+
c.used(file)
326+
return file
292327
}
293328

294329
// Time constants for cache expiration.
@@ -318,7 +353,7 @@ const (
318353
// mtime is more than an hour old. This heuristic eliminates
319354
// nearly all of the mtime updates that would otherwise happen,
320355
// while still keeping the mtimes useful for cache trimming.
321-
func (c *Cache) used(file string) error {
356+
func (c *DiskCache) used(file string) error {
322357
info, err := os.Stat(file)
323358
if err == nil && c.now().Sub(info.ModTime()) < mtimeInterval {
324359
return nil
@@ -339,8 +374,10 @@ func (c *Cache) used(file string) error {
339374
return nil
340375
}
341376

377+
func (c *DiskCache) Close() error { return c.Trim() }
378+
342379
// Trim removes old cache entries that are likely not to be reused.
343-
func (c *Cache) Trim() {
380+
func (c *DiskCache) Trim() error {
344381
now := c.now()
345382

346383
// We maintain in dir/trim.txt the time of the last completed cache trim.
@@ -354,7 +391,7 @@ func (c *Cache) Trim() {
354391
if t, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64); err == nil {
355392
lastTrim := time.Unix(t, 0)
356393
if d := now.Sub(lastTrim); d < trimInterval && d > -mtimeInterval {
357-
return
394+
return nil
358395
}
359396
}
360397
}
@@ -373,12 +410,14 @@ func (c *Cache) Trim() {
373410
var b bytes.Buffer
374411
fmt.Fprintf(&b, "%d", now.Unix())
375412
if err := lockedfile.Write(filepath.Join(c.dir, "trim.txt"), &b, 0666); err != nil {
376-
return
413+
return err
377414
}
415+
416+
return nil
378417
}
379418

380419
// trimSubdir trims a single cache subdirectory.
381-
func (c *Cache) trimSubdir(subdir string, cutoff time.Time) {
420+
func (c *DiskCache) trimSubdir(subdir string, cutoff time.Time) {
382421
// Read all directory entries from subdir before removing
383422
// any files, in case removing files invalidates the file offset
384423
// in the directory scan. Also, ignore error from f.Readdirnames,
@@ -406,7 +445,7 @@ func (c *Cache) trimSubdir(subdir string, cutoff time.Time) {
406445

407446
// putIndexEntry adds an entry to the cache recording that executing the action
408447
// with the given id produces an output with the given output id (hash) and size.
409-
func (c *Cache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify bool) error {
448+
func (c *DiskCache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify bool) error {
410449
// Note: We expect that for one reason or another it may happen
411450
// that repeating an action produces a different output hash
412451
// (for example, if the output contains a time stamp or temp dir name).
@@ -463,21 +502,32 @@ func (c *Cache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify
463502
return nil
464503
}
465504

505+
// noVerifyReadSeeker is a io.ReadSeeker wrapper sentinel type
506+
// that says that Cache.Put should skip the verify check
507+
// (from GODEBUG=goverifycache=1).
508+
type noVerifyReadSeeker struct {
509+
io.ReadSeeker
510+
}
511+
466512
// Put stores the given output in the cache as the output for the action ID.
467513
// It may read file twice. The content of file must not change between the two passes.
468-
func (c *Cache) Put(id ActionID, file io.ReadSeeker) (OutputID, int64, error) {
469-
return c.put(id, file, true)
514+
func (c *DiskCache) Put(id ActionID, file io.ReadSeeker) (OutputID, int64, error) {
515+
wrapper, isNoVerify := file.(noVerifyReadSeeker)
516+
if isNoVerify {
517+
file = wrapper.ReadSeeker
518+
}
519+
return c.put(id, file, !isNoVerify)
470520
}
471521

472522
// PutNoVerify is like Put but disables the verify check
473523
// when GODEBUG=goverifycache=1 is set.
474524
// It is meant for data that is OK to cache but that we expect to vary slightly from run to run,
475525
// like test output containing times and the like.
476-
func (c *Cache) PutNoVerify(id ActionID, file io.ReadSeeker) (OutputID, int64, error) {
477-
return c.put(id, file, false)
526+
func PutNoVerify(c Cache, id ActionID, file io.ReadSeeker) (OutputID, int64, error) {
527+
return c.Put(id, noVerifyReadSeeker{file})
478528
}
479529

480-
func (c *Cache) put(id ActionID, file io.ReadSeeker, allowVerify bool) (OutputID, int64, error) {
530+
func (c *DiskCache) put(id ActionID, file io.ReadSeeker, allowVerify bool) (OutputID, int64, error) {
481531
// Compute output ID.
482532
h := sha256.New()
483533
if _, err := file.Seek(0, 0); err != nil {
@@ -500,14 +550,14 @@ func (c *Cache) put(id ActionID, file io.ReadSeeker, allowVerify bool) (OutputID
500550
}
501551

502552
// PutBytes stores the given bytes in the cache as the output for the action ID.
503-
func (c *Cache) PutBytes(id ActionID, data []byte) error {
553+
func PutBytes(c Cache, id ActionID, data []byte) error {
504554
_, _, err := c.Put(id, bytes.NewReader(data))
505555
return err
506556
}
507557

508558
// copyFile copies file into the cache, expecting it to have the given
509559
// output ID and size, if that file is not present already.
510-
func (c *Cache) copyFile(file io.ReadSeeker, out OutputID, size int64) error {
560+
func (c *DiskCache) copyFile(file io.ReadSeeker, out OutputID, size int64) error {
511561
name := c.fileName(out, "d")
512562
info, err := os.Stat(name)
513563
if err == nil && info.Size() == size {
@@ -608,6 +658,6 @@ func (c *Cache) copyFile(file io.ReadSeeker, out OutputID, size int64) error {
608658
// They may be removed with 'go clean -fuzzcache'.
609659
//
610660
// TODO(#48526): make Trim remove unused files from this directory.
611-
func (c *Cache) FuzzDir() string {
661+
func (c *DiskCache) FuzzDir() string {
612662
return filepath.Join(c.dir, "fuzz")
613663
}

internal/cache/cache_gcil.go

-10
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package cache
22

33
import (
44
"errors"
5-
6-
"github.com/golangci/golangci-lint/internal/robustio"
75
)
86

97
// IsErrMissing allows to access to the internal error.
@@ -12,11 +10,3 @@ func IsErrMissing(err error) bool {
1210
var errENF *entryNotFoundError
1311
return errors.As(err, &errENF)
1412
}
15-
16-
func (c *Cache) readFileCGIL(outputFile string, err error) ([]byte, error) {
17-
if err != nil {
18-
return nil, err
19-
}
20-
21-
return robustio.ReadFile(outputFile)
22-
}

0 commit comments

Comments
 (0)