feat: initial rest api support with /repos/{owner}/{repo}/pulls/{pull_number}/files
This commit is contained in:
parent
ea4e4aa00a
commit
0365862777
|
@ -29,6 +29,7 @@ func SetupRoutes(params RouteParams) {
|
|||
setupManifestsRoutes(params)
|
||||
setupAppRoutes(params)
|
||||
setupWebhookRoutes(params)
|
||||
setupRestRoutes(params)
|
||||
}
|
||||
|
||||
type ClientParams struct {
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
structs "code.gitea.io/gitea/modules/structs"
|
||||
gitea "code.gitea.io/sdk/gitea"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.lumeweb.com/LumeWeb/gitea-github-proxy/config"
|
||||
"github.com/google/go-github/v59/github"
|
||||
"github.com/gorilla/mux"
|
||||
"go.uber.org/zap"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type restApi struct {
|
||||
config *config.Config
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func newRestApi(cfg *config.Config, logger *zap.Logger) *restApi {
|
||||
return &restApi{config: cfg, logger: logger}
|
||||
}
|
||||
|
||||
func (r restApi) handlerGetPullRequestFiles(w http.ResponseWriter, request *http.Request) {
|
||||
vars := mux.Vars(request)
|
||||
|
||||
owner := vars["owner"]
|
||||
repo := vars["repo"]
|
||||
pullNumber := vars["pull_number"]
|
||||
|
||||
client := r.getClientOrError(w)
|
||||
|
||||
if client == nil {
|
||||
return
|
||||
}
|
||||
parsedPullNumber, err := strconv.ParseInt(pullNumber, 10, 64)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to parse pull number", http.StatusBadRequest)
|
||||
r.logger.Error("Failed to parse pull number", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
files, r2, err := client.ListPullRequestFiles(owner, repo, parsedPullNumber, gitea.ListPullRequestFilesOptions{
|
||||
ListOptions: r.getPagingOptions(request),
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to get pull request files", http.StatusInternalServerError)
|
||||
r.logger.Error("Failed to get pull request files", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
githubFiles := make([]*github.CommitFile, len(files))
|
||||
|
||||
for i, file := range files {
|
||||
f := structs.ChangedFile(*file)
|
||||
githubFiles[i] = convertCommitFile(&f)
|
||||
}
|
||||
|
||||
r.sendPagingHeaders(w, r2)
|
||||
r.respond(w, http.StatusOK, githubFiles)
|
||||
}
|
||||
|
||||
func (r restApi) getPagingOptions(request *http.Request) gitea.ListOptions {
|
||||
page, _ := strconv.Atoi(request.URL.Query().Get("page"))
|
||||
perPage, _ := strconv.Atoi(request.URL.Query().Get("per_page"))
|
||||
|
||||
return gitea.ListOptions{
|
||||
Page: page,
|
||||
PageSize: perPage,
|
||||
}
|
||||
}
|
||||
|
||||
func (r restApi) sendPagingHeaders(w http.ResponseWriter, apiResponse *gitea.Response) {
|
||||
links := []string{}
|
||||
|
||||
baseURL := fmt.Sprintf("https://%s", r.config.Domain)
|
||||
|
||||
joinStrings := func(elements []string, separator string) string {
|
||||
if len(elements) == 0 {
|
||||
return ""
|
||||
}
|
||||
result := elements[0]
|
||||
for i := 1; i < len(elements); i++ {
|
||||
result += separator + elements[i]
|
||||
}
|
||||
return result
|
||||
}
|
||||
joinLinks := func(links []string) string {
|
||||
return fmt.Sprintf("%s", joinStrings(links, ", "))
|
||||
}
|
||||
|
||||
if apiResponse.FirstPage > 0 {
|
||||
links = append(links, fmt.Sprintf(`<%s?page=%d>; rel="first"`, baseURL, apiResponse.FirstPage))
|
||||
}
|
||||
if apiResponse.PrevPage > 0 {
|
||||
links = append(links, fmt.Sprintf(`<%s?page=%d>; rel="prev"`, baseURL, apiResponse.PrevPage))
|
||||
}
|
||||
if apiResponse.NextPage > 0 {
|
||||
links = append(links, fmt.Sprintf(`<%s?page=%d>; rel="next"`, baseURL, apiResponse.NextPage))
|
||||
}
|
||||
if apiResponse.LastPage > 0 {
|
||||
links = append(links, fmt.Sprintf(`<%s?page=%d>; rel="last"`, baseURL, apiResponse.LastPage))
|
||||
}
|
||||
|
||||
if len(links) > 0 {
|
||||
w.Header().Add("Link", fmt.Sprintf("%s", joinLinks(links)))
|
||||
}
|
||||
}
|
||||
|
||||
func (r restApi) respond(w http.ResponseWriter, status int, data interface{}) {
|
||||
jsonData, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to marshal response", http.StatusInternalServerError)
|
||||
r.logger.Error("Failed to marshal response", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
if data != nil {
|
||||
_, _ = w.Write(jsonData)
|
||||
}
|
||||
}
|
||||
|
||||
func (r restApi) getClientOrError(w http.ResponseWriter) *gitea.Client {
|
||||
client, err := getClient(ClientParams{
|
||||
Config: r.config,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to get Gitea client", http.StatusInternalServerError)
|
||||
r.logger.Error("Failed to get Gitea client", zap.Error(err))
|
||||
return nil
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
func setupRestRoutes(params RouteParams) {
|
||||
logger := params.Logger
|
||||
cfg := params.Config
|
||||
r := params.R
|
||||
|
||||
restApi := newRestApi(cfg, logger)
|
||||
restRouter := r.PathPrefix("/api").Subrouter()
|
||||
|
||||
restRouter.HandleFunc("/repos/{owner}/{repo}/pulls/{pull_number}/files", restApi.handlerGetPullRequestFiles).Methods("GET")
|
||||
}
|
Loading…
Reference in New Issue