1package main
2
3import (
4 "archive/tar"
5 "bufio"
6 "compress/gzip"
7 "errors"
8 "fmt"
9 "io"
10 "net/http"
11 "os"
12 "strconv"
13
14 flag "github.com/spf13/pflag"
15)
16
17func main() {
18 var (
19 url = flag.StringP("url", "u", "", "Url to the APKINDEX.tar.gz")
20 output = flag.StringP("output", "o", "index.md", "Output path")
21 templateType = flag.StringP("template-type", "p", "text", "Template system to be used, options: html, text")
22 templateFile = flag.StringP("template-file", "t", "text", "Template file to be used")
23 )
24 flag.Parse()
25
26 err := run(
27 *url,
28 *output,
29 *templateType,
30 *templateFile,
31 )
32 if err != nil {
33 fmt.Println(err)
34 os.Exit(1)
35 }
36}
37
38func run(
39 url string,
40 output string,
41 templateType string,
42 templateFile string,
43
44) error {
45
46 tarStream, err := fechIndex(url)
47 if err != nil {
48 return fmt.Errorf("Error fecthing index file: %w", err)
49 }
50
51 defer tarStream.Close()
52
53 archive, err := gzip.NewReader(tarStream)
54 if err != nil {
55 return fmt.Errorf("Error creating gzip reader: %w", err)
56 }
57
58 tr := tar.NewReader(archive)
59
60 for {
61 h, err := tr.Next()
62 if err != nil {
63 return fmt.Errorf("Error reading next tar entry: %w", err)
64 }
65
66 if h.FileInfo().Name() == "APKINDEX" {
67 break
68 }
69 }
70
71 s := bufio.NewScanner(tr)
72
73 entries := make([]*Entry, 0)
74 lines := make([]string, 0)
75
76 for s.Scan() {
77 l := s.Text()
78 if l == "" {
79 entry := Parse(lines)
80 entries = append(entries, entry)
81 lines = make([]string, 0)
82 } else {
83 lines = append(lines, l)
84 }
85 }
86
87 outputFile, err := getOutputFile(output)
88 if err != nil {
89 return fmt.Errorf("Error openning output file: %w", err)
90 }
91
92 tmpl, err := GetTemplate(templateType, templateFile)
93 if err != nil {
94 return fmt.Errorf("Error loading template file: %w", err)
95 }
96
97 err = tmpl.Execute(outputFile, entries)
98 if err != nil {
99 return fmt.Errorf("Error executing template: %w", err)
100 }
101 return nil
102}
103
104func getOutputFile(output string) (*os.File, error) {
105 if output != "" {
106 outputFile, err := os.Create(output)
107 if err != nil {
108 return nil, err
109 }
110 return outputFile, nil
111 } else {
112 return os.Stdout, nil
113 }
114}
115
116func fechIndex(url string) (io.ReadCloser, error) {
117 resp, err := http.Get(url)
118 if err != nil {
119 return nil, err
120 }
121
122 if resp.StatusCode != 200 {
123 return nil, errors.New("Http error " + strconv.Itoa(resp.StatusCode))
124 }
125
126 return resp.Body, nil
127}