|
3 | 3 | // license that can be found in the LICENSE file. |
4 | 4 |
|
5 | 5 | /* |
6 | | -Package goproxytest serves Go modules from a proxy |
7 | | -server designed to run on localhost during tests, both to make tests avoid |
8 | | -requiring specific network servers and also to make them |
9 | | -significantly faster. |
| 6 | +Package goproxytest serves Go modules from a proxy server designed to run on |
| 7 | +localhost during tests, both to make tests avoid requiring specific network |
| 8 | +servers and also to make them significantly faster. |
10 | 9 |
|
11 | | -Each module archive is named path_vers.txt, where slashes in path |
12 | | -have been replaced with underscores. The archive must contain |
13 | | -two files ".info" and ".mod", to be served as the info and mod files |
14 | | -in the proxy protocol (see https://research.swtch.com/vgo-module). |
15 | | -The remaining files are served as the content of the module zip file. |
16 | | -The path@vers prefix required of files in the zip file is added |
17 | | -automatically by the proxy: the files in the archive have names without |
18 | | -the prefix, like plain "go.mod", "x.go", and so on. |
| 10 | +Each module archive is either a file named path_vers.txt or a directory named |
| 11 | +path_vers, where slashes in path have been replaced with underscores. The |
| 12 | +archive or directory must contain two files ".info" and ".mod", to be served as |
| 13 | +the info and mod files in the proxy protocol (see |
| 14 | +https://research.swtch.com/vgo-module). The remaining files are served as the |
| 15 | +content of the module zip file. The path@vers prefix required of files in the |
| 16 | +zip file is added automatically by the proxy: the files in the archive have |
| 17 | +names without the prefix, like plain "go.mod", "x.go", and so on. |
19 | 18 |
|
20 | | -See ../cmd/txtar-addmod and ../cmd/txtar-savedir for tools |
21 | | -generate txtar files, although it's fine to write them by hand. |
| 19 | +See ../cmd/txtar-addmod and ../cmd/txtar-savedir for tools generate txtar |
| 20 | +files, although it's fine to write them by hand. |
22 | 21 | */ |
23 | 22 | package goproxytest |
24 | 23 |
|
@@ -92,7 +91,7 @@ func (srv *Server) readModList() error { |
92 | 91 | } |
93 | 92 | for _, info := range infos { |
94 | 93 | name := info.Name() |
95 | | - if !strings.HasSuffix(name, ".txt") { |
| 94 | + if !strings.HasSuffix(name, ".txt") && !info.IsDir() { |
96 | 95 | continue |
97 | 96 | } |
98 | 97 | name = strings.TrimSuffix(name, ".txt") |
@@ -275,6 +274,34 @@ func (srv *Server) readArchive(path, vers string) *txtar.Archive { |
275 | 274 | name := filepath.Join(srv.dir, prefix+"_"+encVers+".txt") |
276 | 275 | a := srv.archiveCache.Do(name, func() interface{} { |
277 | 276 | a, err := txtar.ParseFile(name) |
| 277 | + if os.IsNotExist(err) { |
| 278 | + // we fallback to trying a directory |
| 279 | + name = strings.TrimSuffix(name, ".txt") |
| 280 | + |
| 281 | + a = new(txtar.Archive) |
| 282 | + |
| 283 | + err = filepath.Walk(name, func(path string, info os.FileInfo, err error) error { |
| 284 | + if err != nil { |
| 285 | + return err |
| 286 | + } |
| 287 | + if path == name && !info.IsDir() { |
| 288 | + return fmt.Errorf("expected a directory root") |
| 289 | + } |
| 290 | + if info.IsDir() { |
| 291 | + return nil |
| 292 | + } |
| 293 | + arpath := filepath.ToSlash(strings.TrimPrefix(path, name+string(os.PathSeparator))) |
| 294 | + data, err := ioutil.ReadFile(path) |
| 295 | + if err != nil { |
| 296 | + return err |
| 297 | + } |
| 298 | + a.Files = append(a.Files, txtar.File{ |
| 299 | + Name: arpath, |
| 300 | + Data: data, |
| 301 | + }) |
| 302 | + return nil |
| 303 | + }) |
| 304 | + } |
278 | 305 | if err != nil { |
279 | 306 | if !os.IsNotExist(err) { |
280 | 307 | fmt.Fprintf(os.Stderr, "go proxy: %v\n", err) |
|
0 commit comments