diff --git a/cmd/vanityserver/README.md b/cmd/vanityserver/README.md index 9dc5ee6..12439db 100644 --- a/cmd/vanityserver/README.md +++ b/cmd/vanityserver/README.md @@ -5,9 +5,12 @@ Runs a barebones vanity server over HTTP. ## Usage ``` -./vanityserver fqdn [repo file] +./vanityserver [-index] fqdn [repo file] ``` +The "-index" flag enables an index page at "/" that lists all repos hosted on +this server. + If repo file is not given, "./repos" is used. The file has the following format: ``` diff --git a/cmd/vanityserver/main.go b/cmd/vanityserver/main.go index 3ea716c..d0970d7 100644 --- a/cmd/vanityserver/main.go +++ b/cmd/vanityserver/main.go @@ -5,7 +5,10 @@ package main // go.jonnrb.io/vanity import ( "bufio" + "bytes" + "flag" "fmt" + "html/template" "io" "log" "net/http" @@ -17,6 +20,10 @@ import ( "go.jonnrb.io/vanity" ) +var ( + showIndex = flag.Bool("index", false, "Show a list of repos at /") +) + var host string func serveRepo(mux *http.ServeMux, root string, u *url.URL) { @@ -41,6 +48,8 @@ func serveRepo(mux *http.ServeMux, root string, u *url.URL) { } func buildMux(mux *http.ServeMux, r io.Reader) { + indexMap := map[string]string{} + sc := bufio.NewScanner(r) for sc.Scan() { fields := strings.Fields(sc.Text()) @@ -53,6 +62,10 @@ func buildMux(mux *http.ServeMux, r io.Reader) { log.Fatalf("Expected line of form \"path vcsScheme://vcsHost/user/repo\" but got %q", sc.Text()) } + if *showIndex { + indexMap[fields[0]] = fields[1] + } + path := fields[0] u, err := url.Parse(fields[1]) if err != nil { @@ -61,18 +74,62 @@ func buildMux(mux *http.ServeMux, r io.Reader) { serveRepo(mux, path, u) } + + if !*showIndex { + return + } + + var b bytes.Buffer + err := template.Must(template.New("").Parse(` + +{{ $host := .Host }} +

{{ html $host }}

+{{ range $root, $repo := .IndexMap }} + + + +{{ else }} +Nothing here. +{{ end }} +
{{ html $root }}{{ html $repo }}
+`)).Execute(&b, struct { + IndexMap map[string]string + Host string + }{ + IndexMap: indexMap, + Host: host, + }) + if err != nil { + log.Fatalf("Couldn't create index page: %v", err) + } + buf := b.Bytes() + + mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/" { + http.NotFound(w, r) + return + } + + io.Copy(w, bytes.NewReader(buf)) + })) } func main() { - if len(os.Args) < 2 { + flag.Usage = func() { fmt.Fprintf(os.Stderr, "usage: %s fqdn [repos file]", os.Args[0]) + flag.PrintDefaults() + } + flag.Parse() + + host = flag.Arg(0) + if host == "" { + flag.Usage() os.Exit(-1) } - host = os.Args[1] reposPath := "repos" - if len(os.Args) > 2 { - reposPath = os.Args[2] + if override := flag.Arg(1); override != "" { + reposPath = override } mux := http.NewServeMux()