This repository has been archived on 2024-03-03. You can view files and clone it, but cannot push or open issues or pull requests.
doggo-fetcher/internal/tags.go

145 lines
3.1 KiB
Go

package internal
import (
"context"
"fmt"
"net/http"
"os"
"strings"
"github.com/google/go-github/v45/github"
)
type TagsAction interface {
GetRelease(beta, rc bool) (string, error)
GetTagsRef() ([]*github.Reference, error)
getLatestTag(beta, rc bool) (string, error)
}
type Tags struct {
release string
client github.Client
ctx context.Context
}
func NewTags(release string, ctx context.Context) TagsAction {
return &Tags{
release: release,
client: *github.NewClient(nil),
ctx: ctx,
}
}
// GetRelease retrieves tags from "golang/go" and check whether
// the given release exists in it
//
// Returns the found release or an error
func (t *Tags) GetRelease(beta, rc bool) (string, error) {
if t.release == LTS {
return t.getLatestTag(beta, rc)
}
refs, err := t.GetTagsRef()
if err != nil {
if err == ErrEmptyTags {
return "", nil
}
return "", err
}
for i, ref := range refs {
userRelease := fmt.Sprintf("go%s", t.release)
tag := strings.Split(*ref.Ref, "/")[2]
if strings.Contains(tag, userRelease) {
if (!beta && strings.Contains(tag, "beta")) || (!rc && strings.Contains(tag, "rc")) {
continue
}
if len(refs) == i+1 {
return tag, nil
}
if beta && strings.Contains(tag, "beta") {
if strings.Contains(*refs[i+1].Ref, userRelease) && strings.Contains(*refs[i+1].Ref, "beta") {
continue
} else {
return tag, nil
}
}
if rc && strings.Contains(tag, "rc") {
if strings.Contains(*refs[i+1].Ref, userRelease) && strings.Contains(*refs[i+1].Ref, "rc") {
continue
} else {
return tag, nil
}
}
if strings.Contains(*refs[i+1].Ref, userRelease) {
continue
}
return tag, nil
}
}
return "", ErrEmptyTags
}
// GetTagsRef retrieves all tags from golang/go
//
// Returns a list of tags reference if there is as least one
// or an error otherwise.
func (t *Tags) GetTagsRef() ([]*github.Reference, error) {
refs, response, err := t.client.Git.ListMatchingRefs(t.ctx, "golang", "go", &github.ReferenceListOptions{
Ref: "tags/go",
})
if err != nil {
return nil, err
}
if response.StatusCode != http.StatusOK {
fmt.Fprintf(os.Stderr, "%s: %d\n", ErrBadResponse.Error(), response.StatusCode)
return nil, ErrBadResponse
}
if len(refs) == 0 {
return nil, ErrEmptyTags
}
return refs, nil
}
// getLatestTag gather find the latest version of golang.
// beta and rc version can be specified.
//
// Returns the latest release or an error
func (t *Tags) getLatestTag(beta, rc bool) (string, error) {
refs, err := t.GetTagsRef()
if err != nil {
if err == ErrEmptyTags {
return "", nil
}
return "", err
}
for i := len(refs) - 1; i >= 0; i-- {
if (!beta && strings.Contains(*refs[i].Ref, "beta")) || (!rc && strings.Contains(*refs[i].Ref, "rc")) {
continue
}
if beta && strings.Contains(*refs[i].Ref, "beta") {
return strings.Split(*refs[i].Ref, "/")[2], nil
}
if rc && strings.Contains(*refs[i].Ref, "rc") {
return strings.Split(*refs[i].Ref, "/")[2], nil
}
if !strings.Contains(*refs[i].Ref, "beta") && !strings.Contains(*refs[i].Ref, "rc") {
return strings.Split(*refs[i].Ref, "/")[2], nil
}
}
return "", nil
}