- commit
- e19c0c4
- parent
- 8014989
- author
- Eric Bower
- date
- 2024-12-18 22:50:49 -0500 EST
feat: `--root-relative` flag to change the url for href links
5 files changed,
+71,
-53
+3,
-3
1@@ -10,9 +10,9 @@
2
3 {{template "meta" .}}
4
5- <link rel="stylesheet" href="/vars.css" />
6- <link rel="stylesheet" href="/smol.css" />
7- <link rel="stylesheet" href="/main.css" />
8+ <link rel="stylesheet" href="{{.Repo.RootRelative}}vars.css" />
9+ <link rel="stylesheet" href="{{.Repo.RootRelative}}smol.css" />
10+ <link rel="stylesheet" href="{{.Repo.RootRelative}}main.css" />
11 </head>
12 <body>
13 <header>{{template "header" .}}</header>
+1,
-1
1@@ -1,7 +1,7 @@
2 {{template "base" .}}
3 {{define "title"}}{{.Commit.Summary}} - {{.Repo.RepoName}}@{{.CommitID}}{{end}}
4 {{define "meta"}}
5-<link rel="stylesheet" href="/syntax.css" />
6+<link rel="stylesheet" href="{{.Repo.RootRelative}}syntax.css" />
7 {{end}}
8
9 {{define "content"}}
+1,
-1
1@@ -1,7 +1,7 @@
2 {{template "base" .}}
3 {{define "title"}}{{.Item.Path}}@{{.RevData.Name}}{{end}}
4 {{define "meta"}}
5-<link rel="stylesheet" href="/syntax.css" />
6+<link rel="stylesheet" href="{{.Repo.RootRelative}}syntax.css" />
7 {{end}}
8
9 {{define "content"}}
+1,
-1
1@@ -2,7 +2,7 @@
2
3 {{define "title"}}{{.Repo.RepoName}}{{if .Repo.Desc}}- {{.Repo.Desc}}{{end}}{{end}}
4 {{define "meta"}}
5-<link rel="stylesheet" href="/syntax.css" />
6+<link rel="stylesheet" href="{{.Repo.RootRelative}}syntax.css" />
7 {{end}}
8
9 {{define "content"}}
M
main.go
+65,
-47
1@@ -14,6 +14,7 @@ import (
2 "sort"
3 "strings"
4 "sync"
5+ "time"
6 "unicode/utf8"
7
8 "github.com/alecthomas/chroma/v2"
9@@ -52,6 +53,9 @@ type Config struct {
10 HomeURL template.URL
11 CloneURL template.URL
12
13+ // https://developer.mozilla.org/en-US/docs/Web/API/URL_API/Resolving_relative_references#root_relative
14+ RootRelative string
15+
16 // computed
17 // cache for skipping commits, trees, etc.
18 Cache map[string]bool
19@@ -73,8 +77,9 @@ type RevInfo interface {
20
21 // revision data
22 type RevData struct {
23- id string
24- name string
25+ id string
26+ name string
27+ Config *Config
28 }
29
30 func (r *RevData) ID() string {
31@@ -86,11 +91,11 @@ func (r *RevData) Name() string {
32 }
33
34 func (r *RevData) TreeURL() template.URL {
35- return getTreeURL(r)
36+ return r.Config.getTreeURL(r)
37 }
38
39 func (r *RevData) LogURL() template.URL {
40- return getLogsURL(r)
41+ return r.Config.getLogsURL(r)
42 }
43
44 type TagData struct {
45@@ -427,7 +432,7 @@ func (c *Config) writeHTMLTreeFile(pageData *PageData, treeItem *TreeItem) strin
46 Contents: template.HTML(contents),
47 Item: treeItem,
48 },
49- Subdir: getFileURL(pageData.RevData, d),
50+ Subdir: getFileDir(pageData.RevData, d),
51 })
52 return readme
53 }
54@@ -494,8 +499,8 @@ func (c *Config) writeLogDiff(repo *git.Repository, pageData *PageData, commit *
55 CommitID: getShortID(commitID),
56 Diff: rnd,
57 Parent: getShortID(commit.ParentID),
58- CommitURL: getCommitURL(commitID),
59- ParentURL: getCommitURL(commit.ParentID),
60+ CommitURL: c.getCommitURL(commitID),
61+ ParentURL: c.getCommitURL(commit.ParentID),
62 }
63
64 c.writeHtml(&WriteData{
65@@ -506,13 +511,13 @@ func (c *Config) writeLogDiff(repo *git.Repository, pageData *PageData, commit *
66 })
67 }
68
69-func getSummaryURL() template.URL {
70- url := "/index.html"
71+func (c *Config) getSummaryURL() template.URL {
72+ url := c.RootRelative + "index.html"
73 return template.URL(url)
74 }
75
76-func getRefsURL() template.URL {
77- url := "/refs.html"
78+func (c *Config) getRefsURL() template.URL {
79+ url := c.RootRelative + "refs.html"
80 return template.URL(url)
81 }
82
83@@ -537,24 +542,32 @@ func getFileBaseDir(info RevInfo) string {
84 return filepath.Join(getTreeBaseDir(info), "item")
85 }
86
87-func getFileURL(info RevInfo, fname string) string {
88+func getFileDir(info RevInfo, fname string) string {
89 return filepath.Join(getFileBaseDir(info), fname)
90 }
91
92-func getTreeURL(info RevInfo) template.URL {
93- dir := getTreeBaseDir(info)
94- url := filepath.Join(dir, "index.html")
95+func (c *Config) getFileURL(info RevInfo, fname string) template.URL {
96+ return c.compileURL(getFileBaseDir(info), fname)
97+}
98+
99+func (c *Config) compileURL(dir, fname string) template.URL {
100+ purl := c.RootRelative + strings.TrimPrefix(dir, "/")
101+ url := filepath.Join(purl, fname)
102 return template.URL(url)
103 }
104
105-func getLogsURL(info RevInfo) template.URL {
106+func (c *Config) getTreeURL(info RevInfo) template.URL {
107+ dir := getTreeBaseDir(info)
108+ return c.compileURL(dir, "index.html")
109+}
110+
111+func (c *Config) getLogsURL(info RevInfo) template.URL {
112 dir := getLogBaseDir(info)
113- url := filepath.Join(dir, "index.html")
114- return template.URL(url)
115+ return c.compileURL(dir, "index.html")
116 }
117
118-func getCommitURL(commitID string) template.URL {
119- url := fmt.Sprintf("/commits/%s.html", commitID)
120+func (c *Config) getCommitURL(commitID string) template.URL {
121+ url := fmt.Sprintf("%scommits/%s.html", c.RootRelative, commitID)
122 return template.URL(url)
123 }
124
125@@ -562,8 +575,8 @@ func (c *Config) getURLs() *SiteURLs {
126 return &SiteURLs{
127 HomeURL: c.HomeURL,
128 CloneURL: c.CloneURL,
129- RefsURL: getRefsURL(),
130- SummaryURL: getSummaryURL(),
131+ RefsURL: c.getRefsURL(),
132+ SummaryURL: c.getSummaryURL(),
133 }
134 }
135
136@@ -596,8 +609,9 @@ func (c *Config) writeRepo() *BranchOutput {
137 }
138
139 data := &RevData{
140- id: fullRevID,
141- name: revName,
142+ id: fullRevID,
143+ name: revName,
144+ Config: c,
145 }
146
147 if first == nil {
148@@ -673,8 +687,9 @@ func (c *Config) writeRepo() *BranchOutput {
149 // use the first revision in our list to generate
150 // the root summary, logs, and tree the user can click
151 revData := &RevData{
152- id: first.ID(),
153- name: first.Name(),
154+ id: first.ID(),
155+ name: first.Name(),
156+ Config: c,
157 }
158
159 data := &PageData{
160@@ -699,6 +714,7 @@ type TreeWalker struct {
161 HideTreeLastCommit bool
162 PageData *PageData
163 Repo *git.Repository
164+ Config *Config
165 }
166
167 type Breadcrumb struct {
168@@ -712,11 +728,9 @@ func (tw *TreeWalker) calcBreadcrumbs(curpath string) []*Breadcrumb {
169 return []*Breadcrumb{}
170 }
171 parts := strings.Split(curpath, string(os.PathSeparator))
172- rootURL := template.URL(
173- filepath.Join(
174- getTreeBaseDir(tw.PageData.RevData),
175- "index.html",
176- ),
177+ rootURL := tw.Config.compileURL(
178+ getTreeBaseDir(tw.PageData.RevData),
179+ "index.html",
180 )
181
182 crumbs := make([]*Breadcrumb, len(parts)+1)
183@@ -727,9 +741,11 @@ func (tw *TreeWalker) calcBreadcrumbs(curpath string) []*Breadcrumb {
184
185 cur := ""
186 for idx, d := range parts {
187+ crumb := filepath.Join(getFileBaseDir(tw.PageData.RevData), cur, d)
188+ crumbUrl := tw.Config.compileURL(crumb, "index.html")
189 crumbs[idx+1] = &Breadcrumb{
190 Text: d,
191- URL: template.URL(filepath.Join(getFileBaseDir(tw.PageData.RevData), cur, d, "index.html")),
192+ URL: crumbUrl,
193 }
194 if idx == len(parts)-1 {
195 crumbs[idx+1].IsLast = true
196@@ -775,7 +791,7 @@ func (tw *TreeWalker) NewTreeItem(entry *git.TreeEntry, curpath string, crumbs [
197 Name: entry.Name(),
198 Path: fname,
199 Entry: entry,
200- URL: template.URL(getFileURL(tw.PageData.RevData, fname)),
201+ URL: tw.Config.getFileURL(tw.PageData.RevData, fname),
202 Crumbs: crumbs,
203 }
204
205@@ -794,29 +810,28 @@ func (tw *TreeWalker) NewTreeItem(entry *git.TreeEntry, curpath string, crumbs [
206 if len(lastCommits) > 0 {
207 lc = lastCommits[0]
208 }
209- item.CommitURL = getCommitURL(lc.ID.String())
210+ item.CommitURL = tw.Config.getCommitURL(lc.ID.String())
211 item.CommitID = getShortID(lc.ID.String())
212 item.Summary = lc.Summary()
213- item.When = lc.Author.When.Format("02 Jan 06")
214+ item.When = lc.Author.When.Format(time.DateOnly)
215 item.Author = lc.Author
216 }
217
218- fpath := getFileURL(
219- tw.PageData.RevData,
220- fmt.Sprintf("%s.html", fname),
221- )
222+ fpath := tw.Config.getFileURL(tw.PageData.RevData, fmt.Sprintf("%s.html", fname))
223 if typ == git.ObjectTree {
224 item.IsDir = true
225- fpath = filepath.Join(
226- getFileBaseDir(tw.PageData.RevData),
227- curpath,
228- entry.Name(),
229+ fpath = tw.Config.compileURL(
230+ filepath.Join(
231+ getFileBaseDir(tw.PageData.RevData),
232+ curpath,
233+ entry.Name(),
234+ ),
235 "index.html",
236 )
237 } else if typ == git.ObjectBlob {
238 item.Icon = FilenameToDevIcon(item.Name)
239 }
240- item.URL = template.URL(fpath)
241+ item.URL = fpath
242
243 return item
244 }
245@@ -926,11 +941,11 @@ func (c *Config) writeRevision(repo *git.Repository, pageData *PageData, refs []
246 }
247 logs = append(logs, &CommitData{
248 ParentID: parentID,
249- URL: getCommitURL(commit.ID.String()),
250+ URL: c.getCommitURL(commit.ID.String()),
251 ShortID: getShortID(commit.ID.String()),
252 SummaryStr: commit.Summary(),
253 AuthorStr: commit.Author.Name,
254- WhenStr: commit.Author.When.Format("02 Jan 06"),
255+ WhenStr: commit.Author.When.Format(time.DateOnly),
256 Commit: commit,
257 Refs: tags,
258 })
259@@ -954,6 +969,7 @@ func (c *Config) writeRevision(repo *git.Repository, pageData *PageData, refs []
260 entries := make(chan *TreeItem)
261 subtrees := make(chan *TreeRoot)
262 tw := &TreeWalker{
263+ Config: c,
264 PageData: pageData,
265 Repo: repo,
266 treeItem: entries,
267@@ -1035,12 +1051,13 @@ func style(theme chroma.Style) string {
268 func main() {
269 var outdir = flag.String("out", "./public", "output directory")
270 var rpath = flag.String("repo", ".", "path to git repo")
271- var revsFlag = flag.String("revs", "HEAD", "list of revs to generate logs and tree (e.g. main,v1,c69f86f,HEAD")
272+ var revsFlag = flag.String("revs", "HEAD", "list of revs to generate logs and tree (e.g. main,v1,c69f86f,HEAD)")
273 var themeFlag = flag.String("theme", "dracula", "theme to use for site")
274 var labelFlag = flag.String("label", "", "pretty name for the subdir where we create the repo, default is last folder in --repo")
275 var cloneFlag = flag.String("clone-url", "", "git clone URL")
276 var homeFlag = flag.String("home-url", "", "URL for breadcumbs to get to list of repositories")
277 var descFlag = flag.String("desc", "", "description for repo")
278+ var rootRelativeFlag = flag.String("root-relative", "/", "html root relative")
279 var maxCommitsFlag = flag.Int("max-commits", 0, "maximum number of commits to generate")
280 var hideTreeLastCommitFlag = flag.Bool("hide-tree-last-commit", false, "dont calculate last commit for each file in the tree")
281
282@@ -1084,6 +1101,7 @@ func main() {
283 Desc: *descFlag,
284 MaxCommits: *maxCommitsFlag,
285 HideTreeLastCommit: *hideTreeLastCommitFlag,
286+ RootRelative: *rootRelativeFlag,
287 Formatter: formatter,
288 }
289 config.Logger.Info("config", "config", config)