forked from bazelbuild/bazelisk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
github.go
102 lines (85 loc) · 3.29 KB
/
github.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package repositories
import (
"encoding/json"
"fmt"
"github.com/bazelbuild/bazelisk/httputil"
"github.com/bazelbuild/bazelisk/platforms"
"github.com/bazelbuild/bazelisk/versions"
)
const (
urlPattern = "https://github.com/%s/bazel/releases/download/%s/%s"
)
// GitHubRepo represents a fork of Bazel hosted on GitHub, and provides a list of all available Bazel binaries in that repo, as well as the ability to download them.
type GitHubRepo struct {
token string
}
// CreateGitHubRepo instantiates a new GitHubRepo.
func CreateGitHubRepo(token string) *GitHubRepo {
return &GitHubRepo{token}
}
// ForkRepo
// GetVersions returns the versions of all available Bazel binaries in the given fork.
func (gh *GitHubRepo) GetVersions(bazeliskHome, bazelFork string) ([]string, error) {
return gh.getFilteredVersions(bazeliskHome, bazelFork, false)
}
func (gh *GitHubRepo) getFilteredVersions(bazeliskHome, bazelFork string, wantPrerelease bool) ([]string, error) {
parse := func(data []byte) ([]gitHubRelease, error) {
var releases []gitHubRelease
if err := json.Unmarshal(data, &releases); err != nil {
return nil, fmt.Errorf("could not parse JSON into list of releases: %v", err)
}
return releases, nil
}
var releases []gitHubRelease
merger := func(chunks [][]byte) ([]byte, error) {
for _, chunk := range chunks {
current, err := parse(chunk)
if err != nil {
return nil, err
}
releases = append(releases, current...)
}
return json.Marshal(releases)
}
url := fmt.Sprintf("https://api.github.com/repos/%s/bazel/releases", bazelFork)
releasesJSON, err := httputil.MaybeDownload(bazeliskHome, url, bazelFork+"-releases.json", "list of Bazel releases from github.com/"+bazelFork, fmt.Sprintf("token %s", gh.token), merger)
if err != nil {
return []string{}, fmt.Errorf("unable to dermine '%s' releases: %v", bazelFork, err)
}
if len(releases) == 0 {
releases, err = parse(releasesJSON)
if err != nil {
return nil, err
}
}
var tags []string
for _, release := range releases {
if release.Prerelease != wantPrerelease {
continue
}
tags = append(tags, release.TagName)
}
return tags, nil
}
type gitHubRelease struct {
TagName string `json:"tag_name"`
Prerelease bool `json:"prerelease"`
}
// DownloadVersion downloads a Bazel binary for the given version and fork to the specified location and returns the absolute path.
func (gh *GitHubRepo) DownloadVersion(fork, version, destDir, destFile string) (string, error) {
filename, err := platforms.DetermineBazelFilename(version, true)
if err != nil {
return "", err
}
url := fmt.Sprintf(urlPattern, fork, version, filename)
return httputil.DownloadBinary(url, destDir, destFile)
}
// GetRollingVersions returns a list of all available rolling release versions.
func (gh *GitHubRepo) GetRollingVersions(bazeliskHome string) ([]string, error) {
// Release candidates are uploaded to GCS only, which means that all prerelease binaries on GitHub belong to rolling releases.
return gh.getFilteredVersions(bazeliskHome, versions.BazelUpstream, true)
}
// DownloadRolling downloads the given Bazel version into the specified location and returns the absolute path.
func (gh *GitHubRepo) DownloadRolling(version, destDir, destFile string) (string, error) {
return gh.DownloadVersion(versions.BazelUpstream, version, destDir, destFile)
}