- commit
- 7338b44
- parent
- c5d9c3c
- author
- Eric Bower
- date
- 2025-03-28 10:47:13 -0400 EDT
feat: allow config `desc` to add a description box to index page refactor: consolidate docs page onto index This change will allow maintainers to add a description box to the top of their git-pr instance as an introduction to their service.
7 files changed,
+241,
-337
M
cfg.go
+2,
-0
1@@ -27,6 +27,7 @@ type GitCfg struct {
2 CreateRepo string `koanf:"create_repo"`
3 Theme string `koanf:"theme"`
4 TimeFormat string `koanf:"time_format"`
5+ Desc string `koanf:"desc"`
6 Logger *slog.Logger
7 }
8
9@@ -113,6 +114,7 @@ func NewGitCfg(logger *slog.Logger) *GitCfg {
10 "theme", out.Theme,
11 "time_format", out.TimeFormat,
12 "create_repo", out.CreateRepo,
13+ "desc", out.Desc,
14 )
15
16 for _, pubkey := range out.AdminsStr {
+1,
-0
1@@ -11,3 +11,4 @@ time_format = "2006-01-02"
2 # admin: only admins
3 # user: admins and users
4 create_repo = "user"
5+desc = ""
+1,
-1
1@@ -4,7 +4,7 @@ body {
2 }
3
4 pre {
5- font-size: 1rem;
6+ padding: var(--grid-height);
7 }
8
9 table, tr {
+0,
-283
1@@ -1,283 +0,0 @@
2-{{template "base" .}}
3-
4-{{define "title"}}git-pr{{end}}
5-
6-{{define "meta"}}
7-<link rel="alternate" type="application/atom+xml"
8- title="RSS feed for git collaboration server"
9- href="/rss" />
10-{{end}}
11-
12-{{define "body"}}
13-<header class="group">
14- <h1 class="text-2xl"><a href="/">DASHBOARD</a> / docs</h1>
15- <div>
16- <span>A pastebin supercharged for git collaboration</span> ·
17- <a href="https://github.com/picosh/git-pr">github</a> ·
18- <a href="https://youtu.be/d28Dih-BBUw">demo video</a>
19- </div>
20- <pre class="m-0">ssh {{.MetaData.URL}} help</pre>
21-</header>
22-
23-<main class="group">
24- <details>
25- <summary>Intro</summary>
26-
27- <div>
28- <p>
29- We are trying to build the simplest git collaboration tool. The goal is to make
30- self-hosting as simple as running an SSH server -- all without
31- sacrificing external collaborators time and energy.
32- </p>
33-
34- <blockquote>
35- <code>git format-patch</code> isn't the problem and pull requests aren't the solution.
36- </blockquote>
37-
38- <p>
39- We are combining mailing list and pull request workflows. In order to build the
40- simplest collaboration tool, we needed something as simple as generating patches
41- but the ease-of-use of pull requests.
42- </p>
43-
44- <p>
45- The goal is not to create another code forge, the goal is to create a very
46- simple self-hosted git solution with the ability to collaborate with external
47- contributors. All the code owner needs to setup a running git server:
48- </p>
49-
50- <ul><li>A single golang binary</li></ul>
51-
52- <div>
53- All an external contributor needs is:
54- </div>
55-
56- <ul>
57- <li>An SSH keypair</li>
58- <li>An SSH client</li>
59- </ul>
60-
61- <div>Then everyone subscribes to our RSS feeds to receive updates to patch requests.</div>
62-
63- <h2 class="text-xl">the problem</h2>
64-
65- <p>
66- Email is great as a decentralized system to send and receive changes (patchsets)
67- to a git repo. However, onboarding a new user to a mailing list, properly
68- setting up their email client, and then finally submitting the code contribution
69- is enough to make many developers give up. Further, because we are leveraging
70- the email protocol for collaboration, we are limited by its feature-set. For
71- example, it is not possible to make edits to emails, everyone has a different
72- client, those clients have different limitations around plain text email and
73- downloading patches from it.
74- </p>
75-
76- <p>
77- Github pull requests are easy to use, easy to edit, and easy to manage. The
78- downside is it forces the user to be inside their website to perform reviews.
79- For quick changes, this is great, but when you start reading code within a web
80- browser, there are quite a few downsides. At a certain point, it makes more
81- sense to review code inside your local development environment, IDE, etc. There
82- are tools and plugins that allow users to review PRs inside their IDE, but it
83- requires a herculean effort to make it usable.
84- </p>
85-
86- <p>
87- Further, self-hosted solutions that mimic a pull request require a lot of
88- infrastructure in order to manage it. A database, a web site connected to git,
89- admin management, and services to manage it all. Another big point of friction:
90- before an external user submits a code change, they first need to create an
91- account and then login. This adds quite a bit of friction for a self-hosted
92- solution, not only for an external contributor, but also for the code owner who
93- has to provision the infra. Often times they also have to fork the repo within
94- the code forge before submitting a PR. Then they never make a contribution ever
95- again and keep a forked repo around forever. That seems silly.
96- </p>
97-
98- <h2 class="text-xl">introducing patch requests (PR)</h2>
99-
100- <p>
101- Instead, we want to create a self-hosted git "server" that can handle sending
102- and receiving patches without the cumbersome nature of setting up email or the
103- limitations imposed by the email protocol. Further, we want the primary workflow
104- to surround the local development environment. Github is bringing the IDE to the
105- browser in order to support their workflow, we want to flip that idea on its
106- head by making code reviews a first-class citizen inside your local development
107- environment.
108- </p>
109-
110- <p>
111- We see this as a hybrid between the github workflow of a pull request and
112- sending and receiving patches over email.
113- </p>
114-
115- <p>
116- The basic idea is to leverage an SSH app to handle most of the interaction
117- between contributor and owner of a project. Everything can be done completely
118- within the terminal, in a way that is ergonomic and fully featured.
119- </p>
120-
121- <p>
122- Notifications would happen with RSS and all state mutations would result in the
123- generation of static web assets so it can all be hosted using a simple file web
124- server.
125- </p>
126-
127- <h3 class="text-lg">format-patch workflow</h3>
128-
129- <p>
130- The fundamental collaboration tool here is <code>format-patch</code>. Whether you a
131- submitting code changes or you are reviewing code changes, it all happens in
132- code. Both contributor and owner are simply creating new commits and generating
133- patches on top of each other. This obviates the need to have a web viewer where
134- the reviewing can "comment" on a line of code block. There's no need, apply the
135- contributor's patches, write comments or code changes, generate a new patch,
136- send the patch to the git server as a "review." This flow also works the exact
137- same if two users are collaborating on a set of changes.
138- </p>
139-
140- <p>
141- This also solves the problem of sending multiple patchsets for the same code
142- change. There's a single, central Patch Request where all changes and
143- collaboration happens.
144- </p>
145-
146- <p>
147- We could figure out a way to leverage <code>git notes</code> for reviews / comments, but
148- honestly, that solution feels brutal and outside the comfort level of most git
149- users. Just send reviews as code and write comments in the programming language
150- you are using. It's the job of the contributor to "address" those comments and
151- then remove them in subsequent patches. This is the forcing function to address
152- all comments: the patch won't be merged if there are comment unaddressed in
153- code; they cannot be ignored or else they will be upstreamed erroneously.
154- </p>
155- </div>
156- </details>
157-
158- <details>
159- <summary>How do Patch Requests work?</summary>
160- <div>
161- Patch requests (PR) are the simplest way to submit, review, and accept changes to your git repository.
162- Here's how it works:
163- </div>
164-
165- <ol>
166- <li>External contributor clones repo (<code>git-clone</code>)</li>
167- <li>External contributor makes a code change (<code>git-add</code> & <code>git-commit</code>)</li>
168- <li>External contributor generates patches (<code>git-format-patch</code>)</li>
169- <li>External contributor submits a PR to SSH server</li>
170- <li>Owner receives RSS notification that there's a new PR</li>
171- <li>Owner applies patches locally (<code>git-am</code>) from SSH server</li>
172- <li>Owner makes suggestions in code! (<code>git-add</code> & <code>git-commit</code>)</li>
173- <li>Owner submits review by piping patch to SSH server (<code>git-format-patch</code>)</li>
174- <li>External contributor receives RSS notification of the PR review</li>
175- <li>External contributor re-applies patches (<code>git-am</code>)</li>
176- <li>External contributor reviews and removes comments in code!</li>
177- <li>External contributor submits another patch (<code>git-format-patch</code>)</li>
178- <li>Owner applies patches locally (<code>git-am</code>)</li>
179- <li>Owner marks PR as accepted and pushes code to main (<code>git-push</code>)</li>
180- </ol>
181-
182- <div>Example commands</div>
183-
184- <pre># Owner hosts repo `test.git` using github
185-
186-# Contributor clones repo
187-git clone git@github.com:picosh/test.git
188-
189-# Contributor wants to make a change
190-# Contributor makes changes via commits
191-git add -A && git commit -m "fix: some bugs"
192-
193-# Contributor runs:
194-git format-patch origin/main --stdout | ssh {{.MetaData.URL}} pr create test
195-# > Patch Request has been created (ID: 1)
196-
197-# Owner can checkout patch:
198-ssh {{.MetaData.URL}} pr print 1 | git am -3
199-# Owner can comment (IN CODE), commit, then send another format-patch
200-# on top of the PR:
201-git format-patch origin/main --stdout | ssh {{.MetaData.URL}} pr add --review 1
202-# UI clearly marks patch as a review
203-
204-# Contributor can checkout reviews
205-ssh {{.MetaData.URL}} pr print 1 | git am -3
206-
207-# Owner can reject a pr:
208-ssh {{.MetaData.URL}} pr close 1
209-
210-# Owner can accept a pr:
211-ssh {{.MetaData.URL}} pr accept 1
212-
213-# Owner can prep PR for upstream:
214-git rebase -i origin/main
215-
216-# Then push to upstream
217-git push origin main
218-
219-# Done!
220-</pre>
221- </details>
222-
223- <details>
224- <summary>What's a repo?</summary>
225-
226- <div>
227- A repo is designed to mimick a git repo, but it's really just a tag. When
228- submitting a patch request, if the user does not provide a repo name then
229- the default "bin" will be selected. When a user creates a repo they become
230- the repo owner and have special privileges.
231- </div>
232- </details>
233-
234- <details>
235- <summary>Can anyone use this service?</summary>
236-
237- <div>
238- This service is a public space for anyone to freely create "repos" and
239- collaborate with users. Anyone is able to add patchsets to a patch request
240- and anyone is able to review any other patch requests, regardless of repo.
241- </div>
242- </details>
243-
244- <details>
245- <summary>First time user experience</summary>
246-
247- <div>
248- Using this service for the first time? Creating a patch request is simple:
249- </div>
250-
251- <pre>git format-patch main --stdout | ssh pr.pico.sh pr create {repo}</pre>
252-
253- <div>When running that command we will automatically create a user and a repo if one doesn't exist.</div>
254-
255- <div>Want to submit a v2 of the patch request?</div>
256-
257- <pre>git format-patch main --stdout | ssh pr.pico.sh pr add {prID}</pre>
258- </details>
259-
260- <details>
261- <summary>How do I receive notifications?</summary>
262-
263- <div>
264- We have different RSS feeds depending on the use case. This is how you
265- can receive notifications for when someone submits or reviews patch requests.
266- </div>
267- </details>
268-
269- <details>
270- <summary>Alternative git collaboration systems</summary>
271-
272- <div>
273- <ol>
274- <li><a href="https://gerritcodereview.com/">Gerrit</a></li>
275- <li><a href="https://we.phorge.it/">Phorge</a> (fork of Phabricator)</li>
276- <li><a href="https://graphite.dev/docs/cli-quick-start">Graphite</a></li>
277- <li><a href="https://codeapprove.com/">CodeApprove</a></li>
278- <li><a href="https://reviewable.io/">Reviewable</a></li>
279- </ol>
280- </div>
281- </details>
282-</main>
283-
284-{{end}}
+215,
-19
1@@ -10,38 +10,234 @@
2
3 {{define "body"}}
4 <header class="group">
5- <h1 class="text-2xl">patchbin</h1>
6+ <h1 class="text-2xl">git-pr</h1>
7 <div>
8 <span>A pastebin supercharged for git collaboration</span> ·
9- <a href="/docs">docs</a>
10+ <a href="https://github.com/picosh/git-pr">github</a> ·
11+ <a href="https://youtu.be/d28Dih-BBUw">demo video</a>
12 </div>
13
14+ {{if .MetaData.Desc}}
15 <div class="box-sm">
16- <div>
17- Welcome to <a href="https://pico.sh">pico's</a> managed patchbin service!
18- This is a <strong>public</strong> service that is free to anyone who wants
19- to collaborate on git patches. The idea is simple: submit a patchset to
20- our service and let anyone collaborate on it by submitting follow-up patchsets.
21- Using this service for the first time? Creating a patch request is simple:
22- </div>
23+ <div>{{.MetaData.Desc}}</div>
24+ </div>
25+ {{end}}
26
27- <pre class="text-sm">git format-patch main --stdout | ssh pr.pico.sh pr create {repo}</pre>
28+ <details>
29+ <summary>Intro</summary>
30
31 <div>
32- When running that command we will automatically create a user and a repo
33- if one doesn't exist. Once the patches have been submitted you'll receive
34- a link that you can send to a reviewer. Anyone can review patch requests.
35- Want to submit a v2 of the patch request?
36+ <p>
37+ We are trying to build the simplest git collaboration tool. The goal is to make
38+ self-hosting as simple as running an SSH server -- all without
39+ sacrificing external collaborators time and energy.
40+ </p>
41+
42+ <blockquote>
43+ <code>git format-patch</code> isn't the problem and pull requests aren't the solution.
44+ </blockquote>
45+
46+ <p>
47+ We are combining mailing list and pull request workflows. In order to build the
48+ simplest collaboration tool, we needed something as simple as generating patches
49+ but the ease-of-use of pull requests.
50+ </p>
51+
52+ <p>
53+ The goal is not to create another code forge, the goal is to create a very
54+ simple self-hosted git solution with the ability to collaborate with external
55+ contributors. All the code owner needs to setup a running git server:
56+ </p>
57+
58+ <ul><li>A single golang binary</li></ul>
59+
60+ <div>
61+ All an external contributor needs is:
62+ </div>
63+
64+ <ul>
65+ <li>An SSH keypair</li>
66+ <li>An SSH client</li>
67+ </ul>
68+
69+ <p>Then everyone subscribes to our RSS feeds to receive updates to patch requests.</p>
70+
71+ <h2 class="text-xl">the problem</h2>
72+
73+ <p>
74+ Email is great as a decentralized system to send and receive changes (patchsets)
75+ to a git repo. However, onboarding a new user to a mailing list, properly
76+ setting up their email client, and then finally submitting the code contribution
77+ is enough to make many developers give up. Further, because we are leveraging
78+ the email protocol for collaboration, we are limited by its feature-set. For
79+ example, it is not possible to make edits to emails, everyone has a different
80+ client, those clients have different limitations around plain text email and
81+ downloading patches from it.
82+ </p>
83+
84+ <p>
85+ Github pull requests are easy to use, easy to edit, and easy to manage. The
86+ downside is it forces the user to be inside their website to perform reviews.
87+ For quick changes, this is great, but when you start reading code within a web
88+ browser, there are quite a few downsides. At a certain point, it makes more
89+ sense to review code inside your local development environment, IDE, etc. There
90+ are tools and plugins that allow users to review PRs inside their IDE, but it
91+ requires a herculean effort to make it usable.
92+ </p>
93+
94+ <p>
95+ Further, self-hosted solutions that mimic a pull request require a lot of
96+ infrastructure in order to manage it. A database, a web site connected to git,
97+ admin management, and services to manage it all. Another big point of friction:
98+ before an external user submits a code change, they first need to create an
99+ account and then login. This adds quite a bit of friction for a self-hosted
100+ solution, not only for an external contributor, but also for the code owner who
101+ has to provision the infra. Often times they also have to fork the repo within
102+ the code forge before submitting a PR. Then they never make a contribution ever
103+ again and keep a forked repo around forever. That seems silly.
104+ </p>
105+
106+ <h2 class="text-xl">introducing patch requests (PR)</h2>
107+
108+ <p>
109+ Instead, we want to create a self-hosted git "server" that can handle sending
110+ and receiving patches without the cumbersome nature of setting up email or the
111+ limitations imposed by the email protocol. Further, we want the primary workflow
112+ to surround the local development environment. Github is bringing the IDE to the
113+ browser in order to support their workflow, we want to flip that idea on its
114+ head by making code reviews a first-class citizen inside your local development
115+ environment.
116+ </p>
117+
118+ <p>
119+ We see this as a hybrid between the github workflow of a pull request and
120+ sending and receiving patches over email.
121+ </p>
122+
123+ <p>
124+ The basic idea is to leverage an SSH app to handle most of the interaction
125+ between contributor and owner of a project. Everything can be done completely
126+ within the terminal, in a way that is ergonomic and fully featured.
127+ </p>
128+
129+ <p>
130+ Notifications would happen with RSS and all state mutations would result in the
131+ generation of static web assets so it can all be hosted using a simple file web
132+ server.
133+ </p>
134+
135+ <h3 class="text-lg">format-patch workflow</h3>
136+
137+ <p>
138+ The fundamental collaboration tool here is <code>format-patch</code>. Whether you a
139+ submitting code changes or you are reviewing code changes, it all happens in
140+ code. Both contributor and owner are simply creating new commits and generating
141+ patches on top of each other. This obviates the need to have a web viewer where
142+ the reviewing can "comment" on a line of code block. There's no need, apply the
143+ contributor's patches, write comments or code changes, generate a new patch,
144+ send the patch to the git server as a "review." This flow also works the exact
145+ same if two users are collaborating on a set of changes.
146+ </p>
147+
148+ <p>
149+ This also solves the problem of sending multiple patchsets for the same code
150+ change. There's a single, central Patch Request where all changes and
151+ collaboration happens.
152+ </p>
153+
154+ <p>
155+ We could figure out a way to leverage <code>git notes</code> for reviews / comments, but
156+ honestly, that solution feels brutal and outside the comfort level of most git
157+ users. Just send reviews as code and write comments in the programming language
158+ you are using. It's the job of the contributor to "address" those comments and
159+ then remove them in subsequent patches. This is the forcing function to address
160+ all comments: the patch won't be merged if there are comment unaddressed in
161+ code; they cannot be ignored or else they will be upstreamed erroneously.
162+ </p>
163 </div>
164+ </details>
165+
166+ <details>
167+ <summary>How do Patch Requests work?</summary>
168+ <div>
169+ Patch requests (PR) are the simplest way to submit, review, and accept changes to your git repository.
170+ Here's how it works:
171+ </div>
172+
173+ <ol>
174+ <li>External contributor clones repo (<code>git-clone</code>)</li>
175+ <li>External contributor makes a code change (<code>git-add</code> & <code>git-commit</code>)</li>
176+ <li>External contributor generates patches (<code>git-format-patch</code>)</li>
177+ <li>External contributor submits a PR to SSH server</li>
178+ <li>Owner receives RSS notification that there's a new PR</li>
179+ <li>Owner applies patches locally (<code>git-am</code>) from SSH server</li>
180+ <li>Owner makes suggestions in code! (<code>git-add</code> & <code>git-commit</code>)</li>
181+ <li>Owner submits review by piping patch to SSH server (<code>git-format-patch</code>)</li>
182+ <li>External contributor receives RSS notification of the PR review</li>
183+ <li>External contributor re-applies patches (<code>git-am</code>)</li>
184+ <li>External contributor reviews and removes comments in code!</li>
185+ <li>External contributor submits another patch (<code>git-format-patch</code>)</li>
186+ <li>Owner applies patches locally (<code>git-am</code>)</li>
187+ <li>Owner marks PR as accepted and pushes code to main (<code>git-push</code>)</li>
188+ </ol>
189+
190+ <div>Example commands</div>
191+
192+ <pre># Owner hosts repo `test.git` using github
193+
194+# Contributor clones repo
195+git clone git@github.com:picosh/test.git
196+
197+# Contributor wants to make a change
198+# Contributor makes changes via commits
199+git add -A && git commit -m "fix: some bugs"
200+
201+# Contributor runs:
202+git format-patch origin/main --stdout | ssh {{.MetaData.URL}} pr create test
203+# > Patch Request has been created (ID: 1)
204+
205+# Owner can checkout patch:
206+ssh {{.MetaData.URL}} pr print 1 | git am -3
207+
208+# Owner can comment (IN CODE), commit, then send another format-patch
209+# on top of the PR:
210+git format-patch origin/main --stdout | ssh {{.MetaData.URL}} pr add --review 1
211+# UI clearly marks patch as a review
212
213- <pre class="text-sm">git format-patch main --stdout | ssh pr.pico.sh pr add {prID}</pre>
214+# Contributor can checkout reviews
215+ssh {{.MetaData.URL}} print pr-1 | git am -3
216+
217+# Owner can reject a pr:
218+ssh {{.MetaData.URL}} pr close 1
219+
220+# Owner can accept a pr:
221+ssh {{.MetaData.URL}} pr accept 1
222+
223+# Owner can prep PR for upstream:
224+git rebase -i origin/main
225+
226+# Then push to upstream
227+git push origin main
228+
229+# Done!
230+</pre>
231+ </details>
232+
233+ <details>
234+ <summary>First time user?</summary>
235
236 <div>
237- Downloading a patchset is easy as well:
238+ Using this service for the first time? Creating a patch request is simple:
239 </div>
240
241- <pre class="text-sm">ssh pr.pico.sh print pr-{prID}</pre>
242- </div>
243+ <pre>git format-patch main --stdout | ssh {{.MetaData.URL}} pr create {repo}</pre>
244+
245+ <div>When running that command we will automatically create a user and a repo if one doesn't exist.</div>
246+
247+ <div>Want to submit a v2 of the patch request?</div>
248+
249+ <pre>git format-patch main --stdout | ssh {{.MetaData.URL}} pr add {prID}</pre>
250+ </details>
251 </header>
252
253 <main>
254@@ -57,6 +253,6 @@
255 </main>
256
257 <footer class="mt">
258- <div><a href="/rss">rss</a></div>
259+ <a href="/rss">rss</a>
260 </footer>
261 {{end}}
+17,
-12
1@@ -17,18 +17,23 @@
2 <details>
3 <summary>Help</summary>
4 <div class="group">
5- <pre class="m-0"># checkout latest patchset
6-ssh {{.MetaData.URL}} print pr-{{.Pr.ID}} | git am -3</pre>
7- <pre class="m-0"># checkout any patchset in a patch request
8-ssh {{.MetaData.URL}} print ps-X | git am -3</pre>
9- <pre class="m-0"># add changes to patch request
10-git format-patch {{.Branch}} --stdout | ssh {{.MetaData.URL}} pr add {{.Pr.ID}}</pre>
11- <pre class="m-0"># add review to patch request
12-git format-patch {{.Branch}} --stdout | ssh {{.MetaData.URL}} pr add --review {{.Pr.ID}}</pre>
13- <pre class="m-0"># accept PR
14-ssh {{.MetaData.URL}} pr accept {{.Pr.ID}}</pre>
15- <pre class="m-0"># close PR
16-ssh {{.MetaData.URL}} pr close {{.Pr.ID}}</pre>
17+ checkout latest patchset:
18+ <pre class="m-0">ssh {{.MetaData.URL}} print pr-{{.Pr.ID}} | git am -3</pre>
19+
20+ checkout any patchset in a patch request:
21+ <pre class="m-0">ssh {{.MetaData.URL}} print ps-X | git am -3</pre>
22+
23+ add changes to patch request:
24+ <pre class="m-0">git format-patch {{.Branch}} --stdout | ssh {{.MetaData.URL}} pr add {{.Pr.ID}}</pre>
25+
26+ add review to patch request:
27+ <pre class="m-0">git format-patch {{.Branch}} --stdout | ssh {{.MetaData.URL}} pr add --review {{.Pr.ID}}</pre>
28+
29+ accept PR:
30+ <pre class="m-0">ssh {{.MetaData.URL}} pr accept {{.Pr.ID}}</pre>
31+
32+ close PR:
33+ <pre class="m-0">ssh {{.MetaData.URL}} pr close {{.Pr.ID}}</pre>
34 </div>
35 </details>
36 </header>
M
web.go
+5,
-22
1@@ -287,25 +287,6 @@ func getPrTableData(web *WebCtx, prs []*PatchRequest, query url.Values) ([]*PrLi
2 return prdata, nil
3 }
4
5-func docsHandler(w http.ResponseWriter, r *http.Request) {
6- web, err := getWebCtx(r)
7- if err != nil {
8- w.WriteHeader(http.StatusInternalServerError)
9- return
10- }
11-
12- w.Header().Set("content-type", "text/html")
13- tmpl := getTemplate("docs.html")
14- err = tmpl.ExecuteTemplate(w, "docs.html", BasicData{
15- MetaData: MetaData{
16- URL: web.Backend.Cfg.Url,
17- },
18- })
19- if err != nil {
20- web.Backend.Logger.Error("cannot execute template", "err", err)
21- }
22-}
23-
24 func indexHandler(w http.ResponseWriter, r *http.Request) {
25 web, err := getWebCtx(r)
26 if err != nil {
27@@ -349,7 +330,8 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
28 NumClosed: numClosed,
29 Prs: prdata,
30 MetaData: MetaData{
31- URL: web.Backend.Cfg.Url,
32+ URL: web.Backend.Cfg.Url,
33+ Desc: template.HTML(web.Backend.Cfg.Desc),
34 },
35 })
36 if err != nil {
37@@ -366,7 +348,8 @@ type UserData struct {
38 }
39
40 type MetaData struct {
41- URL string
42+ URL string
43+ Desc template.HTML
44 }
45
46 type PrListData struct {
47@@ -1122,6 +1105,7 @@ func StartWebServer(cfg *GitCfg) {
48 }
49 formatter := formatterHtml.New(
50 formatterHtml.WithLineNumbers(true),
51+ formatterHtml.LineNumbersInTable(true),
52 formatterHtml.WithClasses(true),
53 formatterHtml.WithLinkableLineNumbers(true, "gitpr"),
54 )
55@@ -1147,7 +1131,6 @@ func StartWebServer(cfg *GitCfg) {
56 http.HandleFunc("GET /r/{user}", ctxMdw(ctx, userDetailHandler))
57 http.HandleFunc("GET /rss/{user}", ctxMdw(ctx, rssHandler))
58 http.HandleFunc("GET /rss", ctxMdw(ctx, rssHandler))
59- http.HandleFunc("GET /docs", ctxMdw(ctx, docsHandler))
60 http.HandleFunc("GET /", ctxMdw(ctx, indexHandler))
61 http.HandleFunc("GET /syntax.css", ctxMdw(ctx, chromaStyleHandler))
62 embedFS, err := getEmbedFS(embedStaticFS, "static")