@@ -384,7 +384,8 @@ func RemoveAll(dir string) error {
384384 return robustio .RemoveAll (dir )
385385}
386386
387- var GoSumFile string // path to go.sum; set by package modload
387+ var GoSumFile string // path to go.sum; set by package modload
388+ var WorkspaceGoSumFiles []string // path to module go.sums in workspace; set by package modload
388389
389390type modSum struct {
390391 mod module.Version
@@ -393,10 +394,11 @@ type modSum struct {
393394
394395var goSum struct {
395396 mu sync.Mutex
396- m map [module.Version ][]string // content of go.sum file
397- status map [modSum ]modSumStatus // state of sums in m
398- overwrite bool // if true, overwrite go.sum without incorporating its contents
399- enabled bool // whether to use go.sum at all
397+ m map [module.Version ][]string // content of go.sum file
398+ w map [string ]map [module.Version ][]string // sum file in workspace -> content of that sum file
399+ status map [modSum ]modSumStatus // state of sums in m
400+ overwrite bool // if true, overwrite go.sum without incorporating its contents
401+ enabled bool // whether to use go.sum at all
400402}
401403
402404type modSumStatus struct {
@@ -417,23 +419,38 @@ func initGoSum() (bool, error) {
417419
418420 goSum .m = make (map [module.Version ][]string )
419421 goSum .status = make (map [modSum ]modSumStatus )
422+ goSum .w = make (map [string ]map [module.Version ][]string )
423+
424+ for _ , f := range WorkspaceGoSumFiles {
425+ goSum .w [f ] = make (map [module.Version ][]string )
426+ _ , err := readGoSumFile (goSum .w [f ], f )
427+ if err != nil {
428+ return false , err
429+ }
430+ }
431+
432+ enabled , err := readGoSumFile (goSum .m , GoSumFile )
433+ goSum .enabled = enabled
434+ return enabled , err
435+ }
436+
437+ func readGoSumFile (dst map [module.Version ][]string , file string ) (bool , error ) {
420438 var (
421439 data []byte
422440 err error
423441 )
424- if actualSumFile , ok := fsys .OverlayPath (GoSumFile ); ok {
442+ if actualSumFile , ok := fsys .OverlayPath (file ); ok {
425443 // Don't lock go.sum if it's part of the overlay.
426444 // On Plan 9, locking requires chmod, and we don't want to modify any file
427445 // in the overlay. See #44700.
428446 data , err = os .ReadFile (actualSumFile )
429447 } else {
430- data , err = lockedfile .Read (GoSumFile )
448+ data , err = lockedfile .Read (file )
431449 }
432450 if err != nil && ! os .IsNotExist (err ) {
433451 return false , err
434452 }
435- goSum .enabled = true
436- readGoSum (goSum .m , GoSumFile , data )
453+ readGoSum (dst , file , data )
437454
438455 return true , nil
439456}
@@ -485,6 +502,16 @@ func HaveSum(mod module.Version) bool {
485502 if err != nil || ! inited {
486503 return false
487504 }
505+ for _ , goSums := range goSum .w {
506+ for _ , h := range goSums [mod ] {
507+ if ! strings .HasPrefix (h , "h1:" ) {
508+ continue
509+ }
510+ if ! goSum .status [modSum {mod , h }].dirty {
511+ return true
512+ }
513+ }
514+ }
488515 for _ , h := range goSum .m [mod ] {
489516 if ! strings .HasPrefix (h , "h1:" ) {
490517 continue
@@ -602,15 +629,32 @@ func checkModSum(mod module.Version, h string) error {
602629// If it finds a conflicting pair instead, it calls base.Fatalf.
603630// goSum.mu must be locked.
604631func haveModSumLocked (mod module.Version , h string ) bool {
632+ sumFileName := "go.sum"
633+ if strings .HasSuffix (GoSumFile , "go.work.sum" ) {
634+ sumFileName = "go.work.sum"
635+ }
605636 for _ , vh := range goSum .m [mod ] {
606637 if h == vh {
607638 return true
608639 }
609640 if strings .HasPrefix (vh , "h1:" ) {
610- base .Fatalf ("verifying %s@%s: checksum mismatch\n \t downloaded: %v\n \t go.sum: %v" + goSumMismatch , mod .Path , mod .Version , h , vh )
641+ base .Fatalf ("verifying %s@%s: checksum mismatch\n \t downloaded: %v\n \t %s: %v" + goSumMismatch , mod .Path , mod .Version , h , sumFileName , vh )
642+ }
643+ }
644+ // Also check workspace sums.
645+ foundMatch := false
646+ // Check sums from all files in case there are conflicts between
647+ // the files.
648+ for goSumFile , goSums := range goSum .w {
649+ for _ , vh := range goSums [mod ] {
650+ if h == vh {
651+ foundMatch = true
652+ } else if strings .HasPrefix (vh , "h1:" ) {
653+ base .Fatalf ("verifying %s@%s: checksum mismatch\n \t downloaded: %v\n \t %s: %v" + goSumMismatch , mod .Path , mod .Version , h , goSumFile , vh )
654+ }
611655 }
612656 }
613- return false
657+ return foundMatch
614658}
615659
616660// addModSumLocked adds the pair mod,h to go.sum.
@@ -749,7 +793,7 @@ Outer:
749793 goSum .m = make (map [module.Version ][]string , len (goSum .m ))
750794 readGoSum (goSum .m , GoSumFile , data )
751795 for ms , st := range goSum .status {
752- if st .used {
796+ if st .used && ! sumInWorkspaceModulesLocked ( ms . mod ) {
753797 addModSumLocked (ms .mod , ms .sum )
754798 }
755799 }
@@ -767,7 +811,7 @@ Outer:
767811 sort .Strings (list )
768812 for _ , h := range list {
769813 st := goSum .status [modSum {m , h }]
770- if ! st .dirty || (st .used && keep [m ]) {
814+ if ( ! st .dirty || (st .used && keep [m ])) && ! sumInWorkspaceModulesLocked ( m ) {
771815 fmt .Fprintf (& buf , "%s %s %s\n " , m .Path , m .Version , h )
772816 }
773817 }
@@ -784,6 +828,15 @@ Outer:
784828 return nil
785829}
786830
831+ func sumInWorkspaceModulesLocked (m module.Version ) bool {
832+ for _ , goSums := range goSum .w {
833+ if _ , ok := goSums [m ]; ok {
834+ return true
835+ }
836+ }
837+ return false
838+ }
839+
787840// TrimGoSum trims go.sum to contain only the modules needed for reproducible
788841// builds.
789842//
0 commit comments