summaryrefslogtreecommitdiffstats
path: root/cmd/ship/root_v2.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/ship/root_v2.go')
-rw-r--r--cmd/ship/root_v2.go158
1 files changed, 158 insertions, 0 deletions
diff --git a/cmd/ship/root_v2.go b/cmd/ship/root_v2.go
new file mode 100644
index 0000000..dab63be
--- /dev/null
+++ b/cmd/ship/root_v2.go
@@ -0,0 +1,158 @@
1package main
2
3import (
4 "os"
5
6 "github.com/bdw/ship/internal/output"
7 "github.com/spf13/cobra"
8)
9
10// This file defines the v2 CLI structure.
11// The primary command is: ship [PATH] [FLAGS]
12// All output is JSON by default.
13
14var rootV2Cmd = &cobra.Command{
15 Use: "ship [PATH]",
16 Short: "Deploy code to a VPS. JSON output for agents.",
17 Long: `Ship deploys code to a VPS. Point it at a directory or binary, get a URL back.
18
19 ship ./myproject # auto-detect and deploy
20 ship ./site --name docs # deploy with specific name
21 ship ./api --health /healthz # deploy with health check
22 ship ./preview --ttl 24h # deploy with auto-expiry
23
24All output is JSON. Use --pretty for human-readable output.`,
25 Args: cobra.MaximumNArgs(1),
26 RunE: runDeployV2,
27 SilenceUsage: true,
28 SilenceErrors: true,
29 DisableAutoGenTag: true,
30}
31
32func initV2() {
33 // Global flags
34 rootV2Cmd.PersistentFlags().StringVar(&hostFlag, "host", "", "VPS host (SSH config alias or user@host)")
35 rootV2Cmd.PersistentFlags().BoolVar(&output.Pretty, "pretty", false, "Human-readable output")
36
37 // Deploy flags
38 rootV2Cmd.Flags().String("name", "", "Deploy name (becomes subdomain)")
39 rootV2Cmd.Flags().String("health", "", "Health check endpoint (e.g., /healthz)")
40 rootV2Cmd.Flags().String("ttl", "", "Auto-delete after duration (e.g., 1h, 7d)")
41 rootV2Cmd.Flags().StringArray("env", nil, "Environment variable (KEY=VALUE)")
42 rootV2Cmd.Flags().String("env-file", "", "Path to .env file")
43
44 // Check for SHIP_PRETTY env var
45 if os.Getenv("SHIP_PRETTY") == "1" {
46 output.Pretty = true
47 }
48
49 // Add subcommands
50 rootV2Cmd.AddCommand(listV2Cmd)
51 rootV2Cmd.AddCommand(statusV2Cmd)
52 rootV2Cmd.AddCommand(logsV2Cmd)
53 rootV2Cmd.AddCommand(removeV2Cmd)
54 rootV2Cmd.AddCommand(hostV2Cmd)
55}
56
57func runDeployV2(cmd *cobra.Command, args []string) error {
58 path := "."
59 if len(args) > 0 {
60 path = args[0]
61 }
62
63 opts := deployV2Options{
64 Host: hostFlag,
65 Pretty: output.Pretty,
66 }
67
68 // Get flag values
69 opts.Name, _ = cmd.Flags().GetString("name")
70 opts.Health, _ = cmd.Flags().GetString("health")
71 opts.TTL, _ = cmd.Flags().GetString("ttl")
72 opts.Env, _ = cmd.Flags().GetStringArray("env")
73 opts.EnvFile, _ = cmd.Flags().GetString("env-file")
74
75 // deployV2 handles all output and exits
76 deployV2(path, opts)
77
78 // Should not reach here (deployV2 calls os.Exit)
79 return nil
80}
81
82// Placeholder subcommands - to be implemented
83
84var listV2Cmd = &cobra.Command{
85 Use: "list",
86 Short: "List all deployments",
87 RunE: func(cmd *cobra.Command, args []string) error {
88 // TODO: implement
89 output.PrintAndExit(&output.ListResponse{
90 Status: "ok",
91 Deploys: []output.DeployInfo{},
92 })
93 return nil
94 },
95}
96
97var statusV2Cmd = &cobra.Command{
98 Use: "status NAME",
99 Short: "Check status of a deployment",
100 Args: cobra.ExactArgs(1),
101 RunE: func(cmd *cobra.Command, args []string) error {
102 // TODO: implement
103 output.PrintAndExit(output.Err(output.ErrNotFound, "not implemented"))
104 return nil
105 },
106}
107
108var logsV2Cmd = &cobra.Command{
109 Use: "logs NAME",
110 Short: "View logs for a deployment",
111 Args: cobra.ExactArgs(1),
112 RunE: func(cmd *cobra.Command, args []string) error {
113 // TODO: implement
114 output.PrintAndExit(output.Err(output.ErrNotFound, "not implemented"))
115 return nil
116 },
117}
118
119var removeV2Cmd = &cobra.Command{
120 Use: "remove NAME",
121 Short: "Remove a deployment",
122 Args: cobra.ExactArgs(1),
123 RunE: func(cmd *cobra.Command, args []string) error {
124 // TODO: implement
125 output.PrintAndExit(output.Err(output.ErrNotFound, "not implemented"))
126 return nil
127 },
128}
129
130var hostV2Cmd = &cobra.Command{
131 Use: "host",
132 Short: "Manage VPS host",
133}
134
135func init() {
136 hostV2Cmd.AddCommand(hostInitV2Cmd)
137 hostV2Cmd.AddCommand(hostStatusV2Cmd)
138}
139
140var hostInitV2Cmd = &cobra.Command{
141 Use: "init USER@HOST --domain DOMAIN",
142 Short: "Initialize a VPS for deployments",
143 RunE: func(cmd *cobra.Command, args []string) error {
144 // TODO: implement - this is critical functionality to preserve
145 output.PrintAndExit(output.Err(output.ErrNotFound, "not implemented"))
146 return nil
147 },
148}
149
150var hostStatusV2Cmd = &cobra.Command{
151 Use: "status",
152 Short: "Check host status",
153 RunE: func(cmd *cobra.Command, args []string) error {
154 // TODO: implement
155 output.PrintAndExit(output.Err(output.ErrNotFound, "not implemented"))
156 return nil
157 },
158}