Skip to content

Commit

Permalink
add --dir-name optional flag to CLI (#317)
Browse files Browse the repository at this point in the history
  • Loading branch information
ronenlu authored Sep 26, 2023
1 parent 2dc41bd commit 96b183f
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 17 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-go.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
gh extension install .
- name: run GitHub atlas extension
run: |
gh atlas init-action -R ${{ secrets.TEST_REPO }} --token=${{ secrets.TEST_ATLAS_TOKEN }} --driver="sqlite" "sqlite_dir"
gh atlas init-action -R ${{ secrets.TEST_REPO }} --token=${{ secrets.TEST_ATLAS_TOKEN }} --dir-name="test-sqlite" --driver="sqlite" "sqlite_dir"
- name: validate pull request is created
uses: nick-fields/retry@v2
with:
Expand Down
16 changes: 16 additions & 0 deletions cloudapi/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,19 @@ func (c *Client) ValidateToken(ctx context.Context) error {
)
return c.post(ctx, query, vars, &payload)
}

// DirNames fetches the names of all migration directories from the Atlas Cloud API.
func (c *Client) DirNames(ctx context.Context) ([]string, error) {
var (
payload struct {
DirSlugs []string `json:"dirSlugs"`
}
query = `query {
dirSlugs
}`
)
if err := c.post(ctx, query, nil, &payload); err != nil {
return nil, err
}
return payload.DirSlugs, nil
}
17 changes: 14 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ var cli struct {
// InitActionCmd is the command for initializing a new Atlas CI workflow.
type InitActionCmd struct {
DirPath string `arg:"" optional:"" type:"-path" help:"Path inside repository containing the migration files."`
DirName string `arg:"" optional:"" type:"-dir-name" help:"Target migration directory name (slug)"`
Driver string `enum:"mysql,postgres,mariadb,sqlite" default:"mysql" help:"Driver of the migration directory (mysql,postgres,mariadb,sqlite)."`
Token string `short:"t" help:"Atlas authentication token."`
Repo string `short:"R" help:"GitHub repository owner/name, defaults to the current repository."`
DirName string `optional:"" help:"Name of target migration directory in Atlas Cloud."`
stdin io.ReadCloser `hidden:""`
cloudURL string `hidden:""`
}
Expand All @@ -63,7 +63,7 @@ func (i *InitActionCmd) Help() string {
return `Examples:
gh atlas init-action
gh atlas init-action --token=$ATLAS_CLOUD_TOKEN
gh atlas init-action --token=$ATLAS_CLOUD_TOKEN --driver="mysql" "dir/migrations"`
gh atlas init-action --token=$ATLAS_CLOUD_TOKEN --dir-name="migrations" --driver="mysql" "dir/migrations"`
}

const (
Expand Down Expand Up @@ -100,9 +100,20 @@ func (i *InitActionCmd) Run(ctx context.Context, client *githubClient, current r
if err = i.setParams(dirs); err != nil {
return err
}
if err = cloudapi.New(i.cloudURL, i.Token).ValidateToken(ctx); err != nil {
cloud := cloudapi.New(i.cloudURL, i.Token)
if err = cloud.ValidateToken(ctx); err != nil {
return errors.New("the given atlas token is invalid, please generate a new one and try again")
}
dirNames, err := cloud.DirNames(ctx)
if err != nil {
return err
}
// If dir name is not set by the user, and there are dirs in the cloud, prompt the user to choose one.
if i.DirName == "" && len(dirNames) > 0 {
if err = i.setDirName(dirNames); err != nil {
return err
}
}
if err = repo.SetSecret(ctx, secretName, i.Token); err != nil {
return err
}
Expand Down
73 changes: 62 additions & 11 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"

"github.com/cli/go-gh/pkg/repository"
Expand Down Expand Up @@ -96,18 +97,31 @@ func TestRunInitActionCmd(t *testing.T) {
}
repo, err := repository.Parse("owner/repo")
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var input struct {
Variables struct {
Token string `json:"token"`
} `json:"variables"`
}
err := json.NewDecoder(r.Body).Decode(&input)
var (
input struct {
Query string `json:"query,omitempty"`
Variables struct {
Token string `json:"token"`
} `json:"variables"`
}
payload struct {
Data struct {
DirSlugs []string `json:"dirSlugs"`
} `json:"data"`
}
)
err = json.NewDecoder(r.Body).Decode(&input)
require.NoError(t, err)
if input.Variables.Token == "invalid token" {
w.WriteHeader(http.StatusUnauthorized)
return
if strings.Contains(input.Query, "validateToken") {
if input.Variables.Token == "invalid token" {
w.WriteHeader(http.StatusUnauthorized)
return
}
}
if strings.Contains(input.Query, "dirSlugs") {
payload.Data.DirSlugs = []string{"name"}
}
body, err := json.Marshal(input)
body, err := json.Marshal(payload)
require.NoError(t, err)
_, err = w.Write(body)
require.NoError(t, err)
Expand All @@ -124,21 +138,55 @@ func TestRunInitActionCmd(t *testing.T) {
name: "all arg and flags supplied",
cmd: &InitActionCmd{
DirPath: "migrations",
DirName: "name",
Driver: "mysql",
Token: "token",
},
expected: &InitActionCmd{
DirPath: "migrations",
DirName: "name",
Driver: "mysql",
Token: "token",
},
},
{
name: "no dir path and driver supplied",
cmd: &InitActionCmd{
Token: "token",
Token: "token",
DirName: "name",
},
prompt: "\n\n",
expected: &InitActionCmd{
DirPath: "migrations",
DirName: "name",
Driver: "mysql",
Token: "token",
},
},
{
name: "no dir name supplied use cloud dir name",
cmd: &InitActionCmd{
DirPath: "migrations",
Driver: "mysql",
Token: "token",
},
prompt: "\n\n",
expected: &InitActionCmd{
DirPath: "migrations",
DirName: "name",
Driver: "mysql",
Token: "token",
},
},
{
name: "no dir name supplied dont use cloud",
cmd: &InitActionCmd{
DirPath: "migrations",
Driver: "mysql",
Token: "token",
},
// use arrow key down and then enter
prompt: "\x1b[B\n\n",
expected: &InitActionCmd{
DirPath: "migrations",
Driver: "mysql",
Expand All @@ -149,11 +197,13 @@ func TestRunInitActionCmd(t *testing.T) {
name: "no token flag supplied",
cmd: &InitActionCmd{
DirPath: "migrations",
DirName: "name",
Driver: "mysql",
},
prompt: "my token\n",
expected: &InitActionCmd{
DirPath: "migrations",
DirName: "name",
Driver: "mysql",
Token: "my token",
},
Expand Down Expand Up @@ -198,6 +248,7 @@ func TestRunInitActionCmd(t *testing.T) {
require.Equal(t, tt.expected.Token, tt.cmd.Token)
require.Equal(t, tt.expected.Driver, tt.cmd.Driver)
require.Equal(t, tt.expected.DirPath, tt.cmd.DirPath)
require.Equal(t, tt.expected.DirName, tt.cmd.DirName)
})
}
}
Expand Down
29 changes: 27 additions & 2 deletions prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ func (i *InitActionCmd) setParams(dirs []string) error {
var err error
if i.DirPath == "" {
prompt := promptui.Select{
Label: "choose migration directory",
Label: "Choose migration directory",
Items: dirs,
Stdin: i.stdin,
}
if _, i.DirPath, err = prompt.Run(); err != nil {
return err
}
prompt = promptui.Select{
Label: "choose driver",
Label: "Choose driver",
Items: []string{"mysql", "postgres", "mariadb", "sqlite"},
Stdin: i.stdin,
}
Expand All @@ -46,3 +46,28 @@ func (i *InitActionCmd) setParams(dirs []string) error {
}
return nil
}

func (i *InitActionCmd) setDirName(names []string) error {
var err error
prompt := promptui.Select{
Label: "Choose action",
Items: []string{"Use existing directory from the Cloud", "Create new directory"},
Stdin: i.stdin,
}
_, rsp, err := prompt.Run()
if err != nil {
return err
}
if rsp == "Create new directory" {
return nil
}
prompt = promptui.Select{
Label: "Choose name of cloud migration directory",
Items: names,
Stdin: i.stdin,
}
if _, i.DirName, err = prompt.Run(); err != nil {
return err
}
return nil
}

0 comments on commit 96b183f

Please sign in to comment.