Skip to content

Commit

Permalink
feat(cmd): add support for cmd (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
gkampitakis authored Feb 19, 2023
1 parent b6312a4 commit 123e2e9
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ format: ## Format code

test: ## Run tests
go test -test.timeout 120s -count=1 .
go test -test.timeout 120s -count=1 ./ciinfo/

test-verbose: ## Run tests with verbose output
go test -test.timeout 120s -v -cover -count=1 .
go test -test.timeout 120s -v -cover -count=1 ./ciinfo/

compile-constants: ## Generates 'constants.go' containing the list with constant values
cp vendors.go compile-constants
Expand Down
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,33 @@ if ciinfo.IsCI {
}
```

## CLI Support

`ciinfo` can also be used as a CLI. You can install it with

```sh
go install github.com/gkampitakis/ciinfo/ciinfo
```

Then `ciinfo` command will be successful ( code 0 ) if running on CI else error ( code -1 ).


```sh
# will output isCI if running onCI
ciinfo && echo 'isCI'
```

`ciinfo` also has

```shell
Usage of ciinfo:
-output string
you can output info [json, pretty].
-pr
check if shell is running on CI for a Pull Request.
```
## Supported CI tools
Officially supported CI servers:
Expand Down
78 changes: 78 additions & 0 deletions ciinfo/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package main

import (
"flag"
"fmt"
"io"
"os"

"github.com/gkampitakis/ciinfo"
)

const (
YES = 0
NO = -1
)

func main() {
isPr := flag.Bool("pr", false, "check if shell is running on CI for a Pull Request.")
output := flag.String("output", "", "you can output info [json, pretty].")

flag.Parse()

run(os.Exit, os.Stdout, *isPr, *output)
}

func run(exit func(int), w io.Writer, isPR bool, output string) {
result := NO

if isPR {
if ciinfo.IsPr {
result = YES
}

exit(result)
}

if output == "json" {
jsonPrint(w)
return
}

if output == "pretty" {
prettyPrint(w)
return
}

if ciinfo.IsCI {
result = YES
}

exit(result)
}

func jsonPrint(w io.Writer) {
fmt.Fprintf(w, `{
"is_ci": %t,
"ci_name": "%s",
"pull_request": %t
}
`, ciinfo.IsCI, ciinfo.Name, ciinfo.IsPr)
}

func prettyPrint(w io.Writer) {
if !ciinfo.IsCI {
fmt.Fprintln(w, "Not running on CI.")
return
}

if ciinfo.Name != "" {
fmt.Fprintf(w, "CI Name: %s\n", ciinfo.Name)
} else {
fmt.Fprintln(w, "Running on CI.")
}

if ciinfo.IsPr {
fmt.Fprintln(w, "Is Pull Request.")
}
}
137 changes: 137 additions & 0 deletions ciinfo/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package main

import (
"io"
"strings"
"testing"

"github.com/gkampitakis/ciinfo"
)

func mockExit(t *testing.T, expectedCode int) func(int) {
t.Helper()
return func(i int) {
if i != expectedCode {
t.Errorf("expected code: %d but got: %d\n", expectedCode, i)
}
}
}

type mockWriter struct {
mockWrite func([]byte)
}

func (m mockWriter) Write(p []byte) (int, error) {
m.mockWrite(p)
return 0, nil
}

func TestCMD(t *testing.T) {
t.Run("should be successful in case of pr", func(t *testing.T) {
ciinfo.IsPr = true

run(mockExit(t, 0), io.Discard, true, "")
})

t.Run("should exit with error in case not being a pr", func(t *testing.T) {
ciinfo.IsPr = false
ciinfo.IsCI = false

run(mockExit(t, -1), io.Discard, true, "")
})

t.Run("should print json output", func(t *testing.T) {
ciinfo.IsPr = true
ciinfo.Name = "mock-ci"
ciinfo.IsCI = true

m := mockWriter{
mockWrite: func(b []byte) {
// clean up tabs,spaces and newlines
chars := []string{" ", "\n", "\t"}
v := string(b)
for _, c := range chars {
v = strings.ReplaceAll(v, c, "")
}

if v != `{"is_ci":true,"ci_name":"mock-ci","pull_request":true}` {
t.Error("expected json format")
}
},
}

run(nil, m, false, "json")
})

t.Run("should print pretty output when not on ci", func(t *testing.T) {
ciinfo.IsCI = false

m := mockWriter{
mockWrite: func(b []byte) {
if string(b) != "Not running on CI.\n" {
t.Error("expected not running on CI.")
}
},
}

run(nil, m, false, "pretty")
})

t.Run("should print pretty output", func(t *testing.T) {
ciinfo.IsPr = true
ciinfo.Name = "mock-ci"
ciinfo.IsCI = true
msgs := []string{
"CI Name: mock-ci\n",
"Is Pull Request.\n",
}

m := mockWriter{
mockWrite: func(b []byte) {
msg := msgs[0]
msgs = msgs[1:]
if string(b) != msg {
t.Errorf("unexpected message: %s", string(b))
}
},
}

run(nil, m, false, "pretty")
})

t.Run("should print pretty output without name", func(t *testing.T) {
ciinfo.IsPr = true
ciinfo.Name = ""
ciinfo.IsCI = true
msgs := []string{
"Running on CI.\n",
"Is Pull Request.\n",
}

m := mockWriter{
mockWrite: func(b []byte) {
msg := msgs[0]
msgs = msgs[1:]
if string(b) != msg {
t.Errorf("unexpected message: %s", string(b))
}
},
}

run(nil, m, false, "pretty")
})

t.Run("should be successful code", func(t *testing.T) {
ciinfo.IsPr = true
ciinfo.Name = "mock-ci"
ciinfo.IsCI = true

run(mockExit(t, 0), io.Discard, false, "")
})

t.Run("should be error code", func(t *testing.T) {
ciinfo.IsCI = false

run(mockExit(t, -1), io.Discard, false, "")
})
}

0 comments on commit 123e2e9

Please sign in to comment.