Skip to content

Commit

Permalink
(ci status) support a short text based pipeline/job status
Browse files Browse the repository at this point in the history
To address #261 & through the use of `--wait` hopefully #240
  • Loading branch information
zaquestion committed Jan 8, 2019
1 parent 78c18e0 commit ca87d10
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 7 deletions.
90 changes: 90 additions & 0 deletions cmd/ci_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package cmd

import (
"fmt"
"log"
"os"
"text/tabwriter"

"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/zaquestion/lab/internal/git"
lab "github.com/zaquestion/lab/internal/gitlab"
)

// ciStatusCmd represents the run command
var ciStatusCmd = &cobra.Command{
Use: "status [branch]",
Aliases: []string{"run"},
Short: "Textual representation of a CI pipeline",
Long: ``,
Example: `lab ci status
lab ci status --wait`,
RunE: nil,
Run: func(cmd *cobra.Command, args []string) {
branch, err := git.CurrentBranch()
if err != nil {
log.Fatal(err)
}

if len(args) > 1 {
branch = args[1]
}
remote := determineSourceRemote(branch)
if len(args) > 0 {
ok, err := git.IsRemote(args[0])
if err != nil || !ok {
log.Fatal(args[0], " is not a remote:", err)
}
remote = args[0]
}
rn, err := git.PathWithNameSpace(remote)
if err != nil {
log.Fatal(err)
}
pid := rn

w := tabwriter.NewWriter(os.Stdout, 2, 4, 1, byte(' '), 0)
jobs, err := lab.CIJobs(pid, branch)
if err != nil {
log.Fatal(errors.Wrap(err, "failed to find ci jobs"))
}
jobs = latestJobs(jobs)

if len(jobs) == 0 {
return
}

wait, err := cmd.Flags().GetBool("wait")
if err != nil {
log.Fatal(err)
}

fmt.Fprintln(w, "Stage:\tName\t-\tStatus")
for {
for _, job := range jobs {
fmt.Fprintf(w, "%s:\t%s\t-\t%s\n", job.Stage, job.Name, job.Status)
}
if !wait {
break
}
if jobs[0].Pipeline.Status != "pending" &&
jobs[0].Pipeline.Status != "running" {
break
}
fmt.Fprintln(w)
}

fmt.Fprintf(w, "\nPipeline Status: %s\n", jobs[0].Pipeline.Status)
if wait && jobs[0].Pipeline.Status != "success" {
os.Exit(1)
}
w.Flush()
},
}

func init() {
ciStatusCmd.MarkZshCompPositionalArgumentCustom(1, "__lab_completion_remote_branches")
ciStatusCmd.Flags().Bool("wait", false, "Continuously print the status and wait to exit until the pipeline finishes. Exit code indicates pipeline status")
ciCmd.AddCommand(ciStatusCmd)
}
65 changes: 65 additions & 0 deletions cmd/ci_status_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package cmd

import (
"os/exec"
"testing"

"github.com/stretchr/testify/assert"
)

