Description
Proposal Details
I would like to be able to create module zip files easily from https://pkg.go.dev/testing/fstest#MapFS and/or other fs.FS
implementing filesystems that are not present on the OS filesystem. Right now I have to use the https://pkg.go.dev/golang.org/x/mod/zip#Create function only. I can't use https://pkg.go.dev/golang.org/x/mod/zip#CreateFromDir with an fs.FS
instance.
The https://pkg.go.dev/golang.org/x/mod/zip#File interface is also a little bit awkward to use. I've found myself creating wrappers like this:
func filesToFS(files ...zip.File) (fs.FS, error) {
// create a struct with all the files that has a Open() method which
// opens said zip.File blah blah
}
func fsToFiles(fsys fs.FS) ([]zip.File, error) {
// walk the fs and create a list of wrapper structs that then call
// Open() on the original fsys when opened and such blah blah
}
and I thought: is there a way to add some fs.FS support to the x/mod/zip package itself? Hence this proposal. I don't really have any concrete thoughts on APIs or whathaveyou but some points of pain that could be taken into consideration for additional functions/features:
- It's hard to take an arbitrary fs.FS and zip it up to a io.Writer. You have to create some local wrapper structs and fiddle with getting the entire fs.FS filetree as a single snapshot into a list of zip.File items
- It's hard to unzip a module zip file from an io.ReaderAt (or zip.Reader) to a virtual filesystem -- this is moreso due to the lack of a standard writable filesystem interface proposal: io/fs: add writable interfaces #45757 but also the lack of a zip.GetModuleZipPrefixDirName() or whatever function; you have to figure out that prefix yourself when extracting the zip file and then optionally remove it
- It's hard to check an io.ReaderAt for validity. there's CheckZip() for .zip os files and CheckFiles() for whatever not-in-a-.zip files but nothing for the .zip buffer is-this-a-valid-mod-.zip-buffer check; you have to turn io.ReaderAt into a zip.Reader (easy) and then into []zip.Files and then CheckFiles() (hard; need own wrapper types).