From badcee790a2da03be03f76d9a3c52eec771cbfc4 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 20 Jan 2026 16:58:46 -0800 Subject: [PATCH] pacify cmd/go's "go mod download" with zero byte (empty) cache/download/*.zip files Updates tailscale/corp#35834 Signed-off-by: Brad Fitzpatrick --- gomodfs.go | 1 + nfs.go | 10 ++++++++++ path.go | 6 ++++-- webdav.go | 4 ++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/gomodfs.go b/gomodfs.go index 4a412f0..1dd28f8 100644 --- a/gomodfs.go +++ b/gomodfs.go @@ -488,6 +488,7 @@ type pathHash [sha256.Size]byte var ( cdFileInfo = mkWellKnownPathHash("info") cdFileMod = mkWellKnownPathHash("mod") + cdFileZip = mkWellKnownPathHash("zip") cdFileZiphash = mkWellKnownPathHash("ziphash") pathHashTSGo = mkWellKnownPathHash(wkTSGoExtracted) ) diff --git a/nfs.go b/nfs.go index 8e2a010..129494c 100644 --- a/nfs.go +++ b/nfs.go @@ -232,6 +232,10 @@ func (b billyFS) Lstat(filename string) (os.FileInfo, error) { ctx := context.TODO() if ext := mp.CacheDownloadFileExt; ext != "" { + if ext == "zip" { + // The "zip" file is unused by cmd/go, so just return an empty file. + return regFileInfo{name: filepath.Base(filename), size: 0}, nil + } v, err := b.fs.getMetaFileByExt(ctx, mp.ModVersion, ext) if err != nil { b.fs.logf("Failed to get %s file for %v: %v", ext, mp.ModVersion, err) @@ -434,6 +438,8 @@ func (h *NFSHandler) fromHandle(handle handle) (ret handleTarget, err error) { return mkTargetFromPath(cdPath(mv, "info")), nil case cdFileMod: return mkTargetFromPath(cdPath(mv, "mod")), nil + case cdFileZip: + return mkTargetFromPath(cdPath(mv, "zip")), nil case cdFileZiphash: return mkTargetFromPath(cdPath(mv, "ziphash")), nil case pathHashTSGo: @@ -677,6 +683,10 @@ func (n *NFSHandler) getFileContentsUncached(ctx context.Context, filename strin } if ext := mp.CacheDownloadFileExt; ext != "" { + if ext == "zip" { + // The "zip" file is unused by cmd/go, so just return an empty file. + return []byte{}, attr, nil + } sp := n.fs.Stats.StartSpan("nfs.OpenFile-ext-" + ext) v, err := n.fs.getMetaFileByExt(ctx, mp.ModVersion, ext) sp.End(err) diff --git a/path.go b/path.go index 8baede4..0ec0b79 100644 --- a/path.go +++ b/path.go @@ -27,9 +27,11 @@ type gmPath struct { // are just checking for, but don't exist in the gomodfs hierarchy. NotExist bool - // CacheDownloadFileExt is one of "mod", "ziphash", "info" + // CacheDownloadFileExt is one of "mod", "ziphash", "info", or "zip". // if the path is for "cache/download//@v/.". // If non-empty, then ModVersion is also populated. + // The file contents for the "zip" file are unused by cmd/go, so gomodfs + // just pretends it exists and returns an empty file. CacheDownloadFileExt string // InZip, if true, means that the path is within the contents of a zip @@ -108,7 +110,7 @@ func parsePath(name string) (ret gmPath) { return } switch ext { - case ".mod", ".ziphash", ".info": + case ".mod", ".ziphash", ".info", ".zip": ret.CacheDownloadFileExt = ext[1:] default: // Not a recognized cache/download file. diff --git a/webdav.go b/webdav.go index 95825b7..ca7a15b 100644 --- a/webdav.go +++ b/webdav.go @@ -93,6 +93,10 @@ func (d webdavFS) Stat(ctx context.Context, name string) (fi os.FileInfo, retErr return regFileInfo{name: name, size: 123}, nil } if ext := dp.CacheDownloadFileExt; ext != "" { + if ext == "zip" { + // The "zip" file is unused by cmd/go, so just return an empty file. + return regFileInfo{name: name, size: 0}, nil + } sp := d.fs.Stats.StartSpan("webdav.Stat-et-" + ext) v, err := d.fs.getMetaFileByExt(ctx, dp.ModVersion, ext) sp.End(err)