func Test_ciStatus(t *testing.T) {
t.Parallel()
repo := copyTestRepo(t)
cmd := exec.Command("../lab_bin", "fetch", "origin")
cmd.Dir = repo
if b, err := cmd.CombinedOutput(); err != nil {
t.Log(string(b))
t.Fatal(err)
}

cmd = exec.Command("../lab_bin", "checkout", "origin/ci_test_pipeline")
cmd.Dir = repo
if b, err := cmd.CombinedOutput(); err != nil {
t.Log(string(b))
t.Fatal(err)
}

cmd = exec.Command("../lab_bin", "checkout", "-b", "ci_test_pipeline")
cmd.Dir = repo
if b, err := cmd.CombinedOutput(); err != nil {
t.Log(string(b))
t.Fatal(err)
}

cmd = exec.Command("../lab_bin", "ci", "status")
cmd.Dir = repo

b, err := cmd.CombinedOutput()
if err != nil {
t.Log(string(b))
t.Fatal(err)
}
out := string(b)
assert.Contains(t, out, `Stage: Name - Status
build: build1 - success
build: build2 - success
build: build2:fails - failed
test: test1 - success
test: test2 - success
test: test2:really_a_long_name_for - success
test: test2:no_suffix:test - success
test: test3 - success
deploy: deploy1 - success
deploy: deploy2 - manual
deploy: deploy3:no_sufix:deploy - success
deploy: deploy4 - success
deploy: deploy5:really_a_long_name_for - success
deploy: deploy5 - success
deploy: deploy6 - success
deploy: deploy7 - success
deploy: deploy8 - success
deploy: deploy9 - success
deploy: deploy10 - success`)

assert.Contains(t, out, "Pipeline Status: success")
}
8 changes: 3 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ require (
github.com/derekparker/delve v1.1.0
github.com/gdamore/encoding v0.0.0-20151215212835-b23993cbb635 // indirect
github.com/gdamore/tcell v0.0.0-20180416163743-2f258105ca8c
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 // indirect
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
Expand All @@ -33,12 +32,11 @@ require (
github.com/spf13/viper v0.0.0-20180507071007-15738813a09d
github.com/stretchr/testify v1.2.2
github.com/tcnksm/go-gitconfig v0.1.2
github.com/xanzy/go-gitlab v0.11.3
github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad // indirect
github.com/xanzy/go-gitlab v0.12.3-0.20181228114601-7bc4155e8bf8
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 // indirect
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793
golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc // indirect
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f // indirect
google.golang.org/appengine v1.1.0 // indirect
golang.org/x/tools v0.0.0-20190107155254-e063def13b29 // indirect
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 // indirect
)

Expand Down
16 changes: 16 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0=
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGEZ+pEmF1OnWuu8AQ9I8iNbHNeno=
Expand Down Expand Up @@ -82,20 +84,31 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPgXBPw=
github.com/tcnksm/go-gitconfig v0.1.2/go.mod h1:/8EhP4H7oJZdIPyT+/UIsG87kTzrzM4UsLGSItWYCpE=
github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad h1:W0LEBv82YCGEtcmPA3uNZBI33/qF//HAAs3MawDjRa0=
github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+MXnS6EwGElrSRjUzQDLXreJlzYLlWiHtt8hM=
github.com/xanzy/go-gitlab v0.0.0-20180921132519-8d21e61ce4a9 h1:gmCeo/bSUp/oLKpsZrICPRTgwsuI3m17l5c2X8y4/0g=
github.com/xanzy/go-gitlab v0.0.0-20180921132519-8d21e61ce4a9/go.mod h1:CRKHkvFWNU6C3AEfqLWjnCNnAs4nj8Zk95rX2S3X6Mw=
github.com/xanzy/go-gitlab v0.11.3 h1:gSYcSb+pCx3fco6/O3w784/omQVTcrgxRzyf14SBvUQ=
github.com/xanzy/go-gitlab v0.11.3/go.mod h1:CRKHkvFWNU6C3AEfqLWjnCNnAs4nj8Zk95rX2S3X6Mw=
github.com/xanzy/go-gitlab v0.12.2 h1:WQY08U/RwrEx1i3x2Fnzsj/oCAzMYMKpk5cq+kHN4Vo=
github.com/xanzy/go-gitlab v0.12.2/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
github.com/xanzy/go-gitlab v0.12.3-0.20181228114601-7bc4155e8bf8 h1:POfZqSXz6Rr3hKp1tfYDH8L28/1lDLaa6CJnFrrxY/0=
github.com/xanzy/go-gitlab v0.12.3-0.20181228114601-7bc4155e8bf8/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 h1:Pn8fQdvx+z1avAi7fdM2kRYWQNxGlavNDSyzrQg2SsU=
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
golang.org/x/crypto v0.0.0-20180420171155-e73bf333ef89 h1:YMKUzb2eHV8HdgAr0z9lbGN1Av2h4cgMMsvi+JV60MM=
golang.org/x/crypto v0.0.0-20180420171155-e73bf333ef89/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181108082009-03003ca0c849 h1:FSqE2GGG7wzsYUsWiQ8MZrvEd1EOyU3NCF0AW3Wtltg=
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc h1:3ElrZeO6IBP+M8kgu5YFwRo92Gqr+zBg3aooYQ6ziqU=
golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288 h1:JIqe8uIcRBHXDQVvZtHwp80ai3Lw3IJAeJEs55Dc1W0=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -104,8 +117,11 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUk
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190107155254-e063def13b29 h1:mtLB/BpwjjSIylF0++D6EG1ExPVEIcFKMMwK6HFmbtU=
golang.org/x/tools v0.0.0-20190107155254-e063def13b29/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY=
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
Expand Down
4 changes: 2 additions & 2 deletions internal/gitlab/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func MRGet(project string, mrNum int) (*gitlab.MergeRequest, error) {
return nil, err
}

mr, _, err := lab.MergeRequests.GetMergeRequest(p.ID, mrNum)
mr, _, err := lab.MergeRequests.GetMergeRequest(p.ID, mrNum, nil)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -224,7 +224,7 @@ func MRList(project string, opts gitlab.ListProjectMergeRequestsOptions, n int)

// MRClose closes an mr on a GitLab project
func MRClose(pid interface{}, id int) error {
mr, _, err := lab.MergeRequests.GetMergeRequest(pid, id)
mr, _, err := lab.MergeRequests.GetMergeRequest(pid, id, nil)
if err != nil {
return err
}
Expand Down

0 comments on commit ca87d10

Please sign in to comment.