all repos — elgit @ f41c7baefd86bf8db0e5f096c449997d9427f813

fork of legit: web frontend for git, written in go

configure golangci-lint

Alan Pearce
commit

f41c7baefd86bf8db0e5f096c449997d9427f813

parent

721a55a5b5ab180d4828e8de8175b24ca8d244f3

A .golangci.yaml
@@ -0,0 +1,65 @@
+--- +# yamllint disable-line rule:line-length +# yaml-language-server: $schema=https://golangci-lint.run/jsonschema/golangci.jsonschema.json +version: "2" +linters: + enable: + - errcheck + - gocritic + - godox + - gosec + - grouper + - lll + - nilerr + - nlreturn + - noctx + - nosprintfhostport + - paralleltest + - prealloc + - reassign + - revive + - sloglint + - unconvert + settings: + gosec: + excludes: + - G115 + paralleltest: + ignore-missing: true + wrapcheck: + ignore-sigs: + - .Errorf( + - errors.New( + - errors.Unwrap( + - errors.Join( + - fault.New( + - fault.Newf( + - fault.Wrap( + - (context.Context).Err( + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - linters: + - revive + path: templates + text: dot-imports + - linters: + - staticcheck + path: templates + text: dot imports + paths: + - third_party$ + - builtin$ + - examples$ +formatters: + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$
M data/entries.godata/entries.go
@@ -32,6 +32,7 @@ Name: r.Name,
LastCommit: r.LastCommit, Repositories: []*Repository{&r}, }) + return } t, ok := ent.Map[r.Category]
@@ -42,6 +43,7 @@ LastCommit: r.LastCommit,
Repositories: []*Repository{&r}, } ent.Map[r.Category] = t + return }
M git/git.gogit/git.go
@@ -108,6 +108,7 @@ return nil, fmt.Errorf("resolving rev %s for %s: %w", ref, path, err)
} g.h = *hash } + return &g, nil }
@@ -120,6 +121,7 @@
commitRefs := []*CommitReference{} err = ci.ForEach(func(c *object.Commit) error { commitRefs = append(commitRefs, &CommitReference{Commit: c}) + return nil }) if err != nil {
@@ -148,6 +150,7 @@ default:
return err } } + return nil }); err != nil { return nil, err
@@ -239,6 +242,7 @@ })
default: return err } + return nil }); err != nil { return nil, err
@@ -246,6 +250,7 @@ }
tagList := &TagList{r: g.r, refs: tags} sort.Sort(tagList) + return tags, nil }
@@ -259,6 +264,7 @@ branches := []*plumbing.Reference{}
_ = bi.ForEach(func(ref *plumbing.Reference) error { branches = append(branches, ref) + return nil })
@@ -272,6 +278,7 @@ if err == nil {
return b, nil } } + return "", fmt.Errorf("unable to find main branch") }
@@ -365,6 +372,7 @@ mode = fs.ModeDir | fs.ModePerm
} fullname := path.Join(prefix, name) + return &infoWrapper{ name: fullname, size: size,
@@ -406,6 +414,7 @@ func (t *TagReference) Message() string {
if t.tag != nil { return t.tag.Message } + return "" }
M git/service/service.gogit/service/service.go
@@ -35,22 +35,26 @@ cmd.Stderr = cmd.Stdout
if err := cmd.Start(); err != nil { log.Printf("git: failed to start git-upload-pack (info/refs): %s", err) + return err } if err := packLine(c.Stdout, "# service=git-upload-pack\n"); err != nil { log.Printf("git: failed to write pack line: %s", err) + return err } if err := packFlush(c.Stdout); err != nil { log.Printf("git: failed to flush pack: %s", err) + return err } buf := bytes.Buffer{} if _, err := io.Copy(&buf, stdoutPipe); err != nil { log.Printf("git: failed to copy stdout to tmp buffer: %s", err) + return err }
@@ -58,6 +62,7 @@ if err := cmd.Wait(); err != nil {
out := strings.Builder{} _, _ = io.Copy(&out, &buf) log.Printf("git: failed to run git-upload-pack; err: %s; output: %s", err, out.String()) + return err }
@@ -100,20 +105,24 @@ }()
if err := cmd.Start(); err != nil { log.Printf("git: failed to start git-upload-pack: %s", err) + return err } if _, err := io.Copy(stdinPipe, c.Stdin); err != nil { log.Printf("git: failed to copy stdin: %s", err) + return err } if _, err := io.Copy(newWriteFlusher(c.Stdout), stdoutPipe); err != nil { log.Printf("git: failed to copy stdout: %s", err) + return err } if err := cmd.Wait(); err != nil { log.Printf("git: failed to wait for git-upload-pack: %s", err) + return err }
@@ -122,10 +131,12 @@ }
func packLine(w io.Writer, s string) error { _, err := fmt.Fprintf(w, "%04x%s", len(s)+4, s) + return err } func packFlush(w io.Writer) error { _, err := fmt.Fprint(w, "0000") + return err }
M git/service/write_flusher.gogit/service/write_flusher.go
@@ -21,5 +21,6 @@ }
func (w writeFlusher) Write(p []byte) (int, error) { defer w.wf.Flush() + return w.wf.Write(p) }
M main.gomain.go
@@ -7,6 +7,7 @@ "log"
"net" "net/http" "strconv" + "time" "alin.ovh/elgit/config" "alin.ovh/elgit/routes"
@@ -34,5 +35,10 @@
mux := routes.Handlers(c, staticFiles) addr := net.JoinHostPort(c.Server.Host, strconv.FormatInt(int64(c.Server.Port), 10)) log.Println("starting server on", addr) - log.Fatal(http.ListenAndServe(addr, mux)) + srv := http.Server{ + Addr: addr, + Handler: mux, + ReadHeaderTimeout: time.Second * 5, + } + log.Fatal(srv.ListenAndServe()) }
M routes/git.goroutes/git.go
@@ -16,6 +16,7 @@ repo, err := d.GetCleanPath(name)
if err != nil { log.Printf("getcleanpath error: %v", err) d.Write404(w) + return }
@@ -31,6 +32,7 @@
if err := cmd.InfoRefs(); err != nil { http.Error(w, err.Error(), 500) log.Printf("git: failed to execute git-upload-pack (info/refs) %s", err) + return } }
@@ -42,6 +44,7 @@ repo, err := d.GetCleanPath(name)
if err != nil { log.Printf("getcleanpath error: %v", err) d.Write404(w) + return }
@@ -63,6 +66,7 @@ reader, err = gzip.NewReader(r.Body)
if err != nil { http.Error(w, err.Error(), 500) log.Printf("git: failed to create gzip reader: %s", err) + return } defer func() {
@@ -77,6 +81,7 @@ cmd.Stdin = reader
if err := cmd.UploadPack(); err != nil { http.Error(w, err.Error(), 500) log.Printf("git: failed to execute git-upload-pack %s", err) + return } }
M routes/routes.goroutes/routes.go
@@ -22,7 +22,7 @@ c *config.Config
projects []string } -func (d *deps) Index(w http.ResponseWriter, r *http.Request, params map[string]string) { +func (d *deps) Index(w http.ResponseWriter, _ *http.Request, _ map[string]string) { repos := d.getAllRepos() pageData := templates.PageData{
@@ -31,27 +31,31 @@ }
if err := templates.IndexPage(pageData, repos).Render(w); err != nil { log.Println(err) + return } } -func (d *deps) RepoIndex(w http.ResponseWriter, r *http.Request, params map[string]string) { +func (d *deps) RepoIndex(w http.ResponseWriter, _ *http.Request, params map[string]string) { name := path.Join(params["category"], params["name"]) if d.isNotAllowed(name) { d.Write404(w) + return } path, err := d.GetCleanPath(name) if err != nil { log.Printf("getcleanpath error: %v", err) d.Write404(w) + return } gr, err := git.Open(path, "") if err != nil { d.Write404(w) + return }
@@ -59,6 +63,7 @@ commits, err := gr.Commits()
if err != nil { d.Write500(w) log.Println(err) + return }
@@ -79,6 +84,7 @@ default:
safe := bluemonday.UGCPolicy().SanitizeBytes([]byte(content)) readmeContent = fmt.Sprintf(`<pre>%s</pre>`, safe) } + break } }
@@ -87,6 +93,7 @@ mainBranch, err := gr.FindMainBranch(d.c.Repo.MainBranch)
if err != nil { d.Write500(w) log.Println(err) + return }
@@ -109,10 +116,11 @@ log.Println(err)
} } -func (d *deps) RepoTree(w http.ResponseWriter, r *http.Request, params map[string]string) { +func (d *deps) RepoTree(w http.ResponseWriter, _ *http.Request, params map[string]string) { name := path.Join(params["category"], params["name"]) if d.isNotAllowed(name) { d.Write404(w) + return } treePath := strings.TrimSuffix(params["rest"], "/")
@@ -122,11 +130,13 @@ path, err := d.GetCleanPath(name)
if err != nil { log.Printf("getcleanpath error: %v", err) d.Write404(w) + return } gr, err := git.Open(path, ref) if err != nil { d.Write404(w) + return }
@@ -134,6 +144,7 @@ files, err := gr.FileTree(treePath)
if err != nil { d.Write500(w) log.Println(err, treePath) + return }
@@ -157,6 +168,7 @@
name := path.Join(params["category"], params["name"]) if d.isNotAllowed(name) { d.Write404(w) + return } treePath := params["rest"]
@@ -166,18 +178,21 @@ path, err := d.GetCleanPath(name)
if err != nil { log.Printf("getcleanpath error: %v", err) d.Write404(w) + return } gr, err := git.Open(path, ref) if err != nil { d.Write404(w) + return } contents, err := gr.FileContent(treePath) if err != nil { d.Write500(w) + return } data := make(map[string]any)
@@ -198,25 +213,25 @@ }
} } -func (d *deps) Archive(w http.ResponseWriter, r *http.Request, params map[string]string) { +func (d *deps) Archive(w http.ResponseWriter, _ *http.Request, params map[string]string) { name := path.Join(params["category"], params["name"]) if d.isNotAllowed(name) { d.Write404(w) + return } file := params["file"] - // TODO: extend this to add more files compression (e.g.: xz) if !strings.HasSuffix(file, ".tar.gz") { d.Write404(w) + return } ref := strings.TrimSuffix(file, ".tar.gz") - // This allows the browser to use a proper name for the file when - // downloading + // This allows the browser to use a proper name for the file when downloading filename := fmt.Sprintf("%s-%s.tar.gz", name, ref) setContentDisposition(w, filename) setGZipMIME(w)
@@ -225,17 +240,24 @@ path, err := d.GetCleanPath(name)
if err != nil { log.Printf("getcleanpath error: %v", err) d.Write404(w) + return } gr, err := git.Open(path, ref) if err != nil { d.Write404(w) + return } gw := gzip.NewWriter(w) - defer gw.Close() + defer func() { + err := gw.Close() + if err != nil { + log.Printf("failed to close gzip writer: %s", err) + } + }() prefix := fmt.Sprintf("%s-%s", name, ref) err = gr.WriteTar(gw, prefix)
@@ -243,6 +265,7 @@ if err != nil {
// once we start writing to the body we can't report error anymore // so we are only left with printing the error. log.Println(err) + return }
@@ -251,14 +274,16 @@ if err != nil {
// once we start writing to the body we can't report error anymore // so we are only left with printing the error. log.Println(err) + return } } -func (d *deps) Log(w http.ResponseWriter, r *http.Request, params map[string]string) { +func (d *deps) Log(w http.ResponseWriter, _ *http.Request, params map[string]string) { name := path.Join(params["category"], params["name"]) if d.isNotAllowed(name) { d.Write404(w) + return } ref := params["ref"]
@@ -267,12 +292,14 @@ path, err := d.GetCleanPath(name)
if err != nil { log.Printf("getcleanpath error: %v", err) d.Write404(w) + return } gr, err := git.Open(path, ref) if err != nil { d.Write404(w) + return }
@@ -280,6 +307,7 @@ commits, err := gr.Commits()
if err != nil { d.Write500(w) log.Println(err) + return }
@@ -294,14 +322,16 @@ }
if err := templates.LogPage(pageData, commits).Render(w); err != nil { log.Println(err) + return } } -func (d *deps) Diff(w http.ResponseWriter, r *http.Request, params map[string]string) { +func (d *deps) Diff(w http.ResponseWriter, _ *http.Request, params map[string]string) { name := path.Join(params["category"], params["name"]) if d.isNotAllowed(name) { d.Write404(w) + return } ref := params["ref"]
@@ -310,11 +340,13 @@ path, err := d.GetCleanPath(name)
if err != nil { log.Printf("getcleanpath error: %v", err) d.Write404(w) + return } gr, err := git.Open(path, ref) if err != nil { d.Write404(w) + return }
@@ -322,6 +354,7 @@ diff, err := gr.Diff()
if err != nil { d.Write500(w) log.Println(err) + return }
@@ -337,15 +370,17 @@ }
if err := templates.CommitPage(pageData, diff).Render(w); err != nil { log.Println(err) + return } } // FileDiff shows the changes to a specific file in a commit -func (d *deps) FileDiff(w http.ResponseWriter, r *http.Request, params map[string]string) { +func (d *deps) FileDiff(w http.ResponseWriter, _ *http.Request, params map[string]string) { name := path.Join(params["category"], params["name"]) if d.isNotAllowed(name) { d.Write404(w) + return } ref := params["ref"]
@@ -355,6 +390,7 @@ path, err := d.GetCleanPath(name)
if err != nil { log.Printf("getcleanpath error: %v", err) d.Write404(w) + return }
@@ -362,6 +398,7 @@ g, err := git.Open(path, ref)
if err != nil { log.Printf("git open error: %v", err) d.Write404(w) + return }
@@ -369,6 +406,7 @@ diff, err := g.DiffFile(filePath)
if err != nil { log.Printf("git diff error: %v", err) d.Write500(w) + return }
@@ -388,10 +426,11 @@ d.Write500(w)
} } -func (d *deps) Refs(w http.ResponseWriter, r *http.Request, params map[string]string) { +func (d *deps) Refs(w http.ResponseWriter, _ *http.Request, params map[string]string) { name := path.Join(params["category"], params["name"]) if d.isNotAllowed(name) { d.Write404(w) + return }
@@ -399,12 +438,14 @@ path, err := d.GetCleanPath(name)
if err != nil { log.Printf("getcleanpath error: %v", err) d.Write404(w) + return } gr, err := git.Open(path, "") if err != nil { d.Write404(w) + return }
@@ -418,6 +459,7 @@ branches, err := gr.Branches()
if err != nil { log.Println(err) d.Write500(w) + return }
@@ -430,6 +472,7 @@ }
if err := templates.RefsPage(pageData, branches, tags).Render(w); err != nil { log.Println(err) + return } }
M routes/template.goroutes/template.go
@@ -7,11 +7,11 @@ "log"
"net/http" "strings" + "alin.ovh/elgit/git" + "alin.ovh/elgit/templates" "github.com/alecthomas/chroma/v2/formatters/html" "github.com/alecthomas/chroma/v2/lexers" "github.com/alecthomas/chroma/v2/styles" - "alin.ovh/elgit/git" - "alin.ovh/elgit/templates" ) func (d *deps) Write404(w http.ResponseWriter) {
@@ -60,6 +60,7 @@ }
if err := templates.TreePage(pageData, files, readme, dotdot).Render(w); err != nil { log.Println(err) + return } }
@@ -83,6 +84,7 @@ /* handle last line not having a newline at the end */
if bufLen >= 1 && buf[(bufLen-1)%(32*1024)] != '\n' { count++ } + return count, nil case err != nil: return 0, err
@@ -113,6 +115,7 @@
iterator, err := lexer.Tokenise(nil, content) if err != nil { d.Write500(w) + return }
@@ -120,6 +123,7 @@ var code bytes.Buffer
err = formatter.Format(&code, style, iterator) if err != nil { d.Write500(w) + return }
@@ -135,6 +139,7 @@ }
if err := templates.FilePage(pageData, true).Render(w); err != nil { log.Println(err) + return } }
@@ -166,6 +171,7 @@ }
if err := templates.FilePage(pageData, false).Render(w); err != nil { log.Println(err) + return } }
M routes/util.goroutes/util.go
@@ -9,14 +9,15 @@ "path/filepath"
"slices" "strings" + "alin.ovh/elgit/data" + "alin.ovh/elgit/git" securejoin "github.com/cyphar/filepath-securejoin" "github.com/dimfeld/httptreemux/v5" - "alin.ovh/elgit/data" - "alin.ovh/elgit/git" ) func isGoModule(gr *git.GitRepo) bool { _, err := gr.FileContent("go.mod") + return err == nil }
@@ -31,6 +32,7 @@ desc = string(db)
} else { desc = "" } + return }
M templates/commit.gotemplates/commit.go
@@ -4,12 +4,12 @@ import (
"fmt" "time" + "alin.ovh/elgit/git" + g "alin.ovh/gomponents" + . "alin.ovh/gomponents/html" "github.com/bluekeyes/go-gitdiff/gitdiff" "github.com/dustin/go-humanize" "github.com/go-git/go-git/v5/plumbing/object" - "alin.ovh/elgit/git" - g "alin.ovh/gomponents" - . "alin.ovh/gomponents/html" ) // CommitPage renders a commit diff page
@@ -90,7 +90,7 @@ ),
g.If(d.IsBinary, P(g.Text("Not showing binary file.")), Pre( - g.Group(g.Map(d.TextFragments, func(tf git.TextFragment) g.Node { + g.Map(d.TextFragments, func(tf git.TextFragment) g.Node { return g.Group( []g.Node{ Header(Class("diff-hunk-header"), g.Text(tf.Header)),
@@ -105,7 +105,7 @@ return Span(Class("diff-noop"), g.Text(line.String()))
} }), }) - })), + }), ), ), ),
@@ -143,5 +143,6 @@ func pluralise(n int) string {
if n == 1 { return "" } + return "s" }
M templates/tree.gotemplates/tree.go
@@ -43,6 +43,7 @@ ),
), } } + return nil }), g.Map(files, func(file git.NiceTree) g.Node {
@@ -66,6 +67,7 @@ ),
), } } + return nil }), ),