From b74d17477f0da4c01827353d86620a054cdf0c90 Mon Sep 17 00:00:00 2001 From: Emmanuel Roux <15956441+fesaille@users.noreply.github.com> Date: Sat, 5 Oct 2024 20:19:11 +0200 Subject: [PATCH] feat: add glab cli Closes #1119 Signed-off-by: Emmanuel Roux --- pkg/get/get.go | 50 +++++++++++++++++++++++++++++++++++++++++++ pkg/get/get_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++++ pkg/get/tools.go | 36 +++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+) diff --git a/pkg/get/get.go b/pkg/get/get.go index 16122dc8b..f4595e90b 100644 --- a/pkg/get/get.go +++ b/pkg/get/get.go @@ -3,6 +3,7 @@ package get import ( "bytes" "crypto/tls" + "encoding/json" "errors" "fmt" "io" @@ -18,6 +19,7 @@ import ( ) const GitHubVersionStrategy = "github" +const GitLabVersionStrategy = "gitlab" const k8sVersionStrategy = "k8s" var supportedOS = [...]string{"linux", "darwin", "ming"} @@ -25,6 +27,7 @@ var supportedArchitectures = [...]string{"x86_64", "arm", "amd64", "armv6l", "ar // githubTimeout expanded from the original 5 seconds due to #693 var githubTimeout = time.Second * 10 +var gitlabTimeout = time.Second * 5 // Tool describes how to download a CLI tool from a binary // release - whether a single binary, or an archive. @@ -157,6 +160,14 @@ func (tool Tool) GetURL(os, arch, version string, quiet bool) (string, error) { return "", err } version = v + } else if strings.Contains(tool.URLTemplate, "https://gitlab.com/") || + tool.VersionStrategy == GitLabVersionStrategy { + + v, err := FindGitLabRelease(tool.Owner, tool.Repo) + if err != nil { + return "", fmt.Errorf("failed to find GitLab release: %w", err) + } + version = v } if tool.VersionStrategy == k8sVersionStrategy { @@ -245,6 +256,45 @@ func FindGitHubRelease(owner, repo string) (string, error) { return version, nil } +func FindGitLabRelease(owner, repo string) (string, error) { + url := fmt.Sprintf("https://gitlab.com/api/v4/projects/%s%%2F%s/releases", owner, repo) + + client := makeHTTPClient(&gitlabTimeout, false) + client.CheckRedirect = func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + } + + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return "", err + } + + req.Header.Set("User-Agent", "arkade") + + res, err := client.Do(req) + if err != nil { + return "", err + } + + if res.StatusCode != http.StatusOK { + return "", fmt.Errorf("server returned status: %d", res.StatusCode) + } + + var releases []struct { + TagName string `json:"tag_name"` + } + + if err := json.NewDecoder(res.Body).Decode(&releases); err != nil { + return "", err + } + + if len(releases) == 0 { + return "", fmt.Errorf("no releases found for the repository") + } + + return releases[0].TagName, nil +} + func FindK8sRelease() (string, error) { url := "https://cdn.dl.k8s.io/release/stable.txt" diff --git a/pkg/get/get_test.go b/pkg/get/get_test.go index 19921efd3..340bde93d 100644 --- a/pkg/get/get_test.go +++ b/pkg/get/get_test.go @@ -1725,6 +1725,58 @@ func Test_DownloadGH(t *testing.T) { } } +func Test_DownloadGlab(t *testing.T) { + tools := MakeTools() + name := "glab" + + tool := getTool(name, tools) + + const toolVersion = "v1.47.0" + + tests := []test{ + { + os: "mingw64_nt-10.0-18362", + arch: arch64bit, + version: toolVersion, + url: `https://gitlab.com/gitlab-org/cli/-/releases/v1.47.0/downloads/glab_1.47.0_windows_amd64.zip`, + }, + { + os: "linux", + arch: arch64bit, + version: toolVersion, + url: `https://gitlab.com/gitlab-org/cli/-/releases/v1.47.0/downloads/glab_1.47.0_linux_am64.tar.gz`, + }, + { + os: "darwin", + arch: arch64bit, + version: toolVersion, + url: `https://gitlab.com/gitlab-org/cli/-/releases/v1.47.0/downloads/glab_1.47.0_darwin_amd64.tar.gz`, + }, + { + os: "darwin", + arch: archARM64, + version: toolVersion, + url: `https://gitlab.com/gitlab-org/cli/-/releases/v1.47.0/downloads/glab_1.47.0_darwin_arm64.tar.gz`, + }, + { + os: "linux", + arch: archARM64, + version: toolVersion, + url: `https://gitlab.com/gitlab-org/cli/-/releases/v1.47.0/downloads/glab_1.47.0_linux_arm64.tar.gz`, + }, + } + + for _, tc := range tests { + got, err := tool.GetURL(tc.os, tc.arch, tc.version, false) + if err != nil { + t.Fatal(err) + } + if got != tc.url { + t.Errorf("want: %s, got: %s", tc.url, got) + } + } +} + func Test_DownloadPack(t *testing.T) { tools := MakeTools() name := "pack" diff --git a/pkg/get/tools.go b/pkg/get/tools.go index a8c83bb38..120dc450b 100644 --- a/pkg/get/tools.go +++ b/pkg/get/tools.go @@ -1086,6 +1086,42 @@ https://github.com/inlets/inletsctl/releases/download/{{.Version}}/{{$fileName}} {{.Version}}/gh_{{.VersionNumber}}_{{$osStr}}_{{$archStr}}.{{$extStr}}`, }) + tools = append(tools, + Tool{ + Owner: "gitlab-org", + Repo: "cli", + Name: "glab", + VersionStrategy: GitLabVersionStrategy, + Description: "A GitLab CLI tool bringing GitLab to your command line.", + URLTemplate: ` + {{$arch := .Arch}} + {{- if eq .Arch "x86_64" -}} + {{$arch = "amd64"}} + {{- else if eq .Arch "armv6l" -}} + {{$arch = "armv6"}} + {{- else if eq .Arch "aarch64" -}} + {{$arch = "arm64"}} + {{- else if eq .Arch "i386" -}} + {{$arch = "386"}} + {{- end -}} + + {{$osStr := ""}} + {{- if eq .OS "linux" -}} + {{$osStr = "linux"}} + {{- else if eq .OS "darwin" -}} + {{$osStr = "darwin"}} + {{- else if HasPrefix .OS "ming" -}} + {{$osStr = "windows"}} + {{- end -}} + + {{$extStr := "tar.gz"}} + {{- if HasPrefix .OS "ming" -}} + {{$extStr = "zip"}} + {{- end -}} + + https://gitlab.com/{{.Owner}}/{{.Repo}}/-/releases/{{.Version}}/downloads/{{.Name}}_{{.VersionNumber}}_{{$osStr}}_{{$arch}}.{{$extStr}}`, + }) + tools = append(tools, Tool{ Owner: "buildpacks",