Add "dev" mode

6167f6273a08d9e82c918ec8ae8cb285b687608d
Alexis Sellier committed ago 1 parent 59a04c99
discuss.go +15 -0
570 570
	pd := s.newPageData(r, nil, "forum", "")
571 571
	pd.Data = newDiscussionData{}
572 572
	s.tmpl.render(w, "discussion_new", pd)
573 573
}
574 574
575 +
const devHandle = "cloudhead.io"
576 +
577 +
func (s *server) handleDevLogin(w http.ResponseWriter, r *http.Request) {
578 +
	avatar := getAvatar(s.db, devHandle)
579 +
	if avatar != "" {
580 +
		upsertAvatar(s.db, devHandle, avatar)
581 +
	}
582 +
	setSessionCookie(w, devHandle)
583 +
	returnTo := r.URL.Query().Get("return")
584 +
	if returnTo == "" {
585 +
		returnTo = s.baseURL + "/"
586 +
	}
587 +
	http.Redirect(w, r, returnTo, http.StatusSeeOther)
588 +
}
589 +
575 590
func (s *server) handleLogin(w http.ResponseWriter, r *http.Request) {
576 591
	type loginData struct {
577 592
		Error    string
578 593
		Handle   string
579 594
		ReturnTo string
handler.go +7 -0
17 17
	Section         string
18 18
	Ref             string
19 19
	CommitHash      string
20 20
	Handle          string
21 21
	Avatar          string
22 +
	DevMode         bool
22 23
	Data            any
23 24
}
24 25
25 26
func (s *server) newPageData(r *http.Request, repo *RepoInfo, section, ref string) pageData {
26 27
	handle := getSessionHandle(r)
34 35
		BaseURL:         s.baseURL,
35 36
		Section:         section,
36 37
		Ref:             ref,
37 38
		Handle:          handle,
38 39
		Avatar:          avatar,
40 +
		DevMode:         s.dev,
39 41
	}
40 42
	if repo != nil {
41 43
		pd.Repo = repo.Name
42 44
		pd.Description = repo.Description
43 45
	}
113 115
	if path == "logout" {
114 116
		s.handleLogout(w, r)
115 117
		return
116 118
	}
117 119
120 +
	if path == "dev/login" && s.dev {
121 +
		s.handleDevLogin(w, r)
122 +
		return
123 +
	}
124 +
118 125
	// Site-level forum (discussions not scoped to a repo).
119 126
	if path == "discussions" || strings.HasPrefix(path, "discussions/") {
120 127
		rest := strings.TrimPrefix(path, "discussions")
121 128
		rest = strings.TrimPrefix(rest, "/")
122 129
		s.routeSiteDiscussions(w, r, rest)
main.go +3 -0
21 21
	description string
22 22
	baseURL     string
23 23
	scanPath    string
24 24
	username    string
25 25
	password    string
26 +
	dev         bool
26 27
}
27 28
28 29
func main() {
29 30
	listen := flag.String("listen", ":8080", "listen address")
30 31
	scanPath := flag.String("scan-path", ".", "path to scan for git repos")
33 34
	baseURL := flag.String("base-url", "", "base URL prefix (e.g. /git)")
34 35
	nonBare := flag.Bool("non-bare", false, "also scan for non-bare repos (dirs containing .git)")
35 36
	username := flag.String("username", "", "HTTP basic auth username (requires -password)")
36 37
	password := flag.String("password", "", "HTTP basic auth password (requires -username)")
37 38
	dbPath := flag.String("db-path", "./forge.db", "path to SQLite database for discussions")
39 +
	dev := flag.Bool("dev", false, "enable dev mode (auto sign-in link)")
38 40
	flag.Parse()
39 41
40 42
	if (*username == "") != (*password == "") {
41 43
		log.Fatal("-username and -password must both be set, or both be omitted")
42 44
	}
79 81
		description: *description,
80 82
		baseURL:     strings.TrimRight(*baseURL, "/"),
81 83
		scanPath:    abs,
82 84
		username:    *username,
83 85
		password:    *password,
86 +
		dev:         *dev,
84 87
	}
85 88
86 89
	mux := http.NewServeMux()
87 90
	mux.HandleFunc("/style.css", srv.serveCSS)
88 91
	mux.HandleFunc("/radiant.svg", srv.serveLogo)
templates/layout.html +1 -1
30 30
<main>
31 31
{{template "content" .}}
32 32
</main>
33 33
{{if not .Repo}}
34 34
<footer>
35 -
  <p><span class="powered-by">Powered by <a href="https://code.radiant.computer/forge">Radiant Forge</a></span><span class="copyright">&copy; 2026 Radiant Computer</span></p>
35 +
  <p><span class="powered-by">Powered by <a href="https://code.radiant.computer/forge">Radiant Forge</a></span>{{if and .DevMode (not .Handle)}}<span class="dev-login"><a href="{{.BaseURL}}/dev/login?return={{.BaseURL}}/">Sign in as cloudhead.io</a></span>{{end}}<span class="copyright">&copy; 2026 Radiant Computer</span></p>
36 36
</footer>
37 37
{{end}}
38 38
</div>
39 39
<script src="{{.BaseURL}}/js/hirad.js"></script>
40 40
<script src="{{.BaseURL}}/js/hiril.js"></script>
watch +1 -1
1 1
#!/bin/sh
2 2
# Rebuild and restart on source changes.
3 3
# Requires `entr(1)`.
4 4
find . -name '*.go' -o -name '*.html' -o -name '*.css' \
5 -
  | entr -r go run . -scan-path ~/src/radiant -non-bare -title "code.radiant.computer" -description "Radiant computer repositories" "$@"
5 +
  | entr -r go run . -dev -scan-path ~/src/radiant -non-bare -title "code.radiant.computer" -description "Radiant computer repositories" "$@"