aboutsummaryrefslogtreecommitdiff
path: root/forged/internal/incoming/web/handlers/group.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--forged/internal/incoming/web/handlers/group.go72
1 files changed, 68 insertions, 4 deletions
diff --git a/forged/internal/incoming/web/handlers/group.go b/forged/internal/incoming/web/handlers/group.go
index 3201491..4823cb7 100644
--- a/forged/internal/incoming/web/handlers/group.go
+++ b/forged/internal/incoming/web/handlers/group.go
@@ -1,13 +1,17 @@
package handlers
import (
+ "fmt"
"log/slog"
"net/http"
+ "path/filepath"
"strconv"
+ "github.com/jackc/pgx/v5"
"go.lindenii.runxiyu.org/forge/forged/internal/database/queries"
"go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/templates"
wtypes "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/types"
+ "go.lindenii.runxiyu.org/forge/forged/internal/ipc/git2c"
)
type GroupHTTP struct {
@@ -31,19 +35,19 @@ func (h *GroupHTTP) Index(w http.ResponseWriter, r *http.Request, _ wtypes.Vars)
Column1: base.URLSegments,
UserID: userID,
}
- p, err := base.Queries.GetGroupByPath(r.Context(), queryParams)
+ p, err := base.Global.Queries.GetGroupByPath(r.Context(), queryParams)
if err != nil {
slog.Error("failed to get group ID by path", "error", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
- subgroups, err := base.Queries.GetSubgroups(r.Context(), &p.ID)
+ subgroups, err := base.Global.Queries.GetSubgroups(r.Context(), &p.ID)
if err != nil {
slog.Error("failed to get subgroups", "error", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
// TODO: gracefully fail this part of the page
}
- repos, err := base.Queries.GetReposInGroup(r.Context(), p.ID)
+ repos, err := base.Global.Queries.GetReposInGroup(r.Context(), p.ID)
if err != nil {
slog.Error("failed to get repos in group", "error", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
@@ -78,7 +82,7 @@ func (h *GroupHTTP) Post(w http.ResponseWriter, r *http.Request, _ wtypes.Vars)
Column1: base.URLSegments,
UserID: userID,
}
- p, err := base.Queries.GetGroupByPath(r.Context(), queryParams)
+ p, err := base.Global.Queries.GetGroupByPath(r.Context(), queryParams)
if err != nil {
slog.Error("failed to get group ID by path", "error", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
@@ -89,4 +93,64 @@ func (h *GroupHTTP) Post(w http.ResponseWriter, r *http.Request, _ wtypes.Vars)
http.Error(w, "You do not have the necessary permissions to create repositories in this group.", http.StatusForbidden)
return
}
+
+ name := r.PostFormValue("repo_name")
+ desc := r.PostFormValue("repo_desc")
+ contrib := r.PostFormValue("repo_contrib")
+ if name == "" {
+ http.Error(w, "Repo name is required", http.StatusBadRequest)
+ return
+ }
+
+ if contrib == "" || contrib == "public" {
+ contrib = "open"
+ }
+
+ tx, err := base.Global.DB.BeginTx(r.Context(), pgx.TxOptions{})
+ if err != nil {
+ slog.Error("begin tx failed", "error", err)
+ http.Error(w, "Internal Server Error", http.StatusInternalServerError)
+ return
+ }
+ defer func() { _ = tx.Rollback(r.Context()) }()
+
+ txq := base.Global.Queries.WithTx(tx)
+ var descPtr *string
+ if desc != "" {
+ descPtr = &desc
+ }
+ repoID, err := txq.InsertRepo(r.Context(), queries.InsertRepoParams{
+ GroupID: p.ID,
+ Name: name,
+ Description: descPtr,
+ ContribRequirements: contrib,
+ })
+ if err != nil {
+ slog.Error("insert repo failed", "error", err)
+ http.Error(w, "Failed to create repository", http.StatusInternalServerError)
+ return
+ }
+
+ repoPath := filepath.Join(base.Global.Config.Git.RepoDir, fmt.Sprintf("%d.git", repoID))
+
+ gitc, err := git2c.NewClient(r.Context(), base.Global.Config.Git.Socket)
+ if err != nil {
+ slog.Error("git2d connect failed", "error", err)
+ http.Error(w, "Failed to initialize repository (backend)", http.StatusInternalServerError)
+ return
+ }
+ defer func() { _ = gitc.Close() }()
+ if err = gitc.InitRepo(repoPath, base.Global.Config.Hooks.Execs); err != nil {
+ slog.Error("git2d init failed", "error", err)
+ http.Error(w, "Failed to initialize repository", http.StatusInternalServerError)
+ return
+ }
+
+ if err = tx.Commit(r.Context()); err != nil {
+ slog.Error("commit tx failed", "error", err)
+ http.Error(w, "Failed to finalize repository creation", http.StatusInternalServerError)
+ return
+ }
+
+ http.Redirect(w, r, r.URL.Path, http.StatusSeeOther)
}