mirror of
https://codeberg.org/Codeberg/pages-server.git
synced 2025-04-25 14:26:58 +00:00
REMOVE fasthttp version
This commit is contained in:
parent
ea13ac0e92
commit
16a8d5d575
26 changed files with 331 additions and 1339 deletions
|
@ -2,6 +2,17 @@ package gitea
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"codeberg.org/codeberg/pages/server/cache"
|
||||
)
|
||||
|
||||
var ErrorNotFound = errors.New("not found")
|
||||
|
@ -11,3 +22,154 @@ const (
|
|||
defaultBranchCacheKeyPrefix = "defaultBranch"
|
||||
giteaObjectTypeHeader = "X-Gitea-Object-Type"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
sdkClient *gitea.Client
|
||||
responseCache cache.SetGetKey
|
||||
|
||||
followSymlinks bool
|
||||
supportLFS bool
|
||||
}
|
||||
|
||||
func NewClient(giteaRoot, giteaAPIToken string, respCache cache.SetGetKey, followSymlinks, supportLFS bool) (*Client, error) {
|
||||
rootURL, err := url.Parse(giteaRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
giteaRoot = strings.Trim(rootURL.String(), "/")
|
||||
|
||||
stdClient := http.Client{Timeout: 10 * time.Second}
|
||||
|
||||
sdk, err := gitea.NewClient(giteaRoot, gitea.SetHTTPClient(&stdClient), gitea.SetToken(giteaAPIToken))
|
||||
return &Client{
|
||||
sdkClient: sdk,
|
||||
responseCache: respCache,
|
||||
followSymlinks: followSymlinks,
|
||||
supportLFS: supportLFS,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (client *Client) GiteaRawContent(targetOwner, targetRepo, ref, resource string) ([]byte, error) {
|
||||
reader, _, err := client.ServeRawContent(targetOwner, targetRepo, ref, resource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer reader.Close()
|
||||
return io.ReadAll(reader)
|
||||
}
|
||||
|
||||
func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource string) (io.ReadCloser, *http.Response, error) {
|
||||
// if cachedValue, ok := fileResponseCache.Get(uri + "?timestamp=" + o.timestamp()); ok && !cachedValue.(gitea.FileResponse).IsEmpty() {
|
||||
// cachedResponse = cachedValue.(gitea.FileResponse)
|
||||
reader, resp, err := client.sdkClient.GetFileReader(targetOwner, targetRepo, ref, resource, client.supportLFS)
|
||||
if resp != nil {
|
||||
switch resp.StatusCode {
|
||||
case http.StatusOK:
|
||||
|
||||
// add caching
|
||||
|
||||
// Write the response body to the original request
|
||||
// var cacheBodyWriter bytes.Buffer
|
||||
// if res != nil {
|
||||
// if res.Header.ContentLength() > fileCacheSizeLimit {
|
||||
// // fasthttp else will set "Content-Length: 0"
|
||||
// ctx.Response().SetBodyStream(&strings.Reader{}, -1)
|
||||
//
|
||||
// err = res.BodyWriteTo(ctx.Response.BodyWriter())
|
||||
// } else {
|
||||
// // TODO: cache is half-empty if request is cancelled - does the ctx.Err() below do the trick?
|
||||
// err = res.BodyWriteTo(io.MultiWriter(ctx.Response().BodyWriter(), &cacheBodyWriter))
|
||||
// }
|
||||
// } else {
|
||||
// _, err = ctx.Write(cachedResponse.Body)
|
||||
// }
|
||||
|
||||
// if res != nil && res.Header.ContentLength() <= fileCacheSizeLimit && ctx.Err() == nil {
|
||||
// cachedResponse.Exists = true
|
||||
// cachedResponse.MimeType = mimeType
|
||||
// cachedResponse.Body = cacheBodyWriter.Bytes()
|
||||
// _ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), cachedResponse, fileCacheTimeout)
|
||||
// }
|
||||
// store ETag in resp !!!!
|
||||
|
||||
objType := resp.Header.Get(giteaObjectTypeHeader)
|
||||
log.Trace().Msgf("server raw content object: %s", objType)
|
||||
if client.followSymlinks && objType == "symlink" {
|
||||
// limit to 1000 chars
|
||||
defer reader.Close()
|
||||
linkDestBytes, err := io.ReadAll(io.LimitReader(reader, 10000))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
linkDest := strings.TrimSpace(string(linkDestBytes))
|
||||
|
||||
log.Debug().Msgf("follow symlink from '%s' to '%s'", resource, linkDest)
|
||||
return client.ServeRawContent(targetOwner, targetRepo, ref, linkDest)
|
||||
}
|
||||
|
||||
return reader, resp.Response, err
|
||||
case http.StatusNotFound:
|
||||
|
||||
// add not exist caching
|
||||
// _ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), gitea.FileResponse{
|
||||
// Exists: false,
|
||||
// }, fileCacheTimeout)
|
||||
|
||||
return nil, resp.Response, ErrorNotFound
|
||||
default:
|
||||
return nil, resp.Response, fmt.Errorf("unexpected status code '%d'", resp.StatusCode)
|
||||
}
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
func (client *Client) GiteaGetRepoBranchTimestamp(repoOwner, repoName, branchName string) (*BranchTimestamp, error) {
|
||||
cacheKey := fmt.Sprintf("%s/%s/%s/%s", branchTimestampCacheKeyPrefix, repoOwner, repoName, branchName)
|
||||
|
||||
if stamp, ok := client.responseCache.Get(cacheKey); ok && stamp != nil {
|
||||
return stamp.(*BranchTimestamp), nil
|
||||
}
|
||||
|
||||
branch, resp, err := client.sdkClient.GetRepoBranch(repoOwner, repoName, branchName)
|
||||
if err != nil {
|
||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
||||
return &BranchTimestamp{}, ErrorNotFound
|
||||
}
|
||||
return &BranchTimestamp{}, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return &BranchTimestamp{}, fmt.Errorf("unexpected status code '%d'", resp.StatusCode)
|
||||
}
|
||||
|
||||
stamp := &BranchTimestamp{
|
||||
Branch: branch.Name,
|
||||
Timestamp: branch.Commit.Timestamp,
|
||||
}
|
||||
|
||||
if err := client.responseCache.Set(cacheKey, stamp, branchExistenceCacheTimeout); err != nil {
|
||||
log.Error().Err(err).Msgf("error on store of repo branch timestamp [%s/%s@%s]", repoOwner, repoName, branchName)
|
||||
}
|
||||
return stamp, nil
|
||||
}
|
||||
|
||||
func (client *Client) GiteaGetRepoDefaultBranch(repoOwner, repoName string) (string, error) {
|
||||
cacheKey := fmt.Sprintf("%s/%s/%s", defaultBranchCacheKeyPrefix, repoOwner, repoName)
|
||||
|
||||
if branch, ok := client.responseCache.Get(cacheKey); ok && branch != nil {
|
||||
return branch.(string), nil
|
||||
}
|
||||
|
||||
repo, resp, err := client.sdkClient.GetRepo(repoOwner, repoName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("unexpected status code '%d'", resp.StatusCode)
|
||||
}
|
||||
|
||||
branch := repo.DefaultBranch
|
||||
if err := client.responseCache.Set(cacheKey, branch, defaultBranchCacheTimeout); err != nil {
|
||||
log.Error().Err(err).Msgf("error on store of repo default branch [%s/%s]", repoOwner, repoName)
|
||||
}
|
||||
return branch, nil
|
||||
}
|
||||
|
|
|
@ -1,174 +0,0 @@
|
|||
//go:build fasthttp
|
||||
|
||||
package gitea
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/valyala/fasthttp"
|
||||
"github.com/valyala/fastjson"
|
||||
|
||||
"codeberg.org/codeberg/pages/server/cache"
|
||||
)
|
||||
|
||||
const (
|
||||
giteaAPIRepos = "/api/v1/repos/"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
giteaRoot string
|
||||
giteaAPIToken string
|
||||
infoTimeout time.Duration
|
||||
contentTimeout time.Duration
|
||||
fastClient *fasthttp.Client
|
||||
responseCache cache.SetGetKey
|
||||
|
||||
followSymlinks bool
|
||||
supportLFS bool
|
||||
}
|
||||
|
||||
func NewClient(giteaRoot, giteaAPIToken string, respCache cache.SetGetKey, followSymlinks, supportLFS bool) (*Client, error) {
|
||||
rootURL, err := url.Parse(giteaRoot)
|
||||
giteaRoot = strings.Trim(rootURL.String(), "/")
|
||||
|
||||
return &Client{
|
||||
giteaRoot: giteaRoot,
|
||||
giteaAPIToken: giteaAPIToken,
|
||||
infoTimeout: 5 * time.Second,
|
||||
contentTimeout: 10 * time.Second,
|
||||
fastClient: getFastHTTPClient(),
|
||||
responseCache: respCache,
|
||||
|
||||
followSymlinks: followSymlinks,
|
||||
supportLFS: supportLFS,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (client *Client) GiteaRawContent(targetOwner, targetRepo, ref, resource string) ([]byte, error) {
|
||||
resp, err := client.ServeRawContent(targetOwner, targetRepo, ref, resource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Body(), nil
|
||||
}
|
||||
|
||||
func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource string) (*fasthttp.Response, error) {
|
||||
var apiURL string
|
||||
if client.supportLFS {
|
||||
apiURL = joinURL(client.giteaRoot, giteaAPIRepos, targetOwner, targetRepo, "media", resource+"?ref="+url.QueryEscape(ref))
|
||||
} else {
|
||||
apiURL = joinURL(client.giteaRoot, giteaAPIRepos, targetOwner, targetRepo, "raw", resource+"?ref="+url.QueryEscape(ref))
|
||||
}
|
||||
resp, err := client.do(client.contentTimeout, apiURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch resp.StatusCode() {
|
||||
case fasthttp.StatusOK:
|
||||
objType := string(resp.Header.Peek(giteaObjectTypeHeader))
|
||||
log.Trace().Msgf("server raw content object: %s", objType)
|
||||
if client.followSymlinks && objType == "symlink" {
|
||||
// TODO: limit to 1000 chars if we switched to std
|
||||
linkDest := strings.TrimSpace(string(resp.Body()))
|
||||
log.Debug().Msgf("follow symlink from '%s' to '%s'", resource, linkDest)
|
||||
return client.ServeRawContent(targetOwner, targetRepo, ref, linkDest)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
|
||||
case fasthttp.StatusNotFound:
|
||||
return nil, ErrorNotFound
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected status code '%d'", resp.StatusCode())
|
||||
}
|
||||
}
|
||||
|
||||
func (client *Client) GiteaGetRepoBranchTimestamp(repoOwner, repoName, branchName string) (*BranchTimestamp, error) {
|
||||
cacheKey := fmt.Sprintf("%s/%s/%s/%s", branchTimestampCacheKeyPrefix, repoOwner, repoName, branchName)
|
||||
|
||||
if stamp, ok := client.responseCache.Get(cacheKey); ok && stamp != nil {
|
||||
return stamp.(*BranchTimestamp), nil
|
||||
}
|
||||
|
||||
url := joinURL(client.giteaRoot, giteaAPIRepos, repoOwner, repoName, "branches", branchName)
|
||||
res, err := client.do(client.infoTimeout, url)
|
||||
if err != nil {
|
||||
return &BranchTimestamp{}, err
|
||||
}
|
||||
if res.StatusCode() != fasthttp.StatusOK {
|
||||
return &BranchTimestamp{}, fmt.Errorf("unexpected status code '%d'", res.StatusCode())
|
||||
}
|
||||
timestamp, err := time.Parse(time.RFC3339, fastjson.GetString(res.Body(), "commit", "timestamp"))
|
||||
if err != nil {
|
||||
return &BranchTimestamp{}, err
|
||||
}
|
||||
|
||||
stamp := &BranchTimestamp{
|
||||
Branch: branchName,
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
|
||||
client.responseCache.Set(cacheKey, stamp, branchExistenceCacheTimeout)
|
||||
return stamp, nil
|
||||
}
|
||||
|
||||
func (client *Client) GiteaGetRepoDefaultBranch(repoOwner, repoName string) (string, error) {
|
||||
cacheKey := fmt.Sprintf("%s/%s/%s", defaultBranchCacheKeyPrefix, repoOwner, repoName)
|
||||
|
||||
if branch, ok := client.responseCache.Get(cacheKey); ok && branch != nil {
|
||||
return branch.(string), nil
|
||||
}
|
||||
|
||||
url := joinURL(client.giteaRoot, giteaAPIRepos, repoOwner, repoName)
|
||||
res, err := client.do(client.infoTimeout, url)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if res.StatusCode() != fasthttp.StatusOK {
|
||||
return "", fmt.Errorf("unexpected status code '%d'", res.StatusCode())
|
||||
}
|
||||
|
||||
branch := fastjson.GetString(res.Body(), "default_branch")
|
||||
client.responseCache.Set(cacheKey, branch, defaultBranchCacheTimeout)
|
||||
return branch, nil
|
||||
}
|
||||
|
||||
func (client *Client) do(timeout time.Duration, url string) (*fasthttp.Response, error) {
|
||||
req := fasthttp.AcquireRequest()
|
||||
|
||||
req.SetRequestURI(url)
|
||||
req.Header.Set(fasthttp.HeaderAuthorization, "token "+client.giteaAPIToken)
|
||||
res := fasthttp.AcquireResponse()
|
||||
|
||||
err := client.fastClient.DoTimeout(req, res, timeout)
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// TODO: once golang v1.19 is min requirement, we can switch to 'JoinPath()' of 'net/url' package
|
||||
func joinURL(baseURL string, paths ...string) string {
|
||||
p := make([]string, 0, len(paths))
|
||||
for i := range paths {
|
||||
path := strings.TrimSpace(paths[i])
|
||||
path = strings.Trim(path, "/")
|
||||
if len(path) != 0 {
|
||||
p = append(p, path)
|
||||
}
|
||||
}
|
||||
|
||||
return baseURL + "/" + strings.Join(p, "/")
|
||||
}
|
||||
|
||||
func getFastHTTPClient() *fasthttp.Client {
|
||||
return &fasthttp.Client{
|
||||
MaxConnDuration: 60 * time.Second,
|
||||
MaxConnWaitTimeout: 1000 * time.Millisecond,
|
||||
MaxConnsPerHost: 128 * 16, // TODO: adjust bottlenecks for best performance with Gitea!
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
//go:build fasthttp
|
||||
|
||||
package gitea
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestJoinURL(t *testing.T) {
|
||||
baseURL := ""
|
||||
assert.EqualValues(t, "/", joinURL(baseURL))
|
||||
assert.EqualValues(t, "/", joinURL(baseURL, "", ""))
|
||||
|
||||
baseURL = "http://wwow.url.com"
|
||||
assert.EqualValues(t, "http://wwow.url.com/a/b/c/d", joinURL(baseURL, "a", "b/c/", "d"))
|
||||
|
||||
baseURL = "http://wow.url.com/subpath/2"
|
||||
assert.EqualValues(t, "http://wow.url.com/subpath/2/content.pdf", joinURL(baseURL, "/content.pdf"))
|
||||
assert.EqualValues(t, "http://wow.url.com/subpath/2/wonderful.jpg", joinURL(baseURL, "wonderful.jpg"))
|
||||
assert.EqualValues(t, "http://wow.url.com/subpath/2/raw/wonderful.jpg?ref=main", joinURL(baseURL, "raw", "wonderful.jpg"+"?ref="+url.QueryEscape("main")))
|
||||
assert.EqualValues(t, "http://wow.url.com/subpath/2/raw/wonderful.jpg%3Fref=main", joinURL(baseURL, "raw", "wonderful.jpg%3Fref=main"))
|
||||
}
|
|
@ -1,168 +0,0 @@
|
|||
//go:build !fasthttp
|
||||
|
||||
package gitea
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"codeberg.org/codeberg/pages/server/cache"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
sdkClient *gitea.Client
|
||||
responseCache cache.SetGetKey
|
||||
|
||||
followSymlinks bool
|
||||
supportLFS bool
|
||||
}
|
||||
|
||||
func NewClient(giteaRoot, giteaAPIToken string, respCache cache.SetGetKey, followSymlinks, supportLFS bool) (*Client, error) {
|
||||
rootURL, err := url.Parse(giteaRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
giteaRoot = strings.Trim(rootURL.String(), "/")
|
||||
|
||||
stdClient := http.Client{Timeout: 10 * time.Second}
|
||||
|
||||
sdk, err := gitea.NewClient(giteaRoot, gitea.SetHTTPClient(&stdClient), gitea.SetToken(giteaAPIToken))
|
||||
return &Client{
|
||||
sdkClient: sdk,
|
||||
responseCache: respCache,
|
||||
followSymlinks: followSymlinks,
|
||||
supportLFS: supportLFS,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (client *Client) GiteaRawContent(targetOwner, targetRepo, ref, resource string) ([]byte, error) {
|
||||
reader, _, err := client.ServeRawContent(targetOwner, targetRepo, ref, resource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer reader.Close()
|
||||
return io.ReadAll(reader)
|
||||
}
|
||||
|
||||
func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource string) (io.ReadCloser, *http.Response, error) {
|
||||
// if cachedValue, ok := fileResponseCache.Get(uri + "?timestamp=" + o.timestamp()); ok && !cachedValue.(gitea.FileResponse).IsEmpty() {
|
||||
// cachedResponse = cachedValue.(gitea.FileResponse)
|
||||
reader, resp, err := client.sdkClient.GetFileReader(targetOwner, targetRepo, ref, resource, client.supportLFS)
|
||||
if resp != nil {
|
||||
switch resp.StatusCode {
|
||||
case http.StatusOK:
|
||||
|
||||
// add caching
|
||||
|
||||
// Write the response body to the original request
|
||||
// var cacheBodyWriter bytes.Buffer
|
||||
// if res != nil {
|
||||
// if res.Header.ContentLength() > fileCacheSizeLimit {
|
||||
// // fasthttp else will set "Content-Length: 0"
|
||||
// ctx.Response().SetBodyStream(&strings.Reader{}, -1)
|
||||
//
|
||||
// err = res.BodyWriteTo(ctx.Response.BodyWriter())
|
||||
// } else {
|
||||
// // TODO: cache is half-empty if request is cancelled - does the ctx.Err() below do the trick?
|
||||
// err = res.BodyWriteTo(io.MultiWriter(ctx.Response().BodyWriter(), &cacheBodyWriter))
|
||||
// }
|
||||
// } else {
|
||||
// _, err = ctx.Write(cachedResponse.Body)
|
||||
// }
|
||||
|
||||
// if res != nil && res.Header.ContentLength() <= fileCacheSizeLimit && ctx.Err() == nil {
|
||||
// cachedResponse.Exists = true
|
||||
// cachedResponse.MimeType = mimeType
|
||||
// cachedResponse.Body = cacheBodyWriter.Bytes()
|
||||
// _ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), cachedResponse, fileCacheTimeout)
|
||||
// }
|
||||
// store ETag in resp !!!!
|
||||
|
||||
objType := resp.Header.Get(giteaObjectTypeHeader)
|
||||
log.Trace().Msgf("server raw content object: %s", objType)
|
||||
if client.followSymlinks && objType == "symlink" {
|
||||
// limit to 1000 chars
|
||||
defer reader.Close()
|
||||
linkDestBytes, err := io.ReadAll(io.LimitReader(reader, 10000))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
linkDest := strings.TrimSpace(string(linkDestBytes))
|
||||
|
||||
log.Debug().Msgf("follow symlink from '%s' to '%s'", resource, linkDest)
|
||||
return client.ServeRawContent(targetOwner, targetRepo, ref, linkDest)
|
||||
}
|
||||
|
||||
return reader, resp.Response, err
|
||||
case http.StatusNotFound:
|
||||
|
||||
// add not exist caching
|
||||
// _ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), gitea.FileResponse{
|
||||
// Exists: false,
|
||||
// }, fileCacheTimeout)
|
||||
|
||||
return nil, resp.Response, ErrorNotFound
|
||||
default:
|
||||
return nil, resp.Response, fmt.Errorf("unexpected status code '%d'", resp.StatusCode)
|
||||
}
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
func (client *Client) GiteaGetRepoBranchTimestamp(repoOwner, repoName, branchName string) (*BranchTimestamp, error) {
|
||||
cacheKey := fmt.Sprintf("%s/%s/%s/%s", branchTimestampCacheKeyPrefix, repoOwner, repoName, branchName)
|
||||
|
||||
if stamp, ok := client.responseCache.Get(cacheKey); ok && stamp != nil {
|
||||
return stamp.(*BranchTimestamp), nil
|
||||
}
|
||||
|
||||
branch, resp, err := client.sdkClient.GetRepoBranch(repoOwner, repoName, branchName)
|
||||
if err != nil {
|
||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
||||
return &BranchTimestamp{}, ErrorNotFound
|
||||
}
|
||||
return &BranchTimestamp{}, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return &BranchTimestamp{}, fmt.Errorf("unexpected status code '%d'", resp.StatusCode)
|
||||
}
|
||||
|
||||
stamp := &BranchTimestamp{
|
||||
Branch: branch.Name,
|
||||
Timestamp: branch.Commit.Timestamp,
|
||||
}
|
||||
|
||||
if err := client.responseCache.Set(cacheKey, stamp, branchExistenceCacheTimeout); err != nil {
|
||||
log.Error().Err(err).Msgf("error on store of repo branch timestamp [%s/%s@%s]", repoOwner, repoName, branchName)
|
||||
}
|
||||
return stamp, nil
|
||||
}
|
||||
|
||||
func (client *Client) GiteaGetRepoDefaultBranch(repoOwner, repoName string) (string, error) {
|
||||
cacheKey := fmt.Sprintf("%s/%s/%s", defaultBranchCacheKeyPrefix, repoOwner, repoName)
|
||||
|
||||
if branch, ok := client.responseCache.Get(cacheKey); ok && branch != nil {
|
||||
return branch.(string), nil
|
||||
}
|
||||
|
||||
repo, resp, err := client.sdkClient.GetRepo(repoOwner, repoName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("unexpected status code '%d'", resp.StatusCode)
|
||||
}
|
||||
|
||||
branch := repo.DefaultBranch
|
||||
if err := client.responseCache.Set(cacheKey, branch, defaultBranchCacheTimeout); err != nil {
|
||||
log.Error().Err(err).Msgf("error on store of repo default branch [%s/%s]", repoOwner, repoName)
|
||||
}
|
||||
return branch, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue