|
1 | 1 | package cmd |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "encoding/json" |
4 | 5 | "fmt" |
| 6 | + "os" |
5 | 7 | "strconv" |
6 | 8 |
|
7 | 9 | "github.com/loops-so/cli/internal/config" |
8 | 10 | "github.com/loops-so/loops-go" |
9 | 11 | "github.com/spf13/cobra" |
10 | 12 | ) |
11 | 13 |
|
| 14 | +// themeFieldParams holds the fields shared by `themes create` and |
| 15 | +// `themes update`. Name is empty when the flag is unset; Styles is nil unless |
| 16 | +// --styles-file is provided. |
| 17 | +type themeFieldParams struct { |
| 18 | + Name string |
| 19 | + Styles *loops.ThemeStyles |
| 20 | +} |
| 21 | + |
| 22 | +func addThemeFieldFlags(cmd *cobra.Command) { |
| 23 | + cmd.Flags().StringP("name", "n", "", "Theme name") |
| 24 | + cmd.Flags().String("styles-file", "", "Path to a JSON file with theme styles") |
| 25 | +} |
| 26 | + |
| 27 | +func themeFieldParamsFromCmd(cmd *cobra.Command) (themeFieldParams, error) { |
| 28 | + var p themeFieldParams |
| 29 | + if cmd.Flags().Changed("name") { |
| 30 | + p.Name, _ = cmd.Flags().GetString("name") |
| 31 | + } |
| 32 | + if cmd.Flags().Changed("styles-file") { |
| 33 | + path, _ := cmd.Flags().GetString("styles-file") |
| 34 | + if path == "" { |
| 35 | + return p, fmt.Errorf("--styles-file requires a value") |
| 36 | + } |
| 37 | + data, err := os.ReadFile(path) |
| 38 | + if err != nil { |
| 39 | + return p, fmt.Errorf("read --styles-file: %w", err) |
| 40 | + } |
| 41 | + var styles loops.ThemeStyles |
| 42 | + if err := json.Unmarshal(data, &styles); err != nil { |
| 43 | + return p, fmt.Errorf("parse --styles-file: %w", err) |
| 44 | + } |
| 45 | + p.Styles = &styles |
| 46 | + } |
| 47 | + return p, nil |
| 48 | +} |
| 49 | + |
12 | 50 | func runThemesGet(cfg *config.Config, id string) (*loops.Theme, error) { |
13 | 51 | return newAPIClient(cfg).GetTheme(id) |
14 | 52 | } |
15 | 53 |
|
| 54 | +func runThemesCreate(cfg *config.Config, req loops.CreateThemeRequest) (*loops.Theme, error) { |
| 55 | + return newAPIClient(cfg).CreateTheme(req) |
| 56 | +} |
| 57 | + |
| 58 | +func runThemesUpdate(cfg *config.Config, id string, req loops.UpdateThemeRequest) (*loops.Theme, error) { |
| 59 | + return newAPIClient(cfg).UpdateTheme(id, req) |
| 60 | +} |
| 61 | + |
16 | 62 | func runThemesList(cfg *config.Config, params loops.PaginationParams) ([]loops.Theme, error) { |
17 | 63 | client := newAPIClient(cfg) |
18 | 64 | if params.Cursor != "" { |
@@ -106,21 +152,88 @@ var themesGetCmd = &cobra.Command{ |
106 | 152 | return printJSON(cmd.OutOrStdout(), th) |
107 | 153 | } |
108 | 154 |
|
109 | | - t := newStyledTable(cmd.OutOrStdout(), "FIELD", "VALUE") |
110 | | - t.Row("themeId", th.ID) |
111 | | - t.Row("name", th.Name) |
112 | | - t.Row("isDefault", strconv.FormatBool(th.IsDefault)) |
113 | | - t.Row("createdAt", th.CreatedAt) |
114 | | - t.Row("updatedAt", th.UpdatedAt) |
115 | | - if err := t.Render(); err != nil { |
| 155 | + return printTheme(cmd, th) |
| 156 | + }, |
| 157 | +} |
| 158 | + |
| 159 | +var themesCreateCmd = &cobra.Command{ |
| 160 | + Use: "create", |
| 161 | + Short: "Create a theme", |
| 162 | + RunE: func(cmd *cobra.Command, args []string) error { |
| 163 | + params, err := themeFieldParamsFromCmd(cmd) |
| 164 | + if err != nil { |
| 165 | + return err |
| 166 | + } |
| 167 | + |
| 168 | + cfg, err := loadConfig() |
| 169 | + if err != nil { |
| 170 | + return err |
| 171 | + } |
| 172 | + |
| 173 | + th, err := runThemesCreate(cfg, loops.CreateThemeRequest{ |
| 174 | + Name: params.Name, |
| 175 | + Styles: params.Styles, |
| 176 | + }) |
| 177 | + if err != nil { |
116 | 178 | return err |
117 | 179 | } |
118 | 180 |
|
119 | | - fmt.Fprintln(cmd.OutOrStdout()) |
120 | | - return printThemeStyles(cmd, th.Styles) |
| 181 | + if isJSONOutput() { |
| 182 | + return printJSON(cmd.OutOrStdout(), th) |
| 183 | + } |
| 184 | + |
| 185 | + fmt.Fprintf(cmd.OutOrStdout(), "Created. (id: %s)\n\n", th.ID) |
| 186 | + return printTheme(cmd, th) |
| 187 | + }, |
| 188 | +} |
| 189 | + |
| 190 | +var themesUpdateCmd = &cobra.Command{ |
| 191 | + Use: "update <id>", |
| 192 | + Short: "Update a theme", |
| 193 | + Args: cobra.ExactArgs(1), |
| 194 | + RunE: func(cmd *cobra.Command, args []string) error { |
| 195 | + params, err := themeFieldParamsFromCmd(cmd) |
| 196 | + if err != nil { |
| 197 | + return err |
| 198 | + } |
| 199 | + |
| 200 | + cfg, err := loadConfig() |
| 201 | + if err != nil { |
| 202 | + return err |
| 203 | + } |
| 204 | + |
| 205 | + th, err := runThemesUpdate(cfg, args[0], loops.UpdateThemeRequest{ |
| 206 | + Name: params.Name, |
| 207 | + Styles: params.Styles, |
| 208 | + }) |
| 209 | + if err != nil { |
| 210 | + return err |
| 211 | + } |
| 212 | + |
| 213 | + if isJSONOutput() { |
| 214 | + return printJSON(cmd.OutOrStdout(), th) |
| 215 | + } |
| 216 | + |
| 217 | + fmt.Fprintf(cmd.OutOrStdout(), "Updated. (id: %s)\n\n", th.ID) |
| 218 | + return printTheme(cmd, th) |
121 | 219 | }, |
122 | 220 | } |
123 | 221 |
|
| 222 | +func printTheme(cmd *cobra.Command, th *loops.Theme) error { |
| 223 | + t := newStyledTable(cmd.OutOrStdout(), "FIELD", "VALUE") |
| 224 | + t.Row("themeId", th.ID) |
| 225 | + t.Row("name", th.Name) |
| 226 | + t.Row("isDefault", strconv.FormatBool(th.IsDefault)) |
| 227 | + t.Row("createdAt", th.CreatedAt) |
| 228 | + t.Row("updatedAt", th.UpdatedAt) |
| 229 | + if err := t.Render(); err != nil { |
| 230 | + return err |
| 231 | + } |
| 232 | + |
| 233 | + fmt.Fprintln(cmd.OutOrStdout()) |
| 234 | + return printThemeStyles(cmd, th.Styles) |
| 235 | +} |
| 236 | + |
124 | 237 | func printThemeStyles(cmd *cobra.Command, s loops.ThemeStyles) error { |
125 | 238 | t := newStyledTable(cmd.OutOrStdout(), "STYLE", "VALUE") |
126 | 239 | for _, row := range themeStyleRows(s) { |
@@ -189,5 +302,14 @@ func init() { |
189 | 302 | addPickFlag(themesListCmd) |
190 | 303 | themesCmd.AddCommand(themesListCmd) |
191 | 304 | themesCmd.AddCommand(themesGetCmd) |
| 305 | + |
| 306 | + addThemeFieldFlags(themesCreateCmd) |
| 307 | + themesCreateCmd.MarkFlagRequired("name") |
| 308 | + themesCmd.AddCommand(themesCreateCmd) |
| 309 | + |
| 310 | + addThemeFieldFlags(themesUpdateCmd) |
| 311 | + themesUpdateCmd.MarkFlagsOneRequired("name", "styles-file") |
| 312 | + themesCmd.AddCommand(themesUpdateCmd) |
| 313 | + |
192 | 314 | rootCmd.AddCommand(themesCmd) |
193 | 315 | } |
0 commit comments