github.com/quay/claircore@v1.5.28/java/jar/fetch_testdata.go (about) 1 //go:build tools 2 3 // Fetch is the script used to populate the stuff in testdir. This extracts a 4 // Cassandra distribution to do so, so unfortunately the URL hard-coded here 5 // needs to be kept in sync with the one in the actual test. 6 package main 7 8 import ( 9 "archive/tar" 10 "archive/zip" 11 "bytes" 12 "compress/gzip" 13 "errors" 14 "io" 15 "log" 16 "net/http" 17 "os" 18 "path/filepath" 19 ) 20 21 const ( 22 url = `https://archive.apache.org/dist/cassandra/4.0.0/apache-cassandra-4.0.0-bin.tar.gz` 23 ) 24 25 func main() { 26 log.Println("fetching", url) 27 res, err := http.Get(url) 28 if !errors.Is(err, nil) { 29 log.Fatal(err) 30 } 31 defer res.Body.Close() 32 if res.StatusCode != http.StatusOK { 33 log.Fatalf("unexpected HTTP status: %v", res.Status) 34 } 35 if err := os.MkdirAll("testdata/manifest", 0755); err != nil { 36 log.Fatal(err) 37 } 38 if err := os.MkdirAll("testdata/properties", 0755); err != nil { 39 log.Fatal(err) 40 } 41 42 gz, err := gzip.NewReader(res.Body) 43 if !errors.Is(err, nil) { 44 log.Fatal(err) 45 } 46 defer gz.Close() 47 t := tar.NewReader(gz) 48 49 var h *tar.Header 50 var buf bytes.Buffer 51 for h, err = t.Next(); err == nil; h, err = t.Next() { 52 if filepath.Ext(h.Name) != ".jar" { 53 continue 54 } 55 buf.Grow(int(h.Size)) 56 if _, err := buf.ReadFrom(t); err != nil { 57 log.Fatal(err) 58 } 59 rd := bytes.NewReader(buf.Bytes()) 60 if err := extractManifest("testdata/manifest", rd, h); err != nil { 61 log.Fatal(err) 62 } 63 if err := extractProperties("testdata/properties", rd, h); err != nil { 64 log.Fatal(err) 65 } 66 buf.Reset() 67 } 68 if !errors.Is(err, io.EOF) { 69 log.Fatal(err) 70 } 71 } 72 73 func extractManifest(prefix string, rd *bytes.Reader, h *tar.Header) error { 74 const manifest = "META-INF/MANIFEST.MF" 75 76 z, err := zip.NewReader(rd, rd.Size()) 77 if err != nil { 78 return err 79 } 80 f, err := z.Open(manifest) 81 if err != nil { 82 // ??? 83 log.Printf("%s: no manifest", h.Name) 84 return nil 85 } 86 defer f.Close() 87 88 outname := filepath.Join(prefix, filepath.Base(h.Name)) 89 o, err := os.Create(outname) 90 if err != nil { 91 return err 92 } 93 defer o.Close() 94 log.Printf("%s: extracting %q to %q", h.Name, manifest, o.Name()) 95 if _, err := io.Copy(o, f); err != nil { 96 return err 97 } 98 return nil 99 } 100 101 func extractProperties(prefix string, rd *bytes.Reader, h *tar.Header) error { 102 z, err := zip.NewReader(rd, rd.Size()) 103 if err != nil { 104 return err 105 } 106 found := false 107 for _, f := range z.File { 108 if filepath.Base(f.Name) != "pom.properties" { 109 continue 110 } 111 rd, err := f.Open() 112 if err != nil { 113 return err 114 } 115 defer rd.Close() 116 outname := filepath.Join(prefix, filepath.Base(h.Name)) 117 o, err := os.Create(outname) 118 if err != nil { 119 return err 120 } 121 defer o.Close() 122 log.Printf("%s: extracting %q to %q", h.Name, f.Name, o.Name()) 123 if _, err := io.Copy(o, rd); err != nil { 124 return err 125 } 126 found = true 127 // It's bad form to let these defers pile up, but this is just a script. 128 } 129 if !found { 130 log.Printf("%s: no properties", h.Name) 131 } 132 return nil 133 }