diff options
author | Runxi Yu <me@runxiyu.org> | 2025-02-19 08:45:09 +0800 |
---|---|---|
committer | Runxi Yu <me@runxiyu.org> | 2025-02-19 08:49:05 +0800 |
commit | ded9d435b081ab552d8c5d4e1f655e7b26a8be0a (patch) | |
tree | 6c5698994b393d9b10c53550ce379ef8ce403565 | |
parent | http: Add blank contrib/%d template (diff) | |
download | forge-ded9d435b081ab552d8c5d4e1f655e7b26a8be0a.tar.gz forge-ded9d435b081ab552d8c5d4e1f655e7b26a8be0a.tar.zst forge-ded9d435b081ab552d8c5d4e1f655e7b26a8be0a.zip |
repo/contrib: Display merge request diffs
Diffstat (limited to '')
-rw-r--r-- | http_handle_repo_commit.go | 59 | ||||
-rw-r--r-- | http_handle_repo_contrib_num.go | 9 | ||||
-rw-r--r-- | http_handle_repo_contrib_one.go | 56 | ||||
-rw-r--r-- | http_server.go | 5 | ||||
-rw-r--r-- | templates/repo_contrib_num.tmpl | 18 | ||||
-rw-r--r-- | templates/repo_contrib_one.tmpl | 83 |
6 files changed, 175 insertions, 55 deletions
diff --git a/http_handle_repo_commit.go b/http_handle_repo_commit.go index 11f16e4..25802ed 100644 --- a/http_handle_repo_commit.go +++ b/http_handle_repo_commit.go @@ -62,9 +62,39 @@ func handle_repo_commit(w http.ResponseWriter, r *http.Request, params map[strin params["parent_commit_hash"] = parent_commit_hash.String() params["patch"] = patch + params["file_patches"] = make_usable_file_patches(patch) + + render_template(w, "repo_commit", params) +} + +type fake_diff_file struct { + hash plumbing.Hash + mode filemode.FileMode + path string +} + +func (f fake_diff_file) Hash() plumbing.Hash { + return f.hash +} + +func (f fake_diff_file) Mode() filemode.FileMode { + return f.mode +} + +func (f fake_diff_file) Path() string { + return f.path +} + +var fake_diff_file_null = fake_diff_file{ + hash: plumbing.NewHash("0000000000000000000000000000000000000000"), + mode: misc.First_or_panic(filemode.New("100644")), + path: "", +} + +func make_usable_file_patches(patch diff.Patch) (usable_file_patches []usable_file_patch) { // TODO: Remove unnecessary context // TODO: Prepend "+"/"-"/" " instead of solely distinguishing based on color - usable_file_patches := make([]usable_file_patch, 0) + usable_file_patches = make([]usable_file_patch, 0) for _, file_patch := range patch.FilePatches() { from, to := file_patch.Files() if from == nil { @@ -91,31 +121,6 @@ func handle_repo_commit(w http.ResponseWriter, r *http.Request, params map[strin } usable_file_patches = append(usable_file_patches, usable_file_patch) } - params["file_patches"] = usable_file_patches - - render_template(w, "repo_commit", params) -} - -type fake_diff_file struct { - hash plumbing.Hash - mode filemode.FileMode - path string -} - -func (f fake_diff_file) Hash() plumbing.Hash { - return f.hash + return } -func (f fake_diff_file) Mode() filemode.FileMode { - return f.mode -} - -func (f fake_diff_file) Path() string { - return f.path -} - -var fake_diff_file_null = fake_diff_file{ - hash: plumbing.NewHash("0000000000000000000000000000000000000000"), - mode: misc.First_or_panic(filemode.New("100644")), - path: "", -} diff --git a/http_handle_repo_contrib_num.go b/http_handle_repo_contrib_num.go deleted file mode 100644 index c4ed5d1..0000000 --- a/http_handle_repo_contrib_num.go +++ /dev/null @@ -1,9 +0,0 @@ -package main - -import ( - "net/http" -) - -func handle_repo_contrib_num(w http.ResponseWriter, r *http.Request, params map[string]any) { - render_template(w, "repo_contrib_num", params) -} diff --git a/http_handle_repo_contrib_one.go b/http_handle_repo_contrib_one.go new file mode 100644 index 0000000..a09b6e8 --- /dev/null +++ b/http_handle_repo_contrib_one.go @@ -0,0 +1,56 @@ +package main + +import ( + "net/http" + "strconv" + + "github.com/go-git/go-git/v5" +) + +func handle_repo_contrib_one(w http.ResponseWriter, r *http.Request, params map[string]any) { + mr_id_string := params["mr_id"].(string) + mr_id, err := strconv.ParseInt(mr_id_string, 10, strconv.IntSize) + if err != nil { + http.Error(w, "Merge request ID not an integer: "+err.Error(), http.StatusBadRequest) + return + } + + var title, status, source_ref, destination_branch string + err = database.QueryRow(r.Context(), "SELECT title, status, source_ref, destination_branch FROM merge_requests WHERE id = $1", mr_id).Scan(&title, &status, &source_ref, &destination_branch) + if err != nil { + http.Error(w, "Error querying merge request: "+err.Error(), http.StatusInternalServerError) + return + } + params["mr_title"], params["mr_status"], params["mr_source_ref"], params["mr_destination_branch"] = title, status, source_ref, destination_branch + + repo := params["repo"].(*git.Repository) + + source_ref_hash, err := get_ref_hash_from_type_and_name(repo, "branch", source_ref) + if err != nil { + http.Error(w, "Error getting source ref hash: "+err.Error(), http.StatusInternalServerError) + return + } + source_commit, err := repo.CommitObject(source_ref_hash) + if err != nil { + http.Error(w, "Error getting source commit: "+err.Error(), http.StatusInternalServerError) + return + } + params["source_commit"] = source_commit + + destination_branch_hash, err := get_ref_hash_from_type_and_name(repo, "branch", destination_branch) + if err != nil { + http.Error(w, "Error getting destination branch hash: "+err.Error(), http.StatusInternalServerError) + return + } + destination_commit, err := repo.CommitObject(destination_branch_hash) + if err != nil { + http.Error(w, "Error getting destination commit: "+err.Error(), http.StatusInternalServerError) + return + } + params["source_commit"] = source_commit + + patch, err := destination_commit.Patch(source_commit) + params["file_patches"] = make_usable_file_patches(patch) + + render_template(w, "repo_contrib_one", params) +} diff --git a/http_server.go b/http_server.go index b44add3..077c63e 100644 --- a/http_server.go +++ b/http_server.go @@ -84,6 +84,8 @@ func (router *http_router_t) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } + params["separator_index"] = separator_index + // TODO if separator_index > 1 { http.Error(w, "Subgroups haven't been implemented yet", http.StatusNotImplemented) @@ -198,7 +200,8 @@ func (router *http_router_t) ServeHTTP(w http.ResponseWriter, r *http.Request) { case separator_index+4: handle_repo_contrib_index(w, r, params) case separator_index+5: - handle_repo_contrib_num(w, r, params) + params["mr_id"] = segments[separator_index+4] + handle_repo_contrib_one(w, r, params) default: http.Error(w, "Too many parameters", http.StatusBadRequest) } diff --git a/templates/repo_contrib_num.tmpl b/templates/repo_contrib_num.tmpl deleted file mode 100644 index dc34c53..0000000 --- a/templates/repo_contrib_num.tmpl +++ /dev/null @@ -1,18 +0,0 @@ -{{- define "repo_contrib_num" -}} -<!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-num"> - {{ template "header" . }} - <div class="padding-wrapper"> - Test - </div> - <footer> - {{ template "footer" . }} - </footer> - </body> -</html> -{{- end -}} diff --git a/templates/repo_contrib_one.tmpl b/templates/repo_contrib_one.tmpl new file mode 100644 index 0000000..85cac10 --- /dev/null +++ b/templates/repo_contrib_one.tmpl @@ -0,0 +1,83 @@ +{{- define "repo_contrib_one" -}} +<!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-one"> + {{ template "header" . }} + <div class="padding-wrapper"> + <table id="mr-info-table"> + <thead> + <tr class="title-row"> + <th colspan="2">Merge request info</th> + </tr> + </thead> + <tbody> + <tr> + <th scope="row">ID</th> + <td>{{ .mr_id }}</td> + </tr> + <tr> + <th scope="row">Status</th> + <td>{{ .mr_status }}</td> + </tr> + <tr> + <th scope="row">Title</th> + <td>{{ .mr_title }}</td> + </tr> + <tr> + <th scope="row">Source ref</th> + <td>{{ .mr_source_ref }}</td> + </tr> + <tr> + <th scope="row">Destination branch</th> + <td>{{ .mr_destination_branch }}</td> + </tr> + </tbody> + </table> + </div> + <div class="padding-wrapper"> + {{ $destination_commit := .destination_commit }} + {{ $source_commit := .source_commit }} + {{ range .file_patches }} + <div class="file-patch toggle-on-wrapper"> + <input type="checkbox" id="toggle-{{ .From.Hash }}{{ .To.Hash }}" class="file-toggle toggle-on-toggle"> + <label for="toggle-{{ .From.Hash }}{{ .To.Hash }}" class="file-header toggle-on-header"> + <div> + {{ if eq .From.Path "" }} + --- /dev/null + {{ else }} + --- a/<a href="../../tree/{{ .From.Path }}?commit={{ $destination_commit.Hash }}">{{ .From.Path }}</a> {{ .From.Mode }} + {{ end }} + <br /> + {{ if eq .To.Path "" }} + +++ /dev/null + {{ else }} + +++ b/<a href="../../tree/{{ .To.Path }}?commit={{ $source_commit.Hash }}">{{ .To.Path }}</a> {{ .To.Mode }} + {{ end }} + </div> + </label> + <div class="file-content toggle-on-content scroll"> + {{ range .Chunks }} + {{ if eq .Operation 0 }} + <pre class="chunk chunk-unchanged">{{ .Content }}</pre> + {{ else if eq .Operation 1 }} + <pre class="chunk chunk-addition">{{ .Content }}</pre> + {{ else if eq .Operation 2 }} + <pre class="chunk chunk-deletion">{{ .Content }}</pre> + {{ else }} + <pre class="chunk chunk-unknown">{{ .Content }}</pre> + {{ end }} + {{ end }} + </div> + </div> + {{ end }} + </div> + <footer> + {{ template "footer" . }} + </footer> + </body> +</html> +{{- end -}} |