@@ -12,7 +12,6 @@ import (
1212 "bytes"
1313 "crypto/sha256"
1414 "encoding/hex"
15- "errors"
1615 "fmt"
1716 "io"
1817 "io/ioutil"
@@ -22,6 +21,8 @@ import (
2221 "strings"
2322 "time"
2423
24+ "github.com/pkg/errors"
25+
2526 "github.com/golangci/golangci-lint/internal/renameio"
2627)
2728
@@ -144,47 +145,56 @@ func (c *Cache) get(id ActionID) (Entry, error) {
144145 missing := func () (Entry , error ) {
145146 return Entry {}, errMissing
146147 }
147- f , err := os .Open (c .fileName (id , "a" ))
148+ failed := func (err error ) (Entry , error ) {
149+ return Entry {}, err
150+ }
151+ fileName := c .fileName (id , "a" )
152+ f , err := os .Open (fileName )
148153 if err != nil {
149- return missing ()
154+ if os .IsNotExist (err ) {
155+ return missing ()
156+ }
157+ return failed (err )
150158 }
151159 defer f .Close ()
152160 entry := make ([]byte , entrySize + 1 ) // +1 to detect whether f is too long
153- if n , err := io .ReadFull (f , entry ); n != entrySize || err != io .ErrUnexpectedEOF {
154- return missing ( )
161+ if n , readErr := io .ReadFull (f , entry ); n != entrySize || readErr != io .ErrUnexpectedEOF {
162+ return failed ( fmt . Errorf ( "read %d/%d bytes from %s with error %s" , n , entrySize , fileName , readErr ) )
155163 }
156164 if entry [0 ] != 'v' || entry [1 ] != '1' || entry [2 ] != ' ' || entry [3 + hexSize ] != ' ' || entry [3 + hexSize + 1 + hexSize ] != ' ' || entry [3 + hexSize + 1 + hexSize + 1 + 20 ] != ' ' || entry [entrySize - 1 ] != '\n' {
157- return missing ( )
165+ return failed ( fmt . Errorf ( "bad data in %s" , fileName ) )
158166 }
159167 eid , entry := entry [3 :3 + hexSize ], entry [3 + hexSize :]
160168 eout , entry := entry [1 :1 + hexSize ], entry [1 + hexSize :]
161169 esize , entry := entry [1 :1 + 20 ], entry [1 + 20 :]
162- etime , entry := entry [1 : 1 + 20 ], entry [ 1 + 20 : ]
170+ etime := entry [1 : 1 + 20 ]
163171 var buf [HashSize ]byte
164- if _ , err : = hex .Decode (buf [:], eid ); err != nil || buf != id {
165- return missing ( )
172+ if _ , err = hex .Decode (buf [:], eid ); err != nil || buf != id {
173+ return failed ( errors . Wrapf ( err , "failed to hex decode eid data in %s" , fileName ) )
166174 }
167- if _ , err : = hex .Decode (buf [:], eout ); err != nil {
168- return missing ( )
175+ if _ , err = hex .Decode (buf [:], eout ); err != nil {
176+ return failed ( errors . Wrapf ( err , "failed to hex decode eout data in %s" , fileName ) )
169177 }
170178 i := 0
171179 for i < len (esize ) && esize [i ] == ' ' {
172180 i ++
173181 }
174182 size , err := strconv .ParseInt (string (esize [i :]), 10 , 64 )
175183 if err != nil || size < 0 {
176- return missing ( )
184+ return failed ( fmt . Errorf ( "failed to parse esize int from %s with error %s" , fileName , err ) )
177185 }
178186 i = 0
179187 for i < len (etime ) && etime [i ] == ' ' {
180188 i ++
181189 }
182190 tm , err := strconv .ParseInt (string (etime [i :]), 10 , 64 )
183191 if err != nil || tm < 0 {
184- return missing ( )
192+ return failed ( fmt . Errorf ( "failed to parse etime int from %s with error %s" , fileName , err ) )
185193 }
186194
187- c .used (c .fileName (id , "a" ))
195+ if err = c .used (fileName ); err != nil {
196+ return failed (errors .Wrapf (err , "failed to mark %s as used" , fileName ))
197+ }
188198
189199 return Entry {buf , size , time .Unix (0 , tm )}, nil
190200}
@@ -196,7 +206,12 @@ func (c *Cache) GetFile(id ActionID) (file string, entry Entry, err error) {
196206 if err != nil {
197207 return "" , Entry {}, err
198208 }
199- file = c .OutputFile (entry .OutputID )
209+
210+ file , err = c .OutputFile (entry .OutputID )
211+ if err != nil {
212+ return "" , Entry {}, err
213+ }
214+
200215 info , err := os .Stat (file )
201216 if err != nil || info .Size () != entry .Size {
202217 return "" , Entry {}, errMissing
@@ -212,18 +227,29 @@ func (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) {
212227 if err != nil {
213228 return nil , entry , err
214229 }
215- data , _ := ioutil .ReadFile (c .OutputFile (entry .OutputID ))
230+ outputFile , err := c .OutputFile (entry .OutputID )
231+ if err != nil {
232+ return nil , entry , err
233+ }
234+
235+ data , err := ioutil .ReadFile (outputFile )
236+ if err != nil {
237+ return nil , entry , err
238+ }
239+
216240 if sha256 .Sum256 (data ) != entry .OutputID {
217241 return nil , entry , errMissing
218242 }
219243 return data , entry , nil
220244}
221245
222246// OutputFile returns the name of the cache file storing output with the given OutputID.
223- func (c * Cache ) OutputFile (out OutputID ) string {
247+ func (c * Cache ) OutputFile (out OutputID ) ( string , error ) {
224248 file := c .fileName (out , "d" )
225- c .used (file )
226- return file
249+ if err := c .used (file ); err != nil {
250+ return "" , err
251+ }
252+ return file , nil
227253}
228254
229255// Time constants for cache expiration.
@@ -253,12 +279,21 @@ const (
253279// mtime is more than an hour old. This heuristic eliminates
254280// nearly all of the mtime updates that would otherwise happen,
255281// while still keeping the mtimes useful for cache trimming.
256- func (c * Cache ) used (file string ) {
282+ func (c * Cache ) used (file string ) error {
257283 info , err := os .Stat (file )
258- if err == nil && c . now (). Sub ( info . ModTime ()) < mtimeInterval {
259- return
284+ if err != nil {
285+ return errors . Wrapf ( err , "failed to stat file %s" , file )
260286 }
261- os .Chtimes (file , c .now (), c .now ())
287+
288+ if c .now ().Sub (info .ModTime ()) < mtimeInterval {
289+ return nil
290+ }
291+
292+ if err := os .Chtimes (file , c .now (), c .now ()); err != nil {
293+ return errors .Wrapf (err , "failed to change time of file %s" , file )
294+ }
295+
296+ return nil
262297}
263298
264299// Trim removes old cache entries that are likely not to be reused.
@@ -285,7 +320,7 @@ func (c *Cache) Trim() {
285320
286321 // Ignore errors from here: if we don't write the complete timestamp, the
287322 // cache will appear older than it is, and we'll trim it again next time.
288- renameio .WriteFile (filepath .Join (c .dir , "trim.txt" ), []byte (fmt .Sprintf ("%d" , now .Unix ())), 0666 )
323+ _ = renameio .WriteFile (filepath .Join (c .dir , "trim.txt" ), []byte (fmt .Sprintf ("%d" , now .Unix ())), 0666 )
289324}
290325
291326// trimSubdir trims a single cache subdirectory.
@@ -367,7 +402,9 @@ func (c *Cache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify
367402 os .Remove (file )
368403 return err
369404 }
370- os .Chtimes (file , c .now (), c .now ()) // mainly for tests
405+ if err = os .Chtimes (file , c .now (), c .now ()); err != nil { // mainly for tests
406+ return errors .Wrapf (err , "failed to change time of file %s" , file )
407+ }
371408
372409 return nil
373410}
@@ -421,9 +458,12 @@ func (c *Cache) copyFile(file io.ReadSeeker, out OutputID, size int64) error {
421458 info , err := os .Stat (name )
422459 if err == nil && info .Size () == size {
423460 // Check hash.
424- if f , err := os .Open (name ); err == nil {
461+ if f , openErr := os .Open (name ); openErr == nil {
425462 h := sha256 .New ()
426- io .Copy (h , f )
463+ if _ , copyErr := io .Copy (h , f ); copyErr != nil {
464+ return errors .Wrap (copyErr , "failed to copy to sha256" )
465+ }
466+
427467 f .Close ()
428468 var out2 OutputID
429469 h .Sum (out2 [:0 ])
@@ -456,44 +496,49 @@ func (c *Cache) copyFile(file io.ReadSeeker, out OutputID, size int64) error {
456496 // before returning, to avoid leaving bad bytes in the file.
457497
458498 // Copy file to f, but also into h to double-check hash.
459- if _ , err : = file .Seek (0 , 0 ); err != nil {
460- f .Truncate (0 )
499+ if _ , err = file .Seek (0 , 0 ); err != nil {
500+ _ = f .Truncate (0 )
461501 return err
462502 }
463503 h := sha256 .New ()
464504 w := io .MultiWriter (f , h )
465- if _ , err : = io .CopyN (w , file , size - 1 ); err != nil {
466- f .Truncate (0 )
505+ if _ , err = io .CopyN (w , file , size - 1 ); err != nil {
506+ _ = f .Truncate (0 )
467507 return err
468508 }
469509 // Check last byte before writing it; writing it will make the size match
470510 // what other processes expect to find and might cause them to start
471511 // using the file.
472512 buf := make ([]byte , 1 )
473- if _ , err : = file .Read (buf ); err != nil {
474- f .Truncate (0 )
513+ if _ , err = file .Read (buf ); err != nil {
514+ _ = f .Truncate (0 )
475515 return err
476516 }
477- h .Write (buf )
517+ if n , wErr := h .Write (buf ); n != len (buf ) {
518+ return fmt .Errorf ("wrote to hash %d/%d bytes with error %s" , n , len (buf ), wErr )
519+ }
520+
478521 sum := h .Sum (nil )
479522 if ! bytes .Equal (sum , out [:]) {
480- f .Truncate (0 )
523+ _ = f .Truncate (0 )
481524 return fmt .Errorf ("file content changed underfoot" )
482525 }
483526
484527 // Commit cache file entry.
485- if _ , err : = f .Write (buf ); err != nil {
486- f .Truncate (0 )
528+ if _ , err = f .Write (buf ); err != nil {
529+ _ = f .Truncate (0 )
487530 return err
488531 }
489- if err : = f .Close (); err != nil {
532+ if err = f .Close (); err != nil {
490533 // Data might not have been written,
491534 // but file may look like it is the right size.
492535 // To be extra careful, remove cached file.
493536 os .Remove (name )
494537 return err
495538 }
496- os .Chtimes (name , c .now (), c .now ()) // mainly for tests
539+ if err = os .Chtimes (name , c .now (), c .now ()); err != nil { // mainly for tests
540+ return errors .Wrapf (err , "failed to change time of file %s" , name )
541+ }
497542
498543 return nil
499544}
0 commit comments