Skip to content

Commit

Permalink
Merge pull request #24 from mdb/improve-repo-flag
Browse files Browse the repository at this point in the history
Improve repo flag and ensure it's properly set.
  • Loading branch information
mdb committed Nov 20, 2022
2 parents 7dfe0a5 + 2c3a6ff commit 3b484ea
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 56 deletions.
2 changes: 1 addition & 1 deletion Makefile
@@ -1,6 +1,6 @@
SOURCE=./...
GOFMT_FILES?=$$(find . -type f -name '*.go')
VERSION?=0.1.2
VERSION?=0.1.3

default: build

Expand Down
30 changes: 1 addition & 29 deletions cmd/main.go
@@ -1,44 +1,16 @@
package main

import (
"fmt"
"os"

"github.com/MakeNowJust/heredoc"
"github.com/cli/go-gh"
"github.com/mdb/gh-dispatch/internal/dispatch"
"github.com/spf13/cobra"
)

// version's value is passed in at build time.
var version string

func main() {
rootCmd := &cobra.Command{
Use: "gh dispatch",
Short: "Send a GitHub dispatch event and watch the resulting GitHub Actions run",
Long: heredoc.Doc(`
Send a workflow_dispatch or repository_dispatch event and watch the resulting
GitHub Actions run.
`),
SilenceUsage: true,
Version: version,
}

defaultRepo := ""
currentRepo, _ := gh.CurrentRepository()
if currentRepo != nil {
defaultRepo = fmt.Sprintf("%s/%s", currentRepo.Owner(), currentRepo.Name())
}

// TODO: how to make this required?
rootCmd.PersistentFlags().StringP("repo", "R", defaultRepo, "The targeted repository's full name (in 'owner/repo' format)")

repositoryCmd := dispatch.NewCmdRepository()
rootCmd.AddCommand(repositoryCmd)

workflowCmd := dispatch.NewCmdWorkflow()
rootCmd.AddCommand(workflowCmd)
rootCmd := dispatch.NewCmdRoot(version)

if err := rootCmd.Execute(); err != nil {
os.Exit(1)
Expand Down
2 changes: 1 addition & 1 deletion cmd/main_test.go
Expand Up @@ -41,7 +41,7 @@ Available Commands:
Flags:
-h, --help help for gh
-R, --repo string The targeted repository's full name (in 'owner/repo' format) (default "mdb/gh-dispatch")
-R, --repo string The targeted repository's full name (default "github.com/mdb/gh-dispatch")
-v, --version version for gh
Use "gh [command] --help" for more information about a command.
Expand Down
46 changes: 42 additions & 4 deletions internal/dispatch/ghrepo.go
@@ -1,19 +1,59 @@
package dispatch

import (
"errors"
"fmt"
"strings"

"github.com/cli/go-gh/pkg/auth"
"github.com/spf13/cobra"
)

func getRepoOption(cmd *cobra.Command) (*ghRepo, error) {
r, _ := cmd.Flags().GetString("repo")
if r == "" {
return nil, errors.New("A --repo must be specified in the [HOST/]OWNER/REPO format")
}

repo, err := newGHRepo(r)
if err != nil {
return nil, err
}

return repo, nil
}

// ghRepo satisfies the ghrepo interface.
// In the context of gh-dispatch, it enables the reuse of
// functions packaged in the upstream github.com/cli/cli
// codebase for rendering GH Actions run output.
// See github.com/cli/cli/v2/internal/ghrepo.
type ghRepo struct {
Name string
Owner string
Name string
Host string
}

func newGHRepo(name string) (*ghRepo, error) {
defaultHost, _ := auth.DefaultHost()
nameParts := strings.Split(name, "/")

switch len(nameParts) {
case 2:
return &ghRepo{
Owner: nameParts[0],
Name: nameParts[1],
Host: defaultHost,
}, nil
case 3:
return &ghRepo{
Owner: nameParts[1],
Name: nameParts[2],
Host: nameParts[0],
}, nil
default:
return nil, errors.New("invalid repository name")
}
}

func (r ghRepo) RepoName() string {
Expand All @@ -25,9 +65,7 @@ func (r ghRepo) RepoOwner() string {
}

func (r ghRepo) RepoHost() string {
host, _ := auth.DefaultHost()

return host
return r.Host
}

func (r ghRepo) RepoFullName() string {
Expand Down
57 changes: 48 additions & 9 deletions internal/dispatch/ghrepo_test.go
Expand Up @@ -6,14 +6,53 @@ import (
"github.com/stretchr/testify/assert"
)

func TestGHRepo(t *testing.T) {
ghRepo := &ghRepo{
Name: "REPO",
Owner: "OWNER",
}
func TestNewGHRepo(t *testing.T) {
tests := []struct {
name string
wantName string
wantOwner string
wantHost string
wantFullName string
wantErr bool
errMsg string
}{
{
name: "foo/bar",
wantOwner: "foo",
wantName: "bar",
wantFullName: "foo/bar",
wantHost: "github.com",
wantErr: false,
}, {
name: "other-github.com/foo/bar",
wantOwner: "foo",
wantName: "bar",
wantFullName: "foo/bar",
wantHost: "other-github.com",
wantErr: false,
}, {
name: "bar",
wantErr: true,
errMsg: "invalid repository name",
}, {
name: "",
wantErr: true,
errMsg: "invalid repository name",
}}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ghr, err := newGHRepo(tt.name)

assert.Equal(t, "OWNER/REPO", ghRepo.RepoFullName())
assert.Equal(t, "OWNER", ghRepo.RepoOwner())
assert.Equal(t, "REPO", ghRepo.RepoName())
assert.Equal(t, "github.com", ghRepo.RepoHost())
if tt.wantErr {
assert.EqualError(t, err, tt.errMsg)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.wantFullName, ghr.RepoFullName())
assert.Equal(t, tt.wantOwner, ghr.RepoOwner())
assert.Equal(t, tt.wantName, ghr.RepoName())
assert.Equal(t, tt.wantHost, ghr.RepoHost())
}
})
}
}
9 changes: 3 additions & 6 deletions internal/dispatch/repository.go
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"encoding/json"
"fmt"
"strings"

"github.com/MakeNowJust/heredoc"
cliapi "github.com/cli/cli/v2/api"
Expand Down Expand Up @@ -60,11 +59,9 @@ func NewCmdRepository() *cobra.Command {
--workflow Hello
`),
RunE: func(cmd *cobra.Command, args []string) error {
r, _ := cmd.Flags().GetString("repo")
repoParts := strings.Split(r, "/")
repo := &ghRepo{
Owner: repoParts[0],
Name: repoParts[1],
repo, err := getRepoOption(cmd)
if err != nil {
return err
}

b := []byte(repositoryClientPayload)
Expand Down
39 changes: 39 additions & 0 deletions internal/dispatch/root.go
@@ -0,0 +1,39 @@
package dispatch

import (
"fmt"

"github.com/MakeNowJust/heredoc"
"github.com/cli/go-gh"
"github.com/spf13/cobra"
)

func NewCmdRoot(version string) *cobra.Command {
rootCmd := &cobra.Command{
Use: "gh dispatch",
Short: "Send a GitHub dispatch event and watch the resulting GitHub Actions run",
Long: heredoc.Doc(`
Send a workflow_dispatch or repository_dispatch event and watch the resulting
GitHub Actions run.
`),
SilenceUsage: true,
Version: version,
}

defaultRepo := ""
currentRepo, _ := gh.CurrentRepository()
if currentRepo != nil {
defaultRepo = fmt.Sprintf("%s/%s/%s", currentRepo.Host(), currentRepo.Owner(), currentRepo.Name())
}

var repo string
rootCmd.PersistentFlags().StringVarP(&repo, "repo", "R", defaultRepo, "The targeted repository's full name")

repositoryCmd := NewCmdRepository()
rootCmd.AddCommand(repositoryCmd)

workflowCmd := NewCmdWorkflow()
rootCmd.AddCommand(workflowCmd)

return rootCmd
}
3 changes: 3 additions & 0 deletions internal/dispatch/types.go
@@ -1,12 +1,15 @@
package dispatch

import (
"errors"
"net/http"

"github.com/cli/cli/v2/pkg/cmd/run/shared"
"github.com/cli/cli/v2/pkg/iostreams"
)

var errUnspecifiedRepo = errors.New("A --repo must be specified in the [HOST/]OWNER/REPO format")

type workflowRun struct {
ID int64 `json:"id"`
WorkflowID int `json:"workflow_id"`
Expand Down
9 changes: 3 additions & 6 deletions internal/dispatch/workflow.go
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"encoding/json"
"fmt"
"strings"

"github.com/MakeNowJust/heredoc"
cliapi "github.com/cli/cli/v2/api"
Expand Down Expand Up @@ -65,11 +64,9 @@ func NewCmdWorkflow() *cobra.Command {
--ref my-feature-branch
`),
RunE: func(cmd *cobra.Command, args []string) error {
r, _ := cmd.Flags().GetString("repo")
repoParts := strings.Split(r, "/")
repo := &ghRepo{
Owner: repoParts[0],
Name: repoParts[1],
repo, err := getRepoOption(cmd)
if err != nil {
return err
}

b := []byte(workflowInputs)
Expand Down

0 comments on commit 3b484ea

Please sign in to comment.