Skip to content

Commit 19e0d7e

Browse files
authored
Merge branch 'main' into fatih/org-switch
2 parents 5fec79b + 269a555 commit 19e0d7e

File tree

5 files changed

+162
-81
lines changed

5 files changed

+162
-81
lines changed

internal/cmd/branch/branch.go

+5-73
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,23 @@
11
package branch
22

33
import (
4-
"context"
5-
"fmt"
6-
"net/url"
7-
8-
"github.com/planetscale/cli/internal/cmdutil"
94
"github.com/planetscale/cli/internal/config"
10-
"github.com/planetscale/cli/internal/printer"
11-
ps "github.com/planetscale/planetscale-go/planetscale"
125

13-
"github.com/pkg/browser"
146
"github.com/spf13/cobra"
157
)
168

179
// BranchCmd handles the branching of a database.
1810
func BranchCmd(cfg *config.Config) *cobra.Command {
19-
createReq := &ps.CreateDatabaseBranchRequest{
20-
Branch: new(ps.DatabaseBranch),
21-
}
22-
2311
cmd := &cobra.Command{
24-
Use: "branch <source-database> <branch> [options]",
25-
Short: "Branch a production database",
26-
Args: cmdutil.RequiredArgs("source-database", "branch"),
27-
Aliases: []string{"b"},
28-
RunE: func(cmd *cobra.Command, args []string) error {
29-
ctx := context.Background()
30-
source := args[0]
31-
branch := args[1]
32-
33-
// Simplest case, the names are equivalent
34-
if source == branch {
35-
return fmt.Errorf("A branch named '%s' already exists", branch)
36-
}
37-
38-
createReq.Database = source
39-
createReq.Branch.Name = branch
40-
createReq.Organization = cfg.Organization
41-
42-
web, err := cmd.Flags().GetBool("web")
43-
if err != nil {
44-
return err
45-
}
46-
47-
if web {
48-
fmt.Println("🌐 Redirecting you to branch a database in your web browser.")
49-
err := browser.OpenURL(fmt.Sprintf("%s/%s/%s/branches?name=%s&notes=%s&showDialog=true", cmdutil.ApplicationURL, cfg.Organization, source, url.QueryEscape(createReq.Branch.Name), url.QueryEscape(createReq.Branch.Notes)))
50-
if err != nil {
51-
return err
52-
}
53-
return nil
54-
}
55-
56-
client, err := cfg.NewClientFromConfig()
57-
if err != nil {
58-
return err
59-
}
60-
61-
end := cmdutil.PrintProgress(fmt.Sprintf("Creating branch from %s...", cmdutil.BoldBlue(source)))
62-
defer end()
63-
dbBranch, err := client.DatabaseBranches.Create(ctx, createReq)
64-
if err != nil {
65-
return err
66-
}
67-
68-
end()
69-
if cfg.OutputJSON {
70-
err := printer.PrintJSON(dbBranch)
71-
if err != nil {
72-
return err
73-
}
74-
} else {
75-
fmt.Printf("Branch %s was successfully created!\n", cmdutil.BoldBlue(dbBranch.Name))
76-
}
77-
78-
return nil
79-
},
12+
Use: "branch <command>",
13+
Short: "Create, delete, and manage branches",
8014
}
8115

82-
cmd.Flags().StringVar(&createReq.Branch.Notes, "notes", "", "notes for the database branch")
83-
cmd.Flags().StringVar(&createReq.Branch.ParentBranch, "from", "", "branch to be created from")
84-
cmd.Flags().BoolP("web", "w", false, "Create a branch in your web browser")
85-
86-
cmd.PersistentFlags().StringVar(&cfg.Organization, "org", cfg.Organization, "The organization for the current user")
16+
cmd.PersistentFlags().StringVar(&cfg.Organization, "org", cfg.Organization,
17+
"The organization for the current user")
8718
cmd.MarkPersistentFlagRequired("org") // nolint:errcheck
8819

20+
cmd.AddCommand(CreateCmd(cfg))
8921
cmd.AddCommand(ListCmd(cfg))
9022
cmd.AddCommand(StatusCmd(cfg))
9123
cmd.AddCommand(DeleteCmd(cfg))

internal/cmd/branch/create.go

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package branch
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/url"
7+
8+
"github.com/pkg/browser"
9+
"github.com/planetscale/cli/internal/cmdutil"
10+
"github.com/planetscale/cli/internal/config"
11+
"github.com/planetscale/cli/internal/printer"
12+
ps "github.com/planetscale/planetscale-go/planetscale"
13+
"github.com/spf13/cobra"
14+
)
15+
16+
func CreateCmd(cfg *config.Config) *cobra.Command {
17+
createReq := &ps.CreateDatabaseBranchRequest{
18+
Branch: new(ps.DatabaseBranch),
19+
}
20+
21+
cmd := &cobra.Command{
22+
Use: "create <source-database> <branch> [options]",
23+
Short: "Create a new branch from a database",
24+
Args: cmdutil.RequiredArgs("source-database", "branch"),
25+
Aliases: []string{"b"},
26+
RunE: func(cmd *cobra.Command, args []string) error {
27+
ctx := context.Background()
28+
source := args[0]
29+
branch := args[1]
30+
31+
// Simplest case, the names are equivalent
32+
if source == branch {
33+
return fmt.Errorf("A branch named '%s' already exists", branch)
34+
}
35+
36+
createReq.Database = source
37+
createReq.Branch.Name = branch
38+
createReq.Organization = cfg.Organization
39+
40+
web, err := cmd.Flags().GetBool("web")
41+
if err != nil {
42+
return err
43+
}
44+
45+
if web {
46+
fmt.Println("🌐 Redirecting you to branch a database in your web browser.")
47+
err := browser.OpenURL(fmt.Sprintf(
48+
"%s/%s/%s/branches?name=%s&notes=%s&showDialog=true",
49+
cmdutil.ApplicationURL, cfg.Organization, source, url.QueryEscape(createReq.Branch.Name), url.QueryEscape(createReq.Branch.Notes),
50+
))
51+
if err != nil {
52+
return err
53+
}
54+
return nil
55+
}
56+
57+
client, err := cfg.NewClientFromConfig()
58+
if err != nil {
59+
return err
60+
}
61+
62+
end := cmdutil.PrintProgress(fmt.Sprintf("Creating branch from %s...", cmdutil.BoldBlue(source)))
63+
defer end()
64+
dbBranch, err := client.DatabaseBranches.Create(ctx, createReq)
65+
if err != nil {
66+
return err
67+
}
68+
69+
end()
70+
if cfg.OutputJSON {
71+
err := printer.PrintJSON(dbBranch)
72+
if err != nil {
73+
return err
74+
}
75+
} else {
76+
fmt.Printf("Branch %s was successfully created!\n", cmdutil.BoldBlue(dbBranch.Name))
77+
}
78+
79+
return nil
80+
},
81+
}
82+
83+
cmd.Flags().StringVar(&createReq.Branch.Notes, "notes", "", "notes for the database branch")
84+
cmd.Flags().StringVar(&createReq.Branch.ParentBranch, "from", "", "branch to be created from")
85+
cmd.Flags().BoolP("web", "w", false, "Create a branch in your web browser")
86+
87+
return cmd
88+
}

internal/cmd/org/list.go

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package org
2+
3+
import (
4+
"context"
5+
"time"
6+
7+
"github.com/planetscale/cli/internal/config"
8+
"github.com/planetscale/cli/internal/printer"
9+
ps "github.com/planetscale/planetscale-go/planetscale"
10+
11+
"github.com/spf13/cobra"
12+
)
13+
14+
// organization returns a table-serializable database model.
15+
type organization struct {
16+
Name string `header:"name" json:"name"`
17+
CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"`
18+
UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"`
19+
}
20+
21+
func ListCmd(cfg *config.Config) *cobra.Command {
22+
cmd := &cobra.Command{
23+
Use: "list",
24+
Short: "List the currently active organizations",
25+
Args: cobra.NoArgs,
26+
Aliases: []string{"ls"},
27+
RunE: func(cmd *cobra.Command, args []string) error {
28+
ctx := context.Background()
29+
client, err := cfg.NewClientFromConfig()
30+
if err != nil {
31+
return err
32+
}
33+
34+
orgs, err := client.Organizations.List(ctx)
35+
if err != nil {
36+
return err
37+
}
38+
39+
err = printer.PrintOutput(cfg.OutputJSON, newOrganizationSlicePrinter(orgs))
40+
if err != nil {
41+
return err
42+
}
43+
44+
return nil
45+
},
46+
}
47+
48+
return cmd
49+
}
50+
51+
// newOrganizationSlicePrinter returns a slice of printable orgs.
52+
func newOrganizationSlicePrinter(organizations []*ps.Organization) []*organization {
53+
orgs := make([]*organization, 0, len(organizations))
54+
55+
for _, org := range organizations {
56+
orgs = append(orgs, newOrgPrinter(org))
57+
}
58+
59+
return orgs
60+
}
61+
62+
func newOrgPrinter(org *ps.Organization) *organization {
63+
return &organization{
64+
Name: org.Name,
65+
CreatedAt: org.CreatedAt.UTC().UnixNano() / (int64(time.Millisecond) / int64(time.Nanosecond)),
66+
UpdatedAt: org.UpdatedAt.UTC().UnixNano() / (int64(time.Millisecond) / int64(time.Nanosecond)),
67+
}
68+
}

internal/cmd/org/org.go

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ func OrgCmd(cfg *config.Config) *cobra.Command {
1414

1515
cmd.AddCommand(SwitchCmd(cfg))
1616
cmd.AddCommand(ShowCmd(cfg))
17+
cmd.AddCommand(ListCmd(cfg))
1718

1819
return cmd
1920
}

internal/cmdutil/args.go

-8
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,6 @@ import (
1111
// required arguments are not available.
1212
func RequiredArgs(reqArgs ...string) cobra.PositionalArgs {
1313
return func(cmd *cobra.Command, args []string) error {
14-
// show just the usage line and any examples if they exist
15-
var usageTemplate = `Usage:{{if .Runnable}} {{.UseLine}}{{end}}{{if .HasExample}}
16-
17-
Examples:
18-
{{.Example}}{{end}}
19-
`
20-
cmd.SetUsageTemplate(usageTemplate)
21-
2214
n := len(reqArgs)
2315
if len(args) >= n {
2416
return nil

0 commit comments

Comments
 (0)