diff options
Diffstat (limited to '')
-rw-r--r-- | forged/internal/incoming/web/handlers/group.go | 72 |
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) } |