@@ -21,19 +21,7 @@ import (
2121// ModuleProxy is a bare-bones Go module proxy for offline testing.
2222// It preloads all module data into memory for fast serving.
2323type ModuleProxy struct {
24- Modules map [string ]* Module
25- }
26-
27- type Module struct {
28- Path string
29- List []byte
30- Versions map [string ]* ModuleVersion
31- }
32-
33- type ModuleVersion struct {
34- Version string
35- Mod []byte
36- Zip []byte
24+ fs fstest.MapFS
3725}
3826
3927// ServeHTTP implements http.Handler
@@ -63,8 +51,12 @@ func (p *ModuleProxy) WriteToDir(dir string) error {
6351// ...
6452func Load (rootDir string ) (* ModuleProxy , error ) {
6553 p := & ModuleProxy {
66- Modules : make ( map [ string ] * Module ) ,
54+ fs : fstest. MapFS {} ,
6755 }
56+
57+ // Track versions per module for generating list files
58+ versions := make (map [string ][]string )
59+
6860 // Walk the root directory to find all modules
6961 err := filepath .WalkDir (rootDir , func (path string , d fs.DirEntry , err error ) error {
7062 if err != nil {
@@ -83,63 +75,58 @@ func Load(rootDir string) (*ModuleProxy, error) {
8375 if ! ok {
8476 return nil // Must have /@v/ separator
8577 }
78+
8679 // Load module file
8780 modfile , err := os .ReadFile (filepath .Join (path , "go.mod" ))
8881 if err != nil {
8982 return err
9083 }
84+
9185 // Create zip file
9286 zipdata , err := p .zip (path , modpath , version )
9387 if err != nil {
9488 return err
9589 }
96- // Add version
97- if p .Modules [modpath ] == nil {
98- p .Modules [modpath ] = & Module {
99- Path : modpath ,
100- Versions : map [string ]* ModuleVersion {},
101- }
102- }
103- p .Modules [modpath ].Versions [version ] = & ModuleVersion {
104- Version : version ,
105- Mod : modfile ,
106- Zip : zipdata ,
90+
91+ // Escape module path
92+ escaped , err := module .EscapePath (modpath )
93+ if err != nil {
94+ return err
10795 }
96+
97+ // Add files to MapFS
98+ prefix := escaped + "/@v/" + version
99+ maps .Copy (p .fs , fstest.MapFS {
100+ prefix + ".mod" : {Data : modfile },
101+ prefix + ".zip" : {Data : zipdata },
102+ prefix + ".info" : {Data : fmt .Appendf (nil , `{"Version":"%s","Time":"2023-01-01T00:00:00Z"}` , version )},
103+ })
104+
105+ // Track version for list generation
106+ versions [escaped ] = append (versions [escaped ], version )
107+
108108 return filepath .SkipDir
109109 })
110110 if err != nil {
111111 return nil , err
112112 }
113- // Generate list data for each module
114- for _ , mod := range p .Modules {
113+
114+ // Generate list files for each module
115+ for escaped , versions := range versions {
115116 var list bytes.Buffer
116- for _ , version := range slices .SortedFunc (maps .Keys (mod .Versions ), semver .Compare ) {
117+ slices .SortFunc (versions , semver .Compare )
118+ for _ , version := range versions {
117119 list .WriteString (version )
118120 list .WriteByte ('\n' )
119121 }
120- mod . List = list .Bytes ()
122+ p . fs [ escaped + "/@v/list" ] = & fstest. MapFile { Data : list .Bytes ()}
121123 }
124+
122125 return p , nil
123126}
124127
125128func (p * ModuleProxy ) FS () fs.FS {
126- files := fstest.MapFS {}
127- for modpath , mod := range p .Modules {
128- escaped , err := module .EscapePath (modpath )
129- if err != nil {
130- continue
131- }
132- files [escaped + "/@v/list" ] = & fstest.MapFile {Data : mod .List }
133- for version , ver := range mod .Versions {
134- prefix := escaped + "/@v/" + version
135- maps .Copy (files , fstest.MapFS {
136- prefix + ".mod" : {Data : ver .Mod },
137- prefix + ".zip" : {Data : ver .Zip },
138- prefix + ".info" : {Data : fmt .Appendf (nil , `{"Version":"%s","Time":"2023-01-01T00:00:00Z"}` , version )},
139- })
140- }
141- }
142- return files
129+ return p .fs
143130}
144131
145132func (p * ModuleProxy ) zip (dir , modpath , version string ) ([]byte , error ) {
0 commit comments