diff options
| author | Gabriel Arakaki Giovanini <mail@gabrielgio.me> | 2023-08-26 17:32:58 +0200 | 
|---|---|---|
| committer | Gabriel Arakaki Giovanini <mail@gabrielgio.me> | 2023-08-26 17:36:15 +0200 | 
| commit | dd2a1c38a5a9f561d58b58da56d3230fd715fcde (patch) | |
| tree | d4161e5f1c0e9718ef739745f6a9619c10701f8e | |
| download | apkdoc-dd2a1c38a5a9f561d58b58da56d3230fd715fcde.tar.gz apkdoc-dd2a1c38a5a9f561d58b58da56d3230fd715fcde.tar.bz2 apkdoc-dd2a1c38a5a9f561d58b58da56d3230fd715fcde.zip | |
Initial commit
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | Makefile | 13 | ||||
| -rw-r--r-- | go.mod | 3 | ||||
| -rw-r--r-- | main.go | 75 | ||||
| -rw-r--r-- | parser.go | 85 | 
5 files changed, 178 insertions, 0 deletions
| diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f331ccd --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +bin/ +vendor/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e3ed19e --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +BIN?=apkdoc +GO_RUN?= go run -v +GO_BUILD?= go build -v + +all: build + +run: +	$(GO_RUN) . + +build: +	$(GO_BUILD) \ +		-o bin/$(BIN) \ +		. @@ -0,0 +1,3 @@ +module git.sr.ht/~gabrielgio/apkdoc + +go 1.20 @@ -0,0 +1,75 @@ +package main + +import ( +	"archive/tar" +	"bufio" +	"compress/gzip" +	"errors" +	"flag" +	"fmt" +	"io" +	"net/http" +) + +func fechIndex(url string) (io.ReadCloser, error) { +	resp, err := http.Get(url) +	if err != nil { +		return nil, err +	} + +	if resp.StatusCode != 200 { +		return nil, errors.New("Invlid response") +	} + +	return resp.Body, nil +} + +func main() { +	url := flag.String("url", "", "Url to the APKINDEX.tar.gz") +	flag.Parse() + +	tarStream, err := fechIndex(*url) +	if err != nil { +		panic("Error fecthing the index: " + err.Error()) +	} + +	defer tarStream.Close() + +	archive, err := gzip.NewReader(tarStream) +	if err != nil { +		panic("Error creating gzip reader: " + err.Error()) +	} + +	tr := tar.NewReader(archive) + +	for { +		h, err := tr.Next() +		if err != nil { +			panic("Error reading next tar entry: " + err.Error()) +		} + +		if h.FileInfo().Name() == "APKINDEX" { +			break +		} +	} + +	s := bufio.NewScanner(tr) + +	entries := make([]*Entry, 0) +	lines := make([]string, 0) + +	for s.Scan() { +		l := s.Text() +		if l == "" { +			entry := Parse(lines) +			entries = append(entries, entry) +			lines = make([]string, 0) +		} else { +			lines = append(lines, l) +		} +	} + +	for _, e := range entries { +		fmt.Printf("%+v\n", e) +	} +} diff --git a/parser.go b/parser.go new file mode 100644 index 0000000..998df91 --- /dev/null +++ b/parser.go @@ -0,0 +1,85 @@ +package main + +import ( +	"strconv" +	"strings" +	"time" +) + +type ( +	// https://wiki.alpinelinux.org/wiki/Apk_spec +	Entry struct { +		Checksum         string     // C +		Name             string     // P +		Architecture     *string    // A +		PackageSize      int        // S +		InstalledSize    *int       // I +		Description      string     // T +		Url              string     // U +		License          string     // L +		Origin           *string    // o +		Maintainer       *string    // m +		BuildTime        *time.Time // t +		Commit           *string    // c +		ProviderPriority *int       // k +		Dependencies     []string   // D +		Provides         []string   // p +		InstallIf        []string   // i +	} +) + +func ptr[T any](v T) *T { +	return &v +} + +func split(line string) (string, string) { +	parts := strings.SplitN(line, ":", 2) +	return parts[0], parts[1] +} + +func toInt(v string) int { +	i, _ := strconv.Atoi(v) +	return i +} + +func Parse(lines []string) *Entry { +	entry := &Entry{} +	for _, line := range lines { +		r, c := split(line) +		switch r { +		case "C": +			entry.Checksum = c +		case "P": +			entry.Name = c +		case "A": +			entry.Architecture = &c +		case "S": +			entry.PackageSize = toInt(c) +		case "I": +			entry.InstalledSize = ptr(toInt(c)) +		case "T": +			entry.Description = c +		case "U": +			entry.Url = c +		case "L": +			entry.License = c +		case "o": +			entry.Origin = &c +		case "m": +			entry.Maintainer = &c +		case "t": +			entry.BuildTime = ptr(time.Unix(int64(toInt(c)), 0)) +		case "c": +			entry.Commit = &c +		case "k": +			entry.ProviderPriority = ptr(toInt(c)) +		case "D": +			entry.Dependencies = strings.Split(c, " ") +		case "p": +			entry.Dependencies = strings.Split(c, " ") +		case "i": +			entry.Dependencies = strings.Split(c, " ") +		} +	} +	return entry +} | 
