@@ -19,6 +19,7 @@ import (
19
19
20
20
"cmd/go/internal/base"
21
21
"cmd/go/internal/cfg"
22
+ "cmd/go/internal/lockedfile"
22
23
"cmd/go/internal/par"
23
24
"cmd/go/internal/renameio"
24
25
@@ -296,7 +297,7 @@ func initGoSum() (bool, error) {
296
297
297
298
goSum .m = make (map [module.Version ][]string )
298
299
goSum .checked = make (map [modSum ]bool )
299
- data , err := renameio . ReadFile (GoSumFile )
300
+ data , err := lockedfile . Read (GoSumFile )
300
301
if err != nil && ! os .IsNotExist (err ) {
301
302
return false , err
302
303
}
@@ -529,60 +530,45 @@ func WriteGoSum() {
529
530
base .Fatalf ("go: updates to go.sum needed, disabled by -mod=readonly" )
530
531
}
531
532
532
- // We want to avoid races between creating the lockfile and deleting it, but
533
- // we also don't want to leave a permanent lockfile in the user's repository.
534
- //
535
- // On top of that, if we crash while writing go.sum, we don't want to lose the
536
- // sums that were already present in the file, so it's important that we write
537
- // the file by renaming rather than truncating — which means that we can't
538
- // lock the go.sum file itself.
539
- //
540
- // Instead, we'll lock a distinguished file in the cache directory: that will
541
- // only race if the user runs `go clean -modcache` concurrently with a command
542
- // that updates go.sum, and that's already racy to begin with.
543
- //
544
- // We'll end up slightly over-synchronizing go.sum writes if the user runs a
545
- // bunch of go commands that update sums in separate modules simultaneously,
546
- // but that's unlikely to matter in practice.
547
-
548
- unlock := SideLock ()
549
- defer unlock ()
533
+ // Make a best-effort attempt to acquire the side lock, only to exclude
534
+ // previous versions of the 'go' command from making simultaneous edits.
535
+ if unlock , err := SideLock (); err == nil {
536
+ defer unlock ()
537
+ }
550
538
551
- if ! goSum .overwrite {
552
- // Re-read the go.sum file to incorporate any sums added by other processes
553
- // in the meantime.
554
- data , err := renameio .ReadFile (GoSumFile )
555
- if err != nil && ! os .IsNotExist (err ) {
556
- base .Fatalf ("go: re-reading go.sum: %v" , err )
539
+ err := lockedfile .Transform (GoSumFile , func (data []byte ) ([]byte , error ) {
540
+ if ! goSum .overwrite {
541
+ // Incorporate any sums added by other processes in the meantime.
542
+ // Add only the sums that we actually checked: the user may have edited or
543
+ // truncated the file to remove erroneous hashes, and we shouldn't restore
544
+ // them without good reason.
545
+ goSum .m = make (map [module.Version ][]string , len (goSum .m ))
546
+ readGoSum (goSum .m , GoSumFile , data )
547
+ for ms := range goSum .checked {
548
+ addModSumLocked (ms .mod , ms .sum )
549
+ goSum .dirty = true
550
+ }
557
551
}
558
552
559
- // Add only the sums that we actually checked: the user may have edited or
560
- // truncated the file to remove erroneous hashes, and we shouldn't restore
561
- // them without good reason.
562
- goSum .m = make (map [module.Version ][]string , len (goSum .m ))
563
- readGoSum (goSum .m , GoSumFile , data )
564
- for ms := range goSum .checked {
565
- addModSumLocked (ms .mod , ms .sum )
566
- goSum .dirty = true
553
+ var mods []module.Version
554
+ for m := range goSum .m {
555
+ mods = append (mods , m )
567
556
}
568
- }
569
-
570
- var mods []module.Version
571
- for m := range goSum .m {
572
- mods = append (mods , m )
573
- }
574
- module .Sort (mods )
575
- var buf bytes.Buffer
576
- for _ , m := range mods {
577
- list := goSum .m [m ]
578
- sort .Strings (list )
579
- for _ , h := range list {
580
- fmt .Fprintf (& buf , "%s %s %s\n " , m .Path , m .Version , h )
557
+ module .Sort (mods )
558
+
559
+ var buf bytes.Buffer
560
+ for _ , m := range mods {
561
+ list := goSum .m [m ]
562
+ sort .Strings (list )
563
+ for _ , h := range list {
564
+ fmt .Fprintf (& buf , "%s %s %s\n " , m .Path , m .Version , h )
565
+ }
581
566
}
582
- }
567
+ return buf .Bytes (), nil
568
+ })
583
569
584
- if err := renameio . WriteFile ( GoSumFile , buf . Bytes (), 0666 ); err != nil {
585
- base .Fatalf ("go: writing go.sum: %v" , err )
570
+ if err != nil {
571
+ base .Fatalf ("go: updating go.sum: %v" , err )
586
572
}
587
573
588
574
goSum .checked = make (map [modSum ]bool )
0 commit comments