Skip to content

Commit

Permalink
(cmd/lint) add subcommand to validate .gitlab-ci.yml
Browse files Browse the repository at this point in the history
  • Loading branch information
zaquestion committed Dec 23, 2017
1 parent f338ef9 commit 4604b39
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 1 deletion.
18 changes: 18 additions & 0 deletions cmd/ci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package cmd

import (
"github.com/spf13/cobra"
)

// ciCmd represents the ci command
var ciCmd = &cobra.Command{
Use: "ci",
Short: "",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
},
}

func init() {
RootCmd.AddCommand(ciCmd)
}
38 changes: 38 additions & 0 deletions cmd/ciLint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package cmd

import (
"fmt"
"io/ioutil"
"log"
"os"

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

// ciLintCmd represents the lint command
var ciLintCmd = &cobra.Command{
Use: "lint",
Short: "Validate .gitlab-ci.yml against GitLab",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
path := ".gitlab-ci.yml"
if len(args) == 1 {
path = args[0]
}
b, err := ioutil.ReadFile(path)
if !os.IsNotExist(err) && err != nil {
log.Fatal(err)
}
ok, err := lab.Lint(string(b))
if !ok || err != nil {
log.Fatal(errors.Wrap(err, "ci yaml invalid"))
}
fmt.Println("Valid!")
},
}

func init() {
ciCmd.AddCommand(ciLintCmd)
}
21 changes: 21 additions & 0 deletions cmd/ciLint_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cmd

import (
"os/exec"
"testing"

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

func Test_ciLint(t *testing.T) {
repo := copyTestRepo(t)
cmd := exec.Command("../lab_bin", "ci", "lint")
cmd.Dir = repo

b, err := cmd.CombinedOutput()
if err != nil {
t.Log(string(b))
t.Fatal(err)
}
require.Contains(t, string(b), "Valid!")
}
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ var templateFuncs = template.FuncMap{
"rpad": rpad,
}

const labUsageTmpl = `{{range .Commands}}{{if (and (or .IsAvailableCommand (ne .Name "help")) (and (ne .Name "clone") (ne .Name "version")))}}
const labUsageTmpl = `{{range .Commands}}{{if (and (or .IsAvailableCommand (ne .Name "help")) (and (ne .Name "clone") (ne .Name "version") (ne .Name "ci")))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}`

func labUsage(c *cobra.Command) string {
Expand Down
14 changes: 14 additions & 0 deletions internal/gitlab/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,17 @@ func SnippetList(opts *gitlab.ListSnippetsOptions) ([]*gitlab.Snippet, error) {
}
return snips, nil
}

func Lint(content string) (bool, error) {
lint, resp, err := lab.Validate.Lint(content)
if err != nil {
return false, err
}
if os.Getenv("DEBUG") != "" {
fmt.Println(resp.Response.Status)
}
if len(lint.Errors) > 0 {
return false, errors.New(strings.Join(lint.Errors, " - "))
}
return lint.Status == "valid", nil
}
51 changes: 51 additions & 0 deletions internal/gitlab/gitlab_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"testing"

"github.com/spf13/viper"
"github.com/stretchr/testify/require"
)

Expand All @@ -13,6 +14,21 @@ func TestMain(m *testing.M) {
if err != nil {
log.Fatal(err)
}

viper.SetConfigName("lab")
viper.SetConfigType("hcl")
viper.AddConfigPath(".")
err = viper.ReadInConfig()
if err != nil {
log.Fatal(err)
}
c := viper.AllSettings()["core"]
config := c.([]map[string]interface{})[0]

Init(
config["host"].(string),
config["user"].(string),
config["token"].(string))
os.Exit(m.Run())
}

Expand All @@ -25,3 +41,38 @@ func TestLoadGitLabTmplIssue(t *testing.T) {
issueTmpl := LoadGitLabTmpl(TmplIssue)
require.Equal(t, issueTmpl, "I am the issue tmpl")
}

func TestLint(t *testing.T) {
tests := []struct {
desc string
content string
expected bool
}{
{
"Valid",
`build1:
stage: build
script:
- echo "Do your build here"`,
true,
},
{
"Invalid",
`build1:
- echo "Do your build here"`,
false,
},
{
"Empty",
``,
false,
},
}
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
test := test
ok, _ := Lint(test.content)
require.Equal(t, test.expected, ok)
})
}
}
32 changes: 32 additions & 0 deletions testdata/.gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
image: busybox:latest

before_script:
- echo "Before script section"
- echo "For example you might run an update here or install a build dependency"
- echo "Or perhaps you might print out some debugging details"

after_script:
- echo "After script section"
- echo "For example you might do some cleanup here"

build1:
stage: build
script:
- echo "Do your build here"

test1:
stage: test
script:
- echo "Do a test here"
- echo "For example run a test suite"

test2:
stage: test
script:
- echo "Do another parallel test here"
- echo "For example run a lint test"

deploy1:
stage: deploy
script:
- echo "Do your deploy here"

0 comments on commit 4604b39

Please sign in to comment.