1package main
2
3import (
4 "fmt"
5 "strconv"
6 "strings"
7 "time"
8)
9
10type (
11 // https://wiki.alpinelinux.org/wiki/Apk_spec
12 Entry struct {
13 Checksum string // C
14 Version string // V
15 Name string // P
16 Architecture *string // A
17 PackageSize int // S
18 InstalledSize int // I
19 Description string // T
20 Url string // U
21 License string // L
22 Origin *string // o
23 Maintainer *string // m
24 BuildTime *time.Time // t
25 Commit *string // c
26 ProviderPriority *int // k
27 Dependencies []string // D
28 Provides []string // p
29 InstallIf []string // i
30 }
31)
32
33func (e *Entry) FomartLink(format string) string {
34 c := strings.Replace(*e.Commit, "-dirty", "", -1)
35 return fmt.Sprintf(format, c, *e.Origin)
36}
37
38func (e *Entry) Properties() map[string]string {
39 p := make(map[string]string)
40
41 p["checksum"] = e.Checksum
42 p["version"] = e.Version
43 p["name"] = e.Name
44 p["package size"] = strconv.Itoa(e.PackageSize)
45 p["installed size"] = strconv.Itoa(e.InstalledSize)
46 p["description"] = e.Description
47 p["url"] = e.Url
48 p["license"] = e.License
49
50 if e.Architecture != nil {
51 p["architecture"] = *e.Architecture
52 }
53
54 if e.Origin != nil {
55 p["origin"] = *e.Origin
56 }
57
58 if e.Maintainer != nil {
59 p["maintainer"] = *e.Maintainer
60 }
61
62 if e.BuildTime != nil {
63 p["build time"] = e.BuildTime.String()
64 }
65
66 if e.Commit != nil {
67 p["commit"] = *e.Commit
68 }
69
70 if e.ProviderPriority != nil {
71 p["provider priority"] = strconv.Itoa(*e.ProviderPriority)
72 }
73
74 if len(e.Dependencies) > 0 {
75 p["dependencies"] = strings.Join(e.Dependencies, " ")
76 }
77
78 if len(e.Provides) > 0 {
79 p["provides"] = strings.Join(e.Provides, " ")
80 }
81
82 if len(e.InstallIf) > 0 {
83 p["install if"] = strings.Join(e.InstallIf, " ")
84 }
85
86 return p
87}
88
89func ptr[T any](v T) *T {
90 return &v
91}
92
93func split(line string) (string, string) {
94 parts := strings.SplitN(line, ":", 2)
95 return parts[0], parts[1]
96}
97
98func toInt(v string) int {
99 i, _ := strconv.Atoi(v)
100 return i
101}
102
103func Parse(lines []string) *Entry {
104 entry := &Entry{}
105 for _, line := range lines {
106 r, c := split(line)
107 switch r {
108 case "C":
109 entry.Checksum = c
110 case "V":
111 entry.Version = c
112 case "P":
113 entry.Name = c
114 case "A":
115 entry.Architecture = &c
116 case "S":
117 entry.PackageSize = toInt(c)
118 case "I":
119 entry.InstalledSize = toInt(c)
120 case "T":
121 entry.Description = c
122 case "U":
123 entry.Url = c
124 case "L":
125 entry.License = c
126 case "o":
127 entry.Origin = &c
128 case "m":
129 entry.Maintainer = &c
130 case "t":
131 entry.BuildTime = ptr(time.Unix(int64(toInt(c)), 0))
132 case "c":
133 entry.Commit = &c
134 case "k":
135 entry.ProviderPriority = ptr(toInt(c))
136 case "D":
137 entry.Dependencies = strings.Split(c, " ")
138 case "p":
139 entry.Dependencies = strings.Split(c, " ")
140 case "i":
141 entry.Dependencies = strings.Split(c, " ")
142 }
143 }
144 return entry
145}