aboutsummaryrefslogtreecommitdiffstats
path: root/repo/repo.go
diff options
context:
space:
mode:
Diffstat (limited to 'repo/repo.go')
-rw-r--r--repo/repo.go93
1 files changed, 93 insertions, 0 deletions
diff --git a/repo/repo.go b/repo/repo.go
new file mode 100644
index 0000000..2c052d6
--- /dev/null
+++ b/repo/repo.go
@@ -0,0 +1,93 @@
+package repo
+
+import (
+ "bytes"
+ _ "embed"
+ "fmt"
+ "html/template"
+ "net/http"
+ "strings"
+)
+
+//go:embed meta.html
+var tmplStr string
+
+type Repo struct {
+ VCS string `toml:"vcs"`
+ Repository string `toml:"repo"`
+ Home string `toml:"source,omitempty"`
+ Directory string `toml:"directory"`
+ File string `toml:"file"`
+}
+
+type RepoHandler struct {
+ Pages map[string][]byte
+}
+
+func New(repo map[string]Repo) (*RepoHandler, error) {
+ m, err := NewMeta()
+ if err != nil {
+ return nil, err
+ }
+ h := &RepoHandler{Pages: map[string][]byte{}}
+ for k, v := range repo {
+ if v.Home == "" {
+ v.Home = "_"
+ }
+
+ b, err := m.Exec(k, v)
+ if err != nil {
+ return nil, err
+ }
+ h.Pages[k] = b
+ }
+ return h, nil
+}
+
+func (h *RepoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ key := fmt.Sprintf("%s%s", r.Host, r.URL.Path)
+ key = strings.TrimSuffix(key, "/")
+
+ page, ok := h.Pages[key]
+ if !ok {
+ http.NotFound(w, r)
+ return
+ }
+
+ if r.FormValue("go-get") == "1" {
+ w.Header().Set("Cache-Control", "public, max-age=86400, immutable")
+ w.Header().Set("Vary", "Host")
+ w.Header().Set("Content-Type", "text/html")
+ w.Write(page)
+ } else {
+ url := fmt.Sprintf("https://pkg.go.dev/%s", key)
+ http.Redirect(w, r, url, http.StatusFound)
+ }
+}
+
+type Meta struct {
+ tmpl *template.Template
+}
+
+func NewMeta() (*Meta, error) {
+ tmpl, err := template.New("meta").Parse(tmplStr)
+ if err != nil {
+ return nil, err
+ }
+ return &Meta{tmpl: tmpl}, nil
+}
+
+func (m *Meta) Exec(pkg string, repo Repo) ([]byte, error) {
+ var buf bytes.Buffer
+ data := struct {
+ Package string
+ Repo
+ }{
+ Package: pkg,
+ Repo: repo,
+ }
+ if err := m.tmpl.Execute(&buf, data); err != nil {
+ return nil, fmt.Errorf("exec template for %v: %w", pkg, err)
+ }
+ return buf.Bytes(), nil
+}