repos / pgit

static site generator for git
git clone https://github.com/picosh/pgit.git

commit
a41a46b
parent
38c6478
author
Eric Bower
date
2023-06-25 18:51:17 +0000 UTC
refactor: change directory structure

And other tweaks
3 files changed,  +101, -57
D Dockerfile
+0, -13
 1@@ -1,13 +0,0 @@
 2-FROM golang:1.20 as builder
 3-COPY . /app
 4-WORKDIR /app
 5-RUN go build -o pgit ./main.go
 6-
 7-RUN git clone https://github.com/picosh/pico.git
 8-RUN git clone https://github.com/picosh/ops.git
 9-
10-RUN ./pgit
11-
12-FROM nginx:latest
13-COPY --from=builder /app/public /usr/share/nginx/html
14-EXPOSE 80
M config.yaml
+7, -2
 1@@ -1,3 +1,8 @@
 2+url: git.erock.io
 3 repos:
 4-  - /app/pico
 5-  - /app/ops
 6+  - path: /home/erock/dev/pico/pico
 7+    refs:
 8+      - main
 9+  - path: /home/erock/dev/pico/pico-ops
10+    refs:
11+      - main
M main.go
+94, -42
  1@@ -4,7 +4,7 @@ import (
  2 	"fmt"
  3 	html "html/template"
  4 	"os"
  5-	"path"
  6+	"path/filepath"
  7 	"strings"
  8 
  9 	git "github.com/gogs/git-module"
 10@@ -83,11 +83,16 @@ func CommitURL(repo string, commitID string) string {
 11 }
 12 
 13 func repoName(root string) string {
 14-	_, file := path.Split(root)
 15+	_, file := filepath.Split(root)
 16 	return file
 17 }
 18-func findDefaultBranch(refs []*git.Reference) *git.Reference {
 19-	for _, def := range defaultBranches {
 20+func findDefaultBranch(config *RepoConfig, refs []*git.Reference) *git.Reference {
 21+	branches := config.Refs
 22+	if len(branches) == 0 {
 23+		branches = defaultBranches
 24+	}
 25+
 26+	for _, def := range branches {
 27 		for _, ref := range refs {
 28 			if "refs/heads/"+def == ref.Refspec {
 29 				return ref
 30@@ -113,7 +118,7 @@ func walkTree(tree *git.Tree, branch string, curpath string, aggregate []*TreeIt
 31 			aggregate = append(aggregate, &TreeItem{
 32 				Path:  fname,
 33 				Entry: entry,
 34-				URL:   path.Join("/tree", branch, fname),
 35+				URL:   filepath.Join("/", "tree", branch, "item", fname),
 36 			})
 37 		}
 38 	}
 39@@ -133,13 +138,13 @@ func writeHtml(data *WriteData) {
 40 	bail(err)
 41 
 42 	outdir := viper.GetString("outdir")
 43-	dir := path.Join(outdir, data.RepoName, data.Subdir)
 44+	dir := filepath.Join(outdir, data.RepoName, data.Subdir)
 45 	fmt.Println(dir)
 46 	fmt.Println(data.Name)
 47 	err = os.MkdirAll(dir, os.ModePerm)
 48 	bail(err)
 49 
 50-	w, err := os.OpenFile(path.Join(dir, data.Name), os.O_WRONLY|os.O_CREATE, 0755)
 51+	w, err := os.OpenFile(filepath.Join(dir, data.Name), os.O_WRONLY|os.O_CREATE, 0755)
 52 	bail(err)
 53 
 54 	err = ts.Execute(w, data)
 55@@ -158,20 +163,31 @@ func writeIndex(data *IndexPage) {
 56 	bail(err)
 57 
 58 	outdir := viper.GetString("outdir")
 59-	dir := path.Join(outdir)
 60+	dir := filepath.Join(outdir)
 61 	fmt.Println(dir)
 62 	err = os.MkdirAll(dir, os.ModePerm)
 63 	bail(err)
 64 
 65-	w, err := os.OpenFile(path.Join(dir, "index.html"), os.O_WRONLY|os.O_CREATE, 0755)
 66+	w, err := os.OpenFile(filepath.Join(dir, "index.html"), os.O_WRONLY|os.O_CREATE, 0755)
 67 	bail(err)
 68 
 69 	err = ts.Execute(w, data)
 70 	bail(err)
 71 }
 72+
 73+func writeRootSummary(data *PageData) {
 74+	writeHtml(&WriteData{
 75+		Name:     "index.html",
 76+		Template: "./html/summary.page.tmpl",
 77+		Data:     data,
 78+		RepoName: data.Repo.Name,
 79+		Repo:     data.Repo,
 80+	})
 81+}
 82 func writeSummary(data *PageData) {
 83 	writeHtml(&WriteData{
 84 		Name:     "index.html",
 85+		Subdir: filepath.Join("tree", data.RevName),
 86 		Template: "./html/summary.page.tmpl",
 87 		Data:     data,
 88 		RepoName: data.Repo.Name,
 89@@ -180,7 +196,8 @@ func writeSummary(data *PageData) {
 90 }
 91 func writeTree(data *PageData) {
 92 	writeHtml(&WriteData{
 93-		Name:     "tree.html",
 94+		Name:     "index.html",
 95+		Subdir: filepath.Join("tree", data.RevName),
 96 		Template: "./html/tree.page.tmpl",
 97 		Data:     data,
 98 		RepoName: data.Repo.Name,
 99@@ -189,7 +206,8 @@ func writeTree(data *PageData) {
100 }
101 func writeLog(data *PageData) {
102 	writeHtml(&WriteData{
103-		Name:     "log.html",
104+		Name:     "index.html",
105+		Subdir: filepath.Join("logs", data.RevName),
106 		Template: "./html/log.page.tmpl",
107 		Data:     data,
108 		RepoName: data.Repo.Name,
109@@ -216,13 +234,13 @@ func writeHTMLTreeFiles(data *PageData) {
110 		bail(err)
111 		file.NumLines = len(strings.Split(string(b), "\n"))
112 
113-		d := path.Dir(file.Path)
114+		d := filepath.Dir(file.Path)
115 		writeHtml(&WriteData{
116 			Name:     fmt.Sprintf("%s.html", file.Entry.Name()),
117 			Template: "./html/file.page.tmpl",
118 			Data:     &FileData{Contents: string(b)},
119 			RepoName: data.Repo.Name,
120-			Subdir:   path.Join("tree", data.RevName, d),
121+			Subdir:   filepath.Join("tree", data.RevName, "item", d),
122 			Repo:     data.Repo,
123 		})
124 	}
125@@ -285,40 +303,62 @@ func writeLogDiffs(project string, repo *git.Repository, data *PageData, cache m
126 	}
127 }
128 
129-func writeRepo(root string) {
130-	repo, err := git.Open(root)
131+func writeRepo(config *RepoConfig) {
132+	repo, err := git.Open(config.Path)
133 	bail(err)
134 
135-	name := repoName(root)
136+	name := repoName(config.Path)
137+
138+	heads, err := repo.ShowRef(git.ShowRefOptions{Heads: true, Tags: false})
139+	bail(err)
140+
141+	rev := findDefaultBranch(config, heads)
142+	if rev == nil {
143+		bail(fmt.Errorf("no default branch found"))
144+	}
145+	_, revName := filepath.Split(rev.Refspec)
146+
147 	repoData := &RepoData{
148 		Name:       name,
149 		SummaryURL: fmt.Sprintf("/%s/index.html", name),
150-		TreeURL:    fmt.Sprintf("/%s/tree.html", name),
151-		LogURL:     fmt.Sprintf("/%s/log.html", name),
152+		TreeURL:    fmt.Sprintf("/%s/tree/%s/index.html", name, revName),
153+		LogURL:     fmt.Sprintf("/%s/logs/%s/index.html", name, revName),
154 		RefsURL:    fmt.Sprintf("/%s/refs.html", name),
155 		CloneURL:   fmt.Sprintf("/%s.git", name),
156 	}
157 
158-	heads, err := repo.ShowRef(git.ShowRefOptions{Heads: true, Tags: false})
159-	bail(err)
160-
161 	tags, _ := repo.ShowRef(git.ShowRefOptions{Heads: false, Tags: true})
162 
163 	cache := make(map[string]bool)
164-	rev := findDefaultBranch(heads)
165-	if rev != nil {
166-		// for _, rev := range heads {
167-		_, revName := path.Split(rev.Refspec)
168-		data := &PageData{
169-			Branches: heads,
170-			Tags:     tags,
171-			Rev:      rev,
172-			RevName:  revName,
173-			Repo:     repoData,
174-			Readme:   "",
175-		}
176 
177-		writeBranch(repo, data, cache)
178+	data := &PageData{
179+		Branches: heads,
180+		Tags:     tags,
181+		Rev:      rev,
182+		RevName:  revName,
183+		Repo:     repoData,
184+		Readme:   "",
185+	}
186+	writeRootSummary(data)
187+	writeRefs(data)
188+
189+	for _, revn := range config.Refs {
190+		for _, head := range heads {
191+			_, headName := filepath.Split(head.Refspec)
192+			if revn != headName {
193+				continue
194+			}
195+			data := &PageData{
196+				Branches: heads,
197+				Tags:     tags,
198+				Rev:      head,
199+				RevName:  headName,
200+				Repo:     repoData,
201+				Readme:   "",
202+			}
203+
204+			writeBranch(repo, data, cache)
205+		}
206 	}
207 }
208 
209@@ -340,11 +380,12 @@ func writeBranch(repo *git.Repository, pageData *PageData, cache map[string]bool
210 	treeEntries := walkTree(tree, pageData.RevName, "", entries)
211 	for _, entry := range treeEntries {
212 		entry.Path = strings.TrimPrefix(entry.Path, "/")
213-		entry.URL = path.Join(
214+		entry.URL = filepath.Join(
215 			"/",
216 			pageData.Repo.Name,
217 			"tree",
218 			pageData.RevName,
219+			"item",
220 			fmt.Sprintf("%s.html", entry.Path),
221 		)
222 	}
223@@ -352,9 +393,7 @@ func writeBranch(repo *git.Repository, pageData *PageData, cache map[string]bool
224 	pageData.Log = logs
225 	pageData.Tree = treeEntries
226 
227-	writeSummary(pageData)
228 	writeLog(pageData)
229-	writeRefs(pageData)
230 	writeHTMLTreeFiles(pageData)
231 	writeLogDiffs(pageData.Repo.Name, repo, pageData, cache)
232 
233@@ -365,6 +404,15 @@ func writeBranch(repo *git.Repository, pageData *PageData, cache map[string]bool
234 	}
235 }
236 
237+type RepoConfig struct {
238+	Path string   `mapstructure:"path"`
239+	Refs []string `mapstructure:"refs"`
240+}
241+type Config struct {
242+	Repos []*RepoConfig `mapstructure:"repos"`
243+	URL   string        `mapstructure:"url"`
244+}
245+
246 func main() {
247 	viper.SetDefault("outdir", "./public")
248 	viper.SetConfigName("config")
249@@ -373,11 +421,15 @@ func main() {
250 	err := viper.ReadInConfig()
251 	bail(err)
252 
253-	repos := viper.GetStringSlice("repos")
254+	var config Config
255+	if err := viper.Unmarshal(&config); err != nil {
256+		fmt.Println(err)
257+		return
258+	}
259 	repoList := []*RepoItemData{}
260-	for _, r := range repos {
261-		name := repoName(r)
262-		url := path.Join("/", name, "index.html")
263+	for _, r := range config.Repos {
264+		name := repoName(r.Path)
265+		url := filepath.Join("/", name, "index.html")
266 		repoList = append(repoList, &RepoItemData{
267 			URL:  url,
268 			Name: name,
269@@ -386,7 +438,7 @@ func main() {
270 	writeIndex(&IndexPage{
271 		RepoList: repoList,
272 	})
273-	for _, r := range repos {
274+	for _, r := range config.Repos {
275 		writeRepo(r)
276 	}
277 }