git-pr

created pr with 3.1 on 2024-07-19T14:53:23Z · by c8ef7d19
added 3.2 on 2024-07-19T14:55:48Z · by c8ef7d19
1: 3b99dc0 < -: ------- feat: static assets
2: 8919af5 ! 1: 66cafc6 feat: static assets folder
3: 7346122 ! 2: 5e76ed3 fix(cli): access control for removing patchsets
4: d8792d5 < -: ------- feat: static folder
pr_reviewed on 2024-07-19T15:42:29Z · by 964fa508
changed status to reviewed on 2024-07-19T15:42:29Z · by 964fa508
added 3.4 on 2024-07-19T17:43:47Z · by c8ef7d19
1: cc56ea1 = 1: 0467f9e feat: static assets folder
2: ef749a4 = 2: da1730f review: typo and future enhancement comment
-: ------- > 3: c038404 refactor: per-file override for static folder
changed status to accepted on 2024-07-19T18:27:53Z · by 964fa508
cmds
checkout latest patchset:
ssh pr.pico.sh print 3 | git am -3
checkout any patchset in a patch request:
ssh pr.pico.sh print 3.[rev] | git am -3
add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add 3
set PR to open (enables RSS notifications):
ssh pr.pico.sh pr open 3
set PR to draft (stops RSS notifications):
ssh pr.pico.sh pr draft 3
+4 -0 Makefile #
......@@ -26,3 +26,7 @@ bp: bp-setup
2626 $(DOCKER_BUILDX_BUILD) -t "ghcr.io/picosh/pico/git-ssh:$(DOCKER_TAG)" --target release-ssh .
2727 $(DOCKER_BUILDX_BUILD) -t "ghcr.io/picosh/pico/git-web:$(DOCKER_TAG)" --target release-web .
2828 .PHONY: bp
29+
30+smol:
31+ curl https://pico.sh/smol.css -o ./static/smol.css
32+.PHONY: smol
+57 -0 web.go #
......@@ -6,8 +6,11 @@ import (
66 "embed"
77 "fmt"
88 "html/template"
9+ "io"
10+ "io/fs"
911 "log/slog"
1012 "net/http"
13+ "os"
1114 "path/filepath"
1215 "slices"
1316 "strconv"
......@@ -23,6 +26,9 @@ import (
2326 //go:embed tmpl/*
2427 var tmplFS embed.FS
2528
29+//go:embed static/*
30+var staticFS embed.FS
31+
2632 type WebCtx struct {
2733 Pr *PrCmd
2834 Backend *Backend
......@@ -618,6 +624,49 @@ func chromaStyleHandler(w http.ResponseWriter, r *http.Request) {
618624 }
619625 }
620626
627+func serveFile(staticfs fs.FS) func(w http.ResponseWriter, r *http.Request) {
628+ return func(w http.ResponseWriter, r *http.Request) {
629+ web, err := getWebCtx(r)
630+ if err != nil {
631+ w.WriteHeader(http.StatusUnprocessableEntity)
632+ return
633+ }
634+ logger := web.Logger
635+
636+ file := r.PathValue("file")
637+ reader, err := staticfs.Open(file)
638+ if err != nil {
639+ logger.Error(err.Error())
640+ http.Error(w, "file not found", 404)
641+ return
642+ }
643+ contents, err := io.ReadAll(reader)
644+ if err != nil {
645+ logger.Error(err.Error())
646+ http.Error(w, "file not found", 404)
647+ return
648+ }
649+ contentType := http.DetectContentType(contents)
650+ w.Header().Add("Content-Type", contentType)
651+
652+ _, err = w.Write(contents)
653+ if err != nil {
654+ logger.Error(err.Error())
655+ http.Error(w, "server error", 500)
656+ return
657+ }
658+ }
659+}
660+
661+type StaticFs struct {
662+ Dir string
663+}
664+
665+func (fs *StaticFs) Open(name string) (os.File, error) {
666+ fp, err := os.Open(filepath.Join(fs.Dir, name))
667+ return *fp, err
668+}
669+
621670 func StartWebServer(cfg *GitCfg) {
622671 addr := fmt.Sprintf("%s:%s", cfg.Host, cfg.WebPort)
623672
......@@ -659,6 +708,14 @@ func StartWebServer(cfg *GitCfg) {
659708 http.HandleFunc("GET /", ctxMdw(ctx, repoListHandler))
660709 http.HandleFunc("GET /syntax.css", ctxMdw(ctx, chromaStyleHandler))
661710 http.HandleFunc("GET /rss", ctxMdw(ctx, rssHandler))
711+ dir := filepath.Join(cfg.DataDir, "static")
712+ var filesys fs.FS = staticFS
713+ _, err = os.Stat(dir)
714+ if err == nil {
715+ cfg.Logger.Info("detected static folder, using instead of the default one")
716+ filesys = os.DirFS(dir)
717+ }
718+ http.HandleFunc("GET /static/{file}", serveFile(filesys))
662719
663720 cfg.Logger.Info("starting web server", "addr", addr)
664721 err = http.ListenAndServe(addr, nil)
Back to top