Skip to content
This repository has been archived by the owner on Nov 22, 2022. It is now read-only.

Commit

Permalink
Merge pull request #445 from profclems/feat-release-create
Browse files Browse the repository at this point in the history
feat: add new `release` commands to manage GitLab releases
  • Loading branch information
profclems authored May 27, 2021
2 parents 4cb936d + f7a7342 commit a18cc9f
Show file tree
Hide file tree
Showing 24 changed files with 1,690 additions and 98 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/CHANGELOG.md

# GLab local config dir
/.glab-cli
.glab-cli
/test/testdata/.glab-cli

# Test binary, built with `go test -c`
Expand Down Expand Up @@ -45,4 +45,4 @@ test/testdata-*

coverage*
vendor
log.txt
log.txt.glab-cli
49 changes: 47 additions & 2 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
"strconv"
"strings"
"time"

"github.com/profclems/glab/internal/config"
Expand Down Expand Up @@ -80,9 +83,9 @@ func (c *Client) HTTPClient() *http.Client {
return c.httpClientOverride
}
if c.httpClient != nil {
return &http.Client{}
return c.httpClient
}
return c.httpClient
return &http.Client{}
}

// OverrideHTTPClient overrides the default http client
Expand Down Expand Up @@ -252,6 +255,48 @@ func (c *Client) BaseURL() *url.URL {
return c.Lab().BaseURL()
}

func NewHTTPRequest(c *Client, method string, baseURL *url.URL, body io.Reader, headers []string, bodyIsJSON bool) (*http.Request, error) {
req, err := http.NewRequest(method, baseURL.String(), body)
if err != nil {
return nil, err
}

for _, h := range headers {
idx := strings.IndexRune(h, ':')
if idx == -1 {
return nil, fmt.Errorf("header %q requires a value separated by ':'", h)
}
name, value := h[0:idx], strings.TrimSpace(h[idx+1:])
if strings.EqualFold(name, "Content-Length") {
length, err := strconv.ParseInt(value, 10, 0)
if err != nil {
return nil, err
}
req.ContentLength = length
} else {
req.Header.Add(name, value)
}
}

if bodyIsJSON && req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "application/json; charset=utf-8")
}

if c.Lab().UserAgent != "" {
req.Header.Set("User-Agent", c.Lab().UserAgent)
}

// TODO: support GITLAB_CI_TOKEN
switch c.AuthType {
case OAuthToken:
req.Header.Set("Authorization", "Bearer "+c.Token())
case PrivateToken:
req.Header.Set("PRIVATE-TOKEN", c.Token())
}

return req, nil
}

func TestClient(httpClient *http.Client, token, host string, isGraphQL bool) (*Client, error) {
testClient, err := NewClient(host, token, true, isGraphQL)
if err != nil {
Expand Down
14 changes: 14 additions & 0 deletions api/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@ package api

import "github.com/xanzy/go-gitlab"

var CreateRelease = func(client *gitlab.Client, projectID interface{}, opts *gitlab.CreateReleaseOptions) (*gitlab.Release, error) {
if client == nil {
client = apiClient.Lab()
}

release, _, err := client.Releases.CreateRelease(projectID, opts)
if err != nil {
return nil, err
}

return release, nil
}

var GetRelease = func(client *gitlab.Client, projectID interface{}, tag string) (*gitlab.Release, error) {
if client == nil {
client = apiClient.Lab()
Expand All @@ -14,6 +27,7 @@ var GetRelease = func(client *gitlab.Client, projectID interface{}, tag string)

return release, nil
}

var ListReleases = func(client *gitlab.Client, projectID interface{}, opts *gitlab.ListReleasesOptions) ([]*gitlab.Release, error) {
if client == nil {
client = apiClient.Lab()
Expand Down
58 changes: 39 additions & 19 deletions cmd/glab/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package main
import (
"errors"
"fmt"
"io"
"net"
"os"
"os/exec"
"strconv"
"strings"

"github.com/profclems/glab/pkg/iostreams"

"github.com/mgutz/ansi"

surveyCore "github.com/AlecAivazis/survey/v2/core"
Expand Down Expand Up @@ -72,7 +73,7 @@ func main() {

cfg, err := cmdFactory.Config()
if err != nil {
fmt.Fprintf(os.Stderr, "failed to read configuration: %s\n", err)
cmdFactory.IO.Logf("failed to read configuration: %s\n", err)
os.Exit(2)
}

Expand All @@ -99,7 +100,7 @@ func main() {
isShell := false
expandedArgs, isShell, err = expand.ExpandAlias(cfg, os.Args, nil)
if err != nil {
fmt.Fprintf(os.Stdout, "Failed to process alias: %s\n", err)
cmdFactory.IO.LogInfof("Failed to process alias: %s\n", err)
os.Exit(2)
}

Expand All @@ -120,7 +121,7 @@ func main() {
os.Exit(ee.ExitCode())
}

fmt.Fprintf(os.Stdout, "failed to run external command: %s", err)
cmdFactory.IO.LogInfof("failed to run external command: %s", err)
os.Exit(3)
}

Expand All @@ -138,9 +139,7 @@ func main() {
rootCmd.SetArgs(expandedArgs)

if cmd, err := rootCmd.ExecuteC(); err != nil {
printError(os.Stderr, err, cmd, debug)
cmd.Print("\n")
os.Exit(1)
printError(cmdFactory.IO, err, cmd, debug, true)
}

if help.HasFailed() {
Expand All @@ -151,33 +150,54 @@ func main() {
if checkUpdate, err := strconv.ParseBool(checkUpdate); err == nil && checkUpdate {
err = update.CheckUpdate(cmdFactory.IO, version, true)
if err != nil && debug {
printError(os.Stderr, err, rootCmd, debug)
printError(cmdFactory.IO, err, rootCmd, debug, false)
}
}
}

func printError(out io.Writer, err error, cmd *cobra.Command, debug bool) {
func printError(streams *iostreams.IOStreams, err error, cmd *cobra.Command, debug, shouldExit bool) {
if err == cmdutils.SilentError {
return
}
color := streams.Color()
printMore := true
exitCode := 1

var dnsError *net.DNSError
if errors.As(err, &dnsError) {
_, _ = fmt.Fprintf(out, "error connecting to %s\n", dnsError.Name)
streams.Logf("%s error connecting to %s\n", color.FailedIcon(), dnsError.Name)
if debug {
_, _ = fmt.Fprintln(out, dnsError)
streams.Log(color.FailedIcon(), dnsError)
}
_, _ = fmt.Fprintln(out, "check your internet connection or status.gitlab.com or 'Run sudo gitlab-ctl status' on your server if self-hosted")
return
streams.Logf("%s check your internet connection or status.gitlab.com or 'Run sudo gitlab-ctl status' on your server if self-hosted\n", color.DotWarnIcon())
printMore = false
}
_, _ = fmt.Fprintln(out, err)
if printMore {
var exitError *cmdutils.ExitError
if errors.As(err, &exitError) {
streams.Logf("%s %s %s=%s\n", color.FailedIcon(), color.Bold(exitError.Details), color.Red("error"), exitError.Err)
exitCode = exitError.Code
printMore = false
}

if printMore {
streams.Log(err)

var flagError *cmdutils.FlagError
if errors.As(err, &flagError) || strings.HasPrefix(err.Error(), "unknown command ") {
if !strings.HasSuffix(err.Error(), "\n") {
_, _ = fmt.Fprintln(out)
var flagError *cmdutils.FlagError
if errors.As(err, &flagError) || strings.HasPrefix(err.Error(), "unknown command ") {
if !strings.HasSuffix(err.Error(), "\n") {
streams.Log()
}
streams.Log(cmd.UsageString())
}
}
_, _ = fmt.Fprintln(out, cmd.UsageString())
}

if cmd != nil {
cmd.Print("\n")
}
if shouldExit {
os.Exit(exitCode)
}
}

Expand Down
22 changes: 13 additions & 9 deletions cmd/glab/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"net"
"testing"

"github.com/profclems/glab/pkg/iostreams"

"github.com/pkg/errors"
"github.com/profclems/glab/commands/cmdutils"
"github.com/spf13/cobra"
Expand All @@ -28,7 +30,7 @@ func Test_printError(t *testing.T) {
name: "generic error",
args: args{
err: errors.New("the app exploded"),
cmd: nil,
cmd: cmd,
debug: false,
},
wantOut: "the app exploded\n",
Expand All @@ -39,11 +41,11 @@ func Test_printError(t *testing.T) {
err: fmt.Errorf("DNS oopsie: %w", &net.DNSError{
Name: "https://gitlab.com/api/v4",
}),
cmd: nil,
cmd: cmd,
debug: false,
},
wantOut: `error connecting to https://gitlab.com/api/v4
check your internet connection or status.gitlab.com or 'Run sudo gitlab-ctl status' on your server if self-hosted
wantOut: `x error connecting to https://gitlab.com/api/v4
check your internet connection or status.gitlab.com or 'Run sudo gitlab-ctl status' on your server if self-hosted
`,
},
{
Expand All @@ -52,13 +54,13 @@ check your internet connection or status.gitlab.com or 'Run sudo gitlab-ctl stat
err: fmt.Errorf("DNS oopsie: %w", &net.DNSError{
Name: "https://gitlab.com/api/v4",
}),
cmd: nil,
cmd: cmd,
debug: true,
},

wantOut: `error connecting to https://gitlab.com/api/v4
lookup https://gitlab.com/api/v4:
check your internet connection or status.gitlab.com or 'Run sudo gitlab-ctl status' on your server if self-hosted
wantOut: `x error connecting to https://gitlab.com/api/v4
x lookup https://gitlab.com/api/v4:
check your internet connection or status.gitlab.com or 'Run sudo gitlab-ctl status' on your server if self-hosted
`,
},
{
Expand All @@ -83,8 +85,10 @@ check your internet connection or status.gitlab.com or 'Run sudo gitlab-ctl stat

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
streams, _, _, _ := iostreams.Test()
out := &bytes.Buffer{}
printError(out, tt.args.err, tt.args.cmd, tt.args.debug)
streams.StdErr = out
printError(streams, tt.args.err, tt.args.cmd, tt.args.debug, false)
if gotOut := out.String(); gotOut != tt.wantOut {
t.Errorf("printError() = %q, want %q", gotOut, tt.wantOut)
}
Expand Down
45 changes: 1 addition & 44 deletions commands/api/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"io"
"net/http"
"net/url"
"strconv"
"strings"

"github.com/profclems/glab/api"
Expand Down Expand Up @@ -68,7 +67,7 @@ func httpRequest(client *api.Client, config config.Config, hostname string, meth
}

baseURL, _ = url.Parse(baseURLStr)
req, err := newRequest(client, method, baseURL, body, client.LabClient.UserAgent, headers, bodyIsJSON)
req, err := api.NewHTTPRequest(client, method, baseURL, body, headers, bodyIsJSON)

if err != nil {
return nil, err
Expand Down Expand Up @@ -123,45 +122,3 @@ func parseQuery(path string, params map[string]interface{}) (string, error) {
}
return path + sep + q.Encode(), nil
}

func newRequest(c *api.Client, method string, baseURL *url.URL, body io.Reader, userAgent string, headers []string, bodyIsJSON bool) (*http.Request, error) {
req, err := http.NewRequest(method, baseURL.String(), body)
if err != nil {
return nil, err
}

for _, h := range headers {
idx := strings.IndexRune(h, ':')
if idx == -1 {
return nil, fmt.Errorf("header %q requires a value separated by ':'", h)
}
name, value := h[0:idx], strings.TrimSpace(h[idx+1:])
if strings.EqualFold(name, "Content-Length") {
length, err := strconv.ParseInt(value, 10, 0)
if err != nil {
return nil, err
}
req.ContentLength = length
} else {
req.Header.Add(name, value)
}
}

if bodyIsJSON && req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "application/json; charset=utf-8")
}

if userAgent != "" {
req.Header.Set("User-Agent", userAgent)
}

// TODO: support GITLAB_CI_TOKEN
switch c.AuthType {
case api.OAuthToken:
req.Header.Set("Authorization", "Bearer "+c.Token())
case api.PrivateToken:
req.Header.Set("PRIVATE-TOKEN", c.Token())
}

return req, nil
}
2 changes: 1 addition & 1 deletion commands/cmdutils/cmdutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ func Test_MilestonesPrompt(t *testing.T) {
ID: 240,
},
{
Title: "Get rid of low quality code",
Title: "Get rid of low quality Code",
ID: 650,
},
}
Expand Down
Loading

0 comments on commit a18cc9f

Please sign in to comment.