main
 1package generator
 2
 3import (
 4	"encoding/xml"
 5	"os"
 6	"path/filepath"
 7
 8	"mokhan.ca/xlgmokha/gitmal/internal/git"
 9)
10
11type AtomFeed struct {
12	XMLName xml.Name    `xml:"feed"`
13	XMLNS   string      `xml:"xmlns,attr"`
14	ID      string      `xml:"id"`
15	Title   string      `xml:"title"`
16	Updated string      `xml:"updated"`
17	Link    []AtomLink  `xml:"link"`
18	Entries []AtomEntry `xml:"entry"`
19}
20
21type AtomLink struct {
22	Rel  string `xml:"rel,attr"`
23	Type string `xml:"type,attr"`
24	Href string `xml:"href,attr"`
25}
26
27type AtomEntry struct {
28	ID      string     `xml:"id"`
29	Title   string     `xml:"title"`
30	Updated string     `xml:"updated"`
31	Author  AtomAuthor `xml:"author"`
32	Content string     `xml:"content"`
33	Link    AtomLink   `xml:"link"`
34}
35
36type AtomAuthor struct {
37	Name  string `xml:"name"`
38	Email string `xml:"email,omitempty"`
39}
40
41func GenerateCommitsAtom(commits []git.Commit, params Params) error {
42	outDir := filepath.Join(params.OutputDir, "commits")
43	if err := os.MkdirAll(outDir, 0o755); err != nil {
44		return err
45	}
46
47	var updated string
48	if len(commits) > 0 {
49		updated = commits[0].Date.Format("2006-01-02T15:04:05Z")
50	}
51
52	entries := make([]AtomEntry, len(commits))
53	for i, c := range commits {
54		content := c.Subject
55		if c.Body != "" {
56			content = c.Subject + "\n\n" + c.Body
57		}
58		entries[i] = AtomEntry{
59			ID:      "urn:sha:" + c.Hash,
60			Title:   c.Subject,
61			Updated: c.Date.Format("2006-01-02T15:04:05Z"),
62			Author:  AtomAuthor{Name: c.Author, Email: c.Email},
63			Content: content,
64			Link: AtomLink{
65				Rel:  "alternate",
66				Type: "text/html",
67				Href: "commit/" + c.Hash + ".html",
68			},
69		}
70	}
71
72	feed := AtomFeed{
73		XMLNS:   "http://www.w3.org/2005/Atom",
74		ID:      "urn:gitmal:" + params.Name + ":" + params.Ref.String(),
75		Title:   params.Name + " commits on " + params.Ref.String(),
76		Updated: updated,
77		Link: []AtomLink{
78			{Rel: "self", Type: "application/atom+xml", Href: "commits/" + params.Ref.DirName() + ".atom"},
79		},
80		Entries: entries,
81	}
82
83	outPath := filepath.Join(outDir, params.Ref.DirName()+".atom")
84	f, err := os.Create(outPath)
85	if err != nil {
86		return err
87	}
88	defer f.Close()
89
90	if _, err := f.WriteString(xml.Header); err != nil {
91		return err
92	}
93	encoder := xml.NewEncoder(f)
94	encoder.Indent("", "  ")
95	return encoder.Encode(feed)
96}