2022-06-14 21:34:57 +02:00
|
|
|
package pkg
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
2022-06-14 23:04:38 +02:00
|
|
|
"os"
|
2022-06-14 21:34:57 +02:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/google/go-github/v45/github"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
ErrBadResponse = errors.New("github API responde with a non success code")
|
|
|
|
ErrEmptyTags = errors.New("no tags found")
|
|
|
|
)
|
|
|
|
|
2022-06-14 23:11:56 +02:00
|
|
|
type TagsAction interface {
|
|
|
|
CheckReleaseExists(beta, rc bool) (string, error)
|
|
|
|
getTagsRef() ([]*github.Reference, error)
|
|
|
|
getLatestRelease(beta, rc bool) (string, error)
|
|
|
|
}
|
|
|
|
|
2022-06-14 21:34:57 +02:00
|
|
|
type Tags struct {
|
|
|
|
release string
|
|
|
|
client github.Client
|
|
|
|
ctx context.Context
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewTags(release string, ctx context.Context) Tags {
|
|
|
|
return Tags{
|
|
|
|
release: release,
|
|
|
|
client: *github.NewClient(nil),
|
|
|
|
ctx: ctx,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-14 23:11:56 +02:00
|
|
|
// GetRelease retrieves tags from "golang/go" and check whether
|
2022-06-14 21:34:57 +02:00
|
|
|
// the given release exists in it
|
2022-06-14 23:11:56 +02:00
|
|
|
//
|
|
|
|
// Returns the found release or an error
|
|
|
|
func (t Tags) GetRelease(beta, rc bool) (string, error) {
|
2022-06-14 23:04:38 +02:00
|
|
|
if t.release == "lts" {
|
2022-06-14 23:11:56 +02:00
|
|
|
return t.getLatestTag(beta, rc)
|
2022-06-14 23:04:38 +02:00
|
|
|
}
|
2022-06-14 21:34:57 +02:00
|
|
|
|
2022-06-14 23:04:38 +02:00
|
|
|
refs, err := t.getTagsRef()
|
2022-06-14 21:34:57 +02:00
|
|
|
if err != nil {
|
2022-06-14 23:04:38 +02:00
|
|
|
if err == ErrEmptyTags {
|
|
|
|
return "", nil
|
|
|
|
}
|
2022-06-14 21:34:57 +02:00
|
|
|
return "", err
|
|
|
|
}
|
2022-06-14 23:04:38 +02:00
|
|
|
for i, ref := range refs {
|
2022-06-14 21:34:57 +02:00
|
|
|
userRelease := fmt.Sprintf("go%s", t.release)
|
2022-06-14 23:04:38 +02:00
|
|
|
tag := strings.Split(*ref.Ref, "/")[2]
|
|
|
|
|
|
|
|
if strings.Contains(tag, userRelease) {
|
|
|
|
if (!beta && strings.Contains(tag, "beta")) || (!rc && strings.Contains(tag, "rc")) {
|
2022-06-14 21:34:57 +02:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2022-06-14 23:04:38 +02:00
|
|
|
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) {
|
2022-06-14 21:34:57 +02:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2022-06-14 23:04:38 +02:00
|
|
|
return tag, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "", nil
|
|
|
|
}
|
|
|
|
|
2022-06-14 23:11:56 +02:00
|
|
|
// getTagsRef retrieves all tags from golang/go
|
2022-06-14 23:04:38 +02:00
|
|
|
//
|
2022-06-14 23:11:56 +02:00
|
|
|
// Returns a list of tags reference if there is as least one
|
|
|
|
// or an error otherwise.
|
2022-06-14 23:04:38 +02:00
|
|
|
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, "non success github status code %d\n", response.StatusCode)
|
|
|
|
return nil, ErrBadResponse
|
|
|
|
}
|
|
|
|
if len(refs) == 0 {
|
|
|
|
return nil, ErrEmptyTags
|
|
|
|
}
|
|
|
|
|
|
|
|
return refs, nil
|
|
|
|
}
|
|
|
|
|
2022-06-14 23:11:56 +02:00
|
|
|
// 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) {
|
2022-06-14 23:04:38 +02:00
|
|
|
refs, err := t.getTagsRef()
|
|
|
|
if err != nil {
|
|
|
|
if err == ErrEmptyTags {
|
2022-06-14 21:34:57 +02:00
|
|
|
return "", nil
|
|
|
|
}
|
2022-06-14 23:04:38 +02:00
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("len(tags): %v\n", len(refs))
|
|
|
|
for i := len(refs) - 1; i >= 0; i-- {
|
|
|
|
fmt.Printf("[%d] tags[i].Name: %v\n", i, *refs[i].Ref)
|
|
|
|
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
|
|
|
|
}
|
2022-06-14 21:34:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return "", nil
|
|
|
|
}
|