Skip to content

Commit b4b4601

Browse files
feat: fix commands
1 parent 14cd5c8 commit b4b4601

22 files changed

Lines changed: 440 additions & 138 deletions

cmd/domains/domains_add.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ func newDomainsAddCommand() *cli.Command {
1515
Name: "add",
1616
Usage: "Add a custom domain to a project",
1717
ArgsUsage: "[project-id] <domain>",
18+
Flags: []cli.Flag{
19+
&cli.StringFlag{Name: "environment", Usage: "Environment ID to link the domain to"},
20+
},
1821
Action: func(c *cli.Context) error {
1922
client, ok := c.App.Metadata[api.ClientKey].(*api.APIClient)
2023
if !ok {
@@ -26,7 +29,7 @@ func newDomainsAddCommand() *cli.Command {
2629
return err
2730
}
2831

29-
environmentID, err := pickEnvironment(client, projectID)
32+
environmentID, err := resolveEnvironmentForDomain(c, client, projectID)
3033
if err != nil {
3134
return err
3235
}

cmd/domains/domains_delete.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,17 @@ func newDomainsDeleteCommand() *cli.Command {
1414
Name: "delete",
1515
Usage: "Remove a custom domain from a project",
1616
ArgsUsage: "[project-id] <domain-id>",
17-
Description: "Permanently removes a custom domain from your project.\n\n" +
18-
" To find your domain ID, run:\n" +
19-
" createos domains list <project-id>",
17+
Flags: []cli.Flag{
18+
&cli.StringFlag{Name: "project", Usage: "Project ID"},
19+
&cli.StringFlag{Name: "domain", Usage: "Domain ID"},
20+
},
2021
Action: func(c *cli.Context) error {
2122
client, ok := c.App.Metadata[api.ClientKey].(*api.APIClient)
2223
if !ok {
2324
return fmt.Errorf("you're not signed in — run 'createos login' to get started")
2425
}
2526

26-
projectID, domainID, err := resolveDomain(c.Args().Slice(), client)
27+
projectID, domainID, err := resolveDomain(c, client)
2728
if err != nil {
2829
return err
2930
}

cmd/domains/domains_refresh.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func newDomainsRefreshCommand() *cli.Command {
2323
return fmt.Errorf("you're not signed in — run 'createos login' to get started")
2424
}
2525

26-
projectID, domainID, err := resolveDomain(c.Args().Slice(), client)
26+
projectID, domainID, err := resolveDomain(c, client)
2727
if err != nil {
2828
return err
2929
}

cmd/domains/domains_verify.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,17 @@ func newDomainsVerifyCommand() *cli.Command {
1919
Usage: "Check DNS propagation and wait for domain verification",
2020
ArgsUsage: "[project-id] <domain-id>",
2121
Flags: []cli.Flag{
22-
&cli.BoolFlag{
23-
Name: "no-wait",
24-
Usage: "Check once and exit instead of polling",
25-
},
22+
&cli.StringFlag{Name: "project", Usage: "Project ID"},
23+
&cli.StringFlag{Name: "domain", Usage: "Domain ID"},
24+
&cli.BoolFlag{Name: "no-wait", Usage: "Check once and exit instead of polling"},
2625
},
2726
Action: func(c *cli.Context) error {
2827
client, ok := c.App.Metadata[api.ClientKey].(*api.APIClient)
2928
if !ok {
3029
return fmt.Errorf("you're not signed in — run 'createos login' to get started")
3130
}
3231

33-
projectID, domainID, err := resolveDomain(c.Args().Slice(), client)
32+
projectID, domainID, err := resolveDomain(c, client)
3433
if err != nil {
3534
return err
3635
}

cmd/domains/helpers.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,28 @@ import (
44
"fmt"
55

66
"github.com/pterm/pterm"
7+
"github.com/urfave/cli/v2"
78

89
"github.com/NodeOps-app/createos-cli/internal/api"
910
"github.com/NodeOps-app/createos-cli/internal/cmdutil"
1011
)
1112

12-
// resolveDomain resolves projectID and domainID from args or interactively.
13-
func resolveDomain(args []string, client *api.APIClient) (string, string, error) {
13+
// resolveDomain resolves projectID and domainID from flags, args, or interactively.
14+
func resolveDomain(c *cli.Context, client *api.APIClient) (string, string, error) {
15+
args := c.Args().Slice()
16+
17+
// --domain flag takes priority
18+
if domainID := c.String("domain"); domainID != "" {
19+
projectID, err := cmdutil.ResolveProjectID(c.String("project"))
20+
if err != nil {
21+
return "", "", err
22+
}
23+
return projectID, domainID, nil
24+
}
25+
1426
switch len(args) {
1527
case 0:
16-
projectID, err := cmdutil.ResolveProjectID("")
28+
projectID, err := cmdutil.ResolveProjectID(c.String("project"))
1729
if err != nil {
1830
return "", "", err
1931
}
@@ -23,7 +35,7 @@ func resolveDomain(args []string, client *api.APIClient) (string, string, error)
2335
}
2436
return projectID, domainID, nil
2537
case 1:
26-
projectID, err := cmdutil.ResolveProjectID("")
38+
projectID, err := cmdutil.ResolveProjectID(c.String("project"))
2739
if err != nil {
2840
return "", "", err
2941
}
@@ -65,6 +77,14 @@ func pickDomain(client *api.APIClient, projectID string) (string, error) {
6577
return "", fmt.Errorf("no domain selected")
6678
}
6779

80+
// resolveEnvironmentForDomain returns an environment ID from flag or interactive select.
81+
func resolveEnvironmentForDomain(c *cli.Context, client *api.APIClient, projectID string) (string, error) {
82+
if envID := c.String("environment"); envID != "" {
83+
return envID, nil
84+
}
85+
return pickEnvironment(client, projectID)
86+
}
87+
6888
// pickEnvironment shows a required interactive environment selector.
6989
func pickEnvironment(client *api.APIClient, projectID string) (string, error) {
7090
envs, err := client.ListEnvironments(projectID)

cmd/environments/environments_delete.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,24 @@ import (
77
"github.com/urfave/cli/v2"
88

99
"github.com/NodeOps-app/createos-cli/internal/api"
10-
"github.com/NodeOps-app/createos-cli/internal/cmdutil"
1110
)
1211

1312
func newEnvironmentsDeleteCommand() *cli.Command {
1413
return &cli.Command{
1514
Name: "delete",
1615
Usage: "Delete an environment",
1716
ArgsUsage: "[project-id] <environment-id>",
18-
Description: "Permanently deletes an environment from your project.\n\n" +
19-
" To find your environment ID, run:\n" +
20-
" createos projects environments list <project-id>",
17+
Flags: []cli.Flag{
18+
&cli.StringFlag{Name: "project", Usage: "Project ID"},
19+
&cli.StringFlag{Name: "environment", Usage: "Environment ID"},
20+
},
2121
Action: func(c *cli.Context) error {
2222
client, ok := c.App.Metadata[api.ClientKey].(*api.APIClient)
2323
if !ok {
2424
return fmt.Errorf("you're not signed in — run 'createos login' to get started")
2525
}
2626

27-
projectID, environmentID, err := cmdutil.ResolveProjectScopedArg(c.Args().Slice(), "an environment ID")
27+
projectID, environmentID, err := resolveEnvironment(c, client)
2828
if err != nil {
2929
return err
3030
}
@@ -47,9 +47,6 @@ func newEnvironmentsDeleteCommand() *cli.Command {
4747
}
4848

4949
pterm.Success.Println("Environment deletion started.")
50-
fmt.Println()
51-
pterm.Println(pterm.Gray(" Tip: To check the environment status, run:"))
52-
pterm.Println(pterm.Gray(" createos projects environments list " + projectID))
5350
return nil
5451
},
5552
}

cmd/environments/environments_list.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ func newEnvironmentsListCommand() *cli.Command {
6666
return err
6767
}
6868
fmt.Println()
69-
pterm.Println(pterm.Gray(" Tip: To delete an environment, run:"))
70-
pterm.Println(pterm.Gray(" createos projects environments delete " + projectID + " <environment-id>"))
7169
return nil
7270
},
7371
}

cmd/environments/helpers.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package environments
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/pterm/pterm"
7+
"github.com/urfave/cli/v2"
8+
9+
"github.com/NodeOps-app/createos-cli/internal/api"
10+
"github.com/NodeOps-app/createos-cli/internal/cmdutil"
11+
)
12+
13+
// resolveEnvironment resolves projectID and environmentID from flags, args, or interactively.
14+
func resolveEnvironment(c *cli.Context, client *api.APIClient) (string, string, error) {
15+
args := c.Args().Slice()
16+
17+
if envID := c.String("environment"); envID != "" {
18+
projectID, err := cmdutil.ResolveProjectID(c.String("project"))
19+
if err != nil {
20+
return "", "", err
21+
}
22+
return projectID, envID, nil
23+
}
24+
25+
switch len(args) {
26+
case 0:
27+
projectID, err := cmdutil.ResolveProjectID(c.String("project"))
28+
if err != nil {
29+
return "", "", err
30+
}
31+
envID, err := pickEnvironment(client, projectID)
32+
if err != nil {
33+
return "", "", err
34+
}
35+
return projectID, envID, nil
36+
case 1:
37+
projectID, err := cmdutil.ResolveProjectID(c.String("project"))
38+
if err != nil {
39+
return "", "", err
40+
}
41+
return projectID, args[0], nil
42+
default:
43+
return args[0], args[1], nil
44+
}
45+
}
46+
47+
func pickEnvironment(client *api.APIClient, projectID string) (string, error) {
48+
envs, err := client.ListEnvironments(projectID)
49+
if err != nil {
50+
return "", err
51+
}
52+
if len(envs) == 0 {
53+
return "", fmt.Errorf("no environments found for this project")
54+
}
55+
if len(envs) == 1 {
56+
pterm.Println(pterm.Gray(fmt.Sprintf(" Using environment: %s", envs[0].DisplayName)))
57+
return envs[0].ID, nil
58+
}
59+
60+
options := make([]string, len(envs))
61+
for i, e := range envs {
62+
options[i] = fmt.Sprintf("%s (%s)", e.DisplayName, e.Status)
63+
}
64+
selected, err := pterm.DefaultInteractiveSelect.
65+
WithOptions(options).
66+
WithDefaultText("Select an environment").
67+
Show()
68+
if err != nil {
69+
return "", fmt.Errorf("could not read selection: %w", err)
70+
}
71+
for i, opt := range options {
72+
if opt == selected {
73+
return envs[i].ID, nil
74+
}
75+
}
76+
return "", fmt.Errorf("no environment selected")
77+
}

cmd/status/status.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ func statusIcon(status string) string {
170170
}
171171
}
172172

173-
174173
func deployStatusIcon(status string) string {
175174
switch status {
176175
case "successful", "running", "active", "deployed":

cmd/templates/helpers.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package templates
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/pterm/pterm"
7+
"github.com/urfave/cli/v2"
8+
9+
"github.com/NodeOps-app/createos-cli/internal/api"
10+
"github.com/NodeOps-app/createos-cli/internal/terminal"
11+
)
12+
13+
// resolveTemplate resolves a template ID from flags, args, or interactively.
14+
func resolveTemplate(c *cli.Context, client *api.APIClient) (string, error) {
15+
if id := c.String("template"); id != "" {
16+
return id, nil
17+
}
18+
if c.NArg() > 0 {
19+
return c.Args().First(), nil
20+
}
21+
if !terminal.IsInteractive() {
22+
return "", fmt.Errorf("please provide a template ID\n\n Example:\n createos templates %s --template <template-id>", c.Command.Name)
23+
}
24+
return pickTemplate(client)
25+
}
26+
27+
func pickTemplate(client *api.APIClient) (string, error) {
28+
templates, err := client.ListPublishedTemplates()
29+
if err != nil {
30+
return "", err
31+
}
32+
if len(templates) == 0 {
33+
return "", fmt.Errorf("no templates available")
34+
}
35+
if len(templates) == 1 {
36+
return templates[0].ID, nil
37+
}
38+
39+
options := make([]string, len(templates))
40+
for i, t := range templates {
41+
options[i] = t.Name
42+
}
43+
selected, err := pterm.DefaultInteractiveSelect.
44+
WithOptions(options).
45+
WithDefaultText("Select a template").
46+
Show()
47+
if err != nil {
48+
return "", fmt.Errorf("could not read selection: %w", err)
49+
}
50+
for i, opt := range options {
51+
if opt == selected {
52+
return templates[i].ID, nil
53+
}
54+
}
55+
return "", fmt.Errorf("no template selected")
56+
}

0 commit comments

Comments
 (0)