diff options
author | Runxi Yu <me@runxiyu.org> | 2025-02-19 01:02:33 +0800 |
---|---|---|
committer | Runxi Yu <me@runxiyu.org> | 2025-02-19 01:02:33 +0800 |
commit | 2d3e888321baeae889c7c51f2312aafba1ec70d0 (patch) | |
tree | 030c79f59ac2f62cce1567fd3fc07607b224d2fd | |
parent | http: Consistently use redirect_with{out,}_slash, never r.URL.Path (diff) | |
download | forge-2d3e888321baeae889c7c51f2312aafba1ec70d0.tar.gz forge-2d3e888321baeae889c7c51f2312aafba1ec70d0.tar.zst forge-2d3e888321baeae889c7c51f2312aafba1ec70d0.zip |
contrib: Add contrib/MR index page
-rw-r--r-- | git_misc.go | 6 | ||||
-rw-r--r-- | http_handle_repo_contrib_index.go | 42 | ||||
-rw-r--r-- | http_server.go | 7 | ||||
-rw-r--r-- | schema.sql | 8 | ||||
-rw-r--r-- | templates/repo_contrib_index.tmpl | 33 |
5 files changed, 89 insertions, 7 deletions
diff --git a/git_misc.go b/git_misc.go index be75e40..db5ff89 100644 --- a/git_misc.go +++ b/git_misc.go @@ -19,11 +19,11 @@ var ( ) // open_git_repo opens a git repository by group and repo name. -func open_git_repo(ctx context.Context, group_name, repo_name string) (repo *git.Repository, description string, err error) { +func open_git_repo(ctx context.Context, group_name, repo_name string) (repo *git.Repository, description string, repo_id int, err error) { var fs_path string - err = database.QueryRow(ctx, "SELECT r.filesystem_path, COALESCE(r.description, '') FROM repos r JOIN groups g ON r.group_id = g.id WHERE g.name = $1 AND r.name = $2;", group_name, repo_name).Scan(&fs_path, &description) + err = database.QueryRow(ctx, "SELECT r.filesystem_path, COALESCE(r.description, ''), r.id FROM repos r JOIN groups g ON r.group_id = g.id WHERE g.name = $1 AND r.name = $2;", group_name, repo_name).Scan(&fs_path, &description, &repo_id) if err != nil { - return nil, "", err + return } repo, err = git.PlainOpen(fs_path) return diff --git a/http_handle_repo_contrib_index.go b/http_handle_repo_contrib_index.go new file mode 100644 index 0000000..632e8f2 --- /dev/null +++ b/http_handle_repo_contrib_index.go @@ -0,0 +1,42 @@ +package main + +import ( + "net/http" + + "github.com/go-git/go-git/v5" +) + +type id_title_status_t struct { + ID int + Title string + Status string +} + +func handle_repo_contrib_index(w http.ResponseWriter, r *http.Request, params map[string]any) { + _ = params["repo"].(*git.Repository) + + rows, err := database.Query(r.Context(), "SELECT id, title, status FROM merge_requests WHERE repo_id = $1", params["repo_id"]) + if err != nil { + http.Error(w, "Error querying merge requests: "+err.Error(), http.StatusInternalServerError) + return + } + defer rows.Close() + + result := []id_title_status_t{} + for rows.Next() { + var id int + var title, status string + if err := rows.Scan(&id, &title, &status); err != nil { + http.Error(w, "Error scanning merge request: "+err.Error(), http.StatusInternalServerError) + return + } + result = append(result, id_title_status_t{id, title, status}) + } + if err := rows.Err(); err != nil { + http.Error(w, "Error ranging over merge requests: "+err.Error(), http.StatusInternalServerError) + return + } + params["merge_requests"] = result + + render_template(w, "repo_contrib_index", params) +} diff --git a/http_server.go b/http_server.go index e5cb6ce..c17bc6f 100644 --- a/http_server.go +++ b/http_server.go @@ -146,7 +146,7 @@ func (router *http_router_t) ServeHTTP(w http.ResponseWriter, r *http.Request) { // TODO: subgroups - params["repo"], params["repo_description"], err = open_git_repo(r.Context(), group_name, module_name) + params["repo"], params["repo_description"], params["repo_id"], err = open_git_repo(r.Context(), group_name, module_name) if err != nil { http.Error(w, "Error opening repo: "+err.Error(), http.StatusInternalServerError) return @@ -189,6 +189,11 @@ func (router *http_router_t) ServeHTTP(w http.ResponseWriter, r *http.Request) { } params["commit_id"] = segments[separator_index+4] handle_repo_commit(w, r, params) + case "contrib": + if redirect_with_slash(w, r) { + return + } + handle_repo_contrib_index(w, r, params) default: http.Error(w, fmt.Sprintf("Unknown repo feature: %s", repo_feature), http.StatusNotFound) } @@ -64,15 +64,17 @@ CREATE TABLE sessions ( UNIQUE(user_id, session_id) ); +// TODO: CREATE TABLE merge_requests ( id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, + title TEXT NOT NULL, repo_id INTEGER NOT NULL REFERENCES repos(id) ON DELETE CASCADE, - creator INTEGER REFERENCES users(id) ON DELETE SET NULL, + creator INTEGER NOT NULL REFERENCES users(id) ON DELETE SET NULL, source_ref TEXT NOT NULL, destination_branch TEXT NOT NULL, status TEXT NOT NULL CHECK (status IN ('open', 'merged', 'closed')), - created_at TIMESTAMP NOT NULL, - mailing_list_id INT UNIQUE REFERENCES mailing_lists(id) ON DELETE CASCADE + UNIQUE (repo_id, source_ref, destination_branch), + UNIQUE (repo_id, id) ); CREATE TABLE user_group_roles ( diff --git a/templates/repo_contrib_index.tmpl b/templates/repo_contrib_index.tmpl new file mode 100644 index 0000000..6da917b --- /dev/null +++ b/templates/repo_contrib_index.tmpl @@ -0,0 +1,33 @@ +{{- define "repo_contrib_index" -}} +<!DOCTYPE html> +<html lang="en"> + <head> + {{ template "head_common" . }} + <title>Merge requests – {{ .repo_name }} – {{ .group_name }} – {{ .global.forge_title }}</title> + </head> + <body class="repo-contrib-index"> + {{ template "header" . }} + <div class="padding-wrapper"> + <table id="recent-merge_requests" class="wide"> + <thead> + <tr class="title-row"> + <th colspan="3">Merge requests</th> + </tr> + </thead> + <tbody> + {{- range .merge_requests }} + <tr> + <td class="merge_request-id">{{ .ID }}</td> + <td class="merge_request-title"><a href="{{ .ID }}/">{{ .Title }}</a></td> + <td class="merge_request-status">{{ .Status }}</td> + </tr> + {{- end }} + </tbody> + </table> + </div> + <footer> + {{ template "footer" . }} + </footer> + </body> +</html> +{{- end -}} |