Skip to content

Instantly share code, notes, and snippets.

@soasme
Created April 25, 2020 04:10
Show Gist options
  • Save soasme/a627614a8f7d2c4f041c610b4a123728 to your computer and use it in GitHub Desktop.
Save soasme/a627614a8f7d2c4f041c610b4a123728 to your computer and use it in GitHub Desktop.
package main
import (
"archive/zip"
"fmt"
"io/ioutil"
"os"
"strings"
)
// The metadata about the archive itself in the same basic key: value format.
type Wheel struct {
// `Wheel-Version` is the version number of the Wheel specification.
WheelVersion string
// `Generator` is the name and optionally the version of the software
// that produced the archive.
Generator string
// `Root-Is-Purelib` is true if the top level directory of the archive
// should be installed into purelib; otherwise the root should be
// installed into platlib.
RootIsPurelib bool
// `Tag` is the wheel's expanded compatibility tags; in the example the filename would contain py2.py3-none-any.
Tag []string
// Build is the build number and is omitted if there is no build number.
Build string
}
func WheelUnpack(filename string) (reader *zip.ReadCloser, err error) {
return zip.OpenReader(filename)
}
func ReadWheel(f *zip.File) (wheel Wheel, err error) {
rc, err := f.Open()
if err != nil {
return Wheel{}, err
}
defer rc.Close()
bytes, err := ioutil.ReadAll(rc)
content := string(bytes)
for _, line := range strings.Split(content, "\n") {
if strings.TrimSpace(line) == "" {
continue
}
sep := strings.Index(line, ":")
if sep == -1 {
return Wheel{}, fmt.Errorf("wheel: broken sep in WHEEL: %v", line)
}
key, value := line[0:sep], line[sep+1:len(line)]
switch key {
case "Wheel-Version":
wheel.WheelVersion = value
case "Generator":
wheel.Generator = value
case "Root-Is-Purelib":
wheel.RootIsPurelib = value == "true"
case "Tag":
wheel.Tag = append(wheel.Tag, value)
case "Build":
wheel.Build = value
}
}
return wheel, nil
}
func main() {
filename := os.Args[1]
fmt.Println("Parsing: " + filename)
r, err := WheelUnpack(filename)
if err != nil {
panic(err)
}
defer r.Close()
for _, f := range r.File {
// fmt.Println(f.Name)
chunks := strings.Split(f.Name, "/")
if chunks[len(chunks)-1] == "WHEEL" {
wheel, err := ReadWheel(f)
if err != nil {
panic(err)
}
fmt.Println(wheel)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment