apkdoc @ a21602a450217333a27419d8168865b21fae6e7e

feat: Add option for inputing template

Now a template file is required to run the cli command. That gives the
user an option to provide its own template file.

An default will be provided later.
  1diff --git a/example.txt b/example.txt
  2new file mode 100644
  3index 0000000000000000000000000000000000000000..8c5c0eb742c679931b7cacb13d419e64e9411413
  4--- /dev/null
  5+++ b/example.txt
  6@@ -0,0 +1,8 @@
  7+# Apks Alpine 3.18
  8+
  9+{{ range $e := . }}
 10+## {{ $e.Name  }}
 11+
 12+{{ range $name, $value := ($e.Properties) }}- **{{$name}}**: {{ $value }}
 13+{{ end }}
 14+{{ end }}
 15diff --git a/main.go b/main.go
 16index fe3c34ff9c8a0fac6d77e6b41d7ebb7897ae4bbf..314ecc8ad5f43e74b6670920e62dd853335e1e7d 100644
 17--- a/main.go
 18+++ b/main.go
 19@@ -5,19 +5,18 @@ 	"archive/tar"
 20 	"bufio"
 21 	"compress/gzip"
 22 	"errors"
 23-	"fmt"
 24 	"io"
 25 	"net/http"
 26 	"os"
 27 
 28-	"git.sr.ht/~gabrielgio/apkdoc/parser"
 29 	flag "github.com/spf13/pflag"
 30 )
 31 
 32 func main() {
 33 	url := flag.StringP("url", "u", "", "Url to the APKINDEX.tar.gz")
 34 	output := flag.StringP("output", "o", "index.md", "Output path")
 35-	repositoryFormat := flag.StringP("repository-format", "f", "https://git.sr.ht/~gabrielgio/apkbuilds/tree/%s/item/apks/%s", "Template to build repository link")
 36+	templateType := flag.StringP("template-type", "p", "text", "Template system to be used, options: html, text")
 37+	templateFile := flag.StringP("template-file", "t", "text", "Template file to be used")
 38 	flag.Parse()
 39 
 40 	tarStream, err := fechIndex(*url)
 41@@ -47,13 +46,13 @@ 	}
 42 
 43 	s := bufio.NewScanner(tr)
 44 
 45-	entries := make([]*parser.Entry, 0)
 46+	entries := make([]*Entry, 0)
 47 	lines := make([]string, 0)
 48 
 49 	for s.Scan() {
 50 		l := s.Text()
 51 		if l == "" {
 52-			entry := parser.Parse(lines)
 53+			entry := Parse(lines)
 54 			entries = append(entries, entry)
 55 			lines = make([]string, 0)
 56 		} else {
 57@@ -66,13 +65,16 @@ 	if err != nil {
 58 		panic("Error openning output file: " + err.Error())
 59 	}
 60 
 61-	for _, e := range entries {
 62-		fmt.Fprintln(outputFile, e.FomartLink(*repositoryFormat))
 63+	tmpl, err := GetTemplate(*templateType, *templateFile)
 64+	if err != nil {
 65+		panic("Error loading template file: " + err.Error())
 66 	}
 67+
 68+	tmpl.Execute(outputFile, entries)
 69 }
 70 
 71 func getOutputFile(output string) (*os.File, error) {
 72-	if output == "" {
 73+	if output != "" {
 74 		outputFile, err := os.Create(output)
 75 		if err != nil {
 76 			return nil, err
 77diff --git a/parser/parser.go b/parser.go
 78rename from parser/parser.go
 79rename to parser.go
 80index 62b0d855ba36b390d7eb5c6bcbe76294cad99bc5..344efcab3bf3b5e1388d95237d1bbbbb00e3f62a 100644
 81--- a/parser/parser.go
 82+++ b/parser.go
 83@@ -1,4 +1,4 @@
 84-package parser
 85+package main
 86 
 87 import (
 88 	"fmt"
 89@@ -33,6 +33,57 @@
 90 func (e *Entry) FomartLink(format string) string {
 91 	c := strings.Replace(*e.Commit, "-dirty", "", -1)
 92 	return fmt.Sprintf(format, c, *e.Origin)
 93+}
 94+
 95+func (e *Entry) Properties() map[string]string {
 96+	p := make(map[string]string)
 97+
 98+	p["checksum"] = e.Checksum
 99+	p["version"] = e.Version
100+	p["name"] = e.Name
101+	p["package size"] = strconv.Itoa(e.PackageSize)
102+	p["installed size"] = strconv.Itoa(e.InstalledSize)
103+	p["description"] = e.Description
104+	p["url"] = e.Url
105+	p["license"] = e.License
106+
107+	if e.Architecture != nil {
108+		p["architecture"] = *e.Architecture
109+	}
110+
111+	if e.Origin != nil {
112+		p["origin"] = *e.Origin
113+	}
114+
115+	if e.Maintainer != nil {
116+		p["maintainer"] = *e.Maintainer
117+	}
118+
119+	if e.BuildTime != nil {
120+		p["build time"] = e.BuildTime.String()
121+	}
122+
123+	if e.Commit != nil {
124+		p["commit"] = *e.Commit
125+	}
126+
127+	if e.ProviderPriority != nil {
128+		p["provider priority"] = strconv.Itoa(*e.ProviderPriority)
129+	}
130+
131+	if len(e.Dependencies) > 0 {
132+		p["dependencies"] = strings.Join(e.Dependencies, " ")
133+	}
134+
135+	if len(e.Provides) > 0 {
136+		p["provides"] = strings.Join(e.Provides, " ")
137+	}
138+
139+	if len(e.InstallIf) > 0 {
140+		p["install if"] = strings.Join(e.InstallIf, " ")
141+	}
142+
143+	return p
144 }
145 
146 func ptr[T any](v T) *T {
147diff --git a/template.go b/template.go
148new file mode 100644
149index 0000000000000000000000000000000000000000..503af64338f8d2e30b3e37390cf9e54a642b2e44
150--- /dev/null
151+++ b/template.go
152@@ -0,0 +1,44 @@
153+package main
154+
155+import (
156+	html "html/template"
157+	"io"
158+	"os"
159+	text "text/template"
160+)
161+
162+type Templater interface {
163+	Execute(wr io.Writer, data any) error
164+}
165+
166+var (
167+	templateFunc = map[string]any{
168+		"DerefI": func(i *int) int { return *i },
169+		"DerefS": func(i *string) string { return *i },
170+	}
171+)
172+
173+func GetTemplate(templateType, filePath string) (Templater, error) {
174+	file, err := os.Open(filePath)
175+	if err != nil {
176+		return nil, err
177+	}
178+
179+	tmpl, err := io.ReadAll(file)
180+	if err != nil {
181+		return nil, err
182+	}
183+
184+	switch templateType {
185+	case "text":
186+		return text.New("text").
187+			Funcs(templateFunc).
188+			Parse(string(tmpl))
189+	case "html":
190+		return html.New("html").
191+			Funcs(templateFunc).
192+			Parse(string(tmpl))
193+	default:
194+		panic("Invalid template-type")
195+	}
196+}