Skip to content

Commit 37c089e

Browse files
committed
feat: add preloading of the stainless config and openapi path
1 parent ad64eb7 commit 37c089e

File tree

4 files changed

+78
-169
lines changed

4 files changed

+78
-169
lines changed

build.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ var buildsCreate = cli.Command{
142142
Action: getAPIFlagAction[string]("body", "targets.-1"),
143143
},
144144
},
145-
Before: initAPICommand,
145+
Before: initAPICommandWithWorkspaceDefaults,
146146
Action: handleBuildsCreate,
147147
HideHelpCommand: true,
148148
}
@@ -526,3 +526,28 @@ func handleBuildsCompare(ctx context.Context, cmd *cli.Command) error {
526526
fmt.Printf("%s\n", colorizeJSON(res.RawJSON(), os.Stdout))
527527
return nil
528528
}
529+
530+
// initAPICommandWithWorkspaceDefaults applies workspace defaults before initializing API command
531+
func initAPICommandWithWorkspaceDefaults(ctx context.Context, cmd *cli.Command) (context.Context, error) {
532+
cc, err := initAPICommand(ctx, cmd)
533+
if err != nil {
534+
return nil, err
535+
}
536+
config, _, err := FindWorkspaceConfig()
537+
if err == nil && config != nil {
538+
if !cmd.IsSet("openapi-spec") && !cmd.IsSet("oas") && config.OpenAPISpec != "" {
539+
fileAction := getAPIFlagFileAction("body", "revision.openapi\\.yml.content")
540+
if err := fileAction(cc, cmd, config.OpenAPISpec); err != nil {
541+
return nil, fmt.Errorf("failed to load OpenAPI spec from workspace config: %v", err)
542+
}
543+
}
544+
545+
if !cmd.IsSet("stainless-config") && !cmd.IsSet("config") && config.StainlessConfig != "" {
546+
fileAction := getAPIFlagFileAction("body", "revision.openapi\\.stainless\\.yml.content")
547+
if err := fileAction(cc, cmd, config.StainlessConfig); err != nil {
548+
return nil, fmt.Errorf("failed to load Stainless config from workspace config: %v", err)
549+
}
550+
}
551+
}
552+
return cc, err
553+
}

initworkspace.go

Lines changed: 0 additions & 150 deletions
This file was deleted.

util.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ func CheckInteractiveAndInitWorkspace(cmd *cli.Command, projectName string) {
337337
fmt.Scanln(&answer)
338338

339339
if strings.ToLower(answer) == "y" || strings.ToLower(answer) == "yes" {
340-
if err := InitWorkspaceConfig(projectName); err != nil {
340+
if err := InitWorkspaceConfig(projectName, "", ""); err != nil {
341341
fmt.Printf("%s %s\n", au.BrightRed("✱"), fmt.Sprintf("Failed to initialize workspace: %v", err))
342342
return
343343
}

workspace.go

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ package main
44

55
import (
66
"context"
7+
"encoding/json"
78
"fmt"
89
"maps"
910
"os"
1011
"path/filepath"
1112
"slices"
1213
"strings"
1314

14-
"encoding/json"
1515
"github.com/charmbracelet/bubbles/key"
1616
"github.com/charmbracelet/huh"
1717
"github.com/charmbracelet/lipgloss"
@@ -56,21 +56,34 @@ func handleInitWorkspace(ctx context.Context, cmd *cli.Command) error {
5656

5757
fmt.Println()
5858

59-
// If project name wasn't provided via flag, prompt the user interactively
59+
// Set up form theme and keymap for use in multiple forms
60+
keyMap := huh.NewDefaultKeyMap()
61+
keyMap.Input.AcceptSuggestion = key.NewBinding(
62+
key.WithKeys("tab"),
63+
key.WithHelp("tab", "complete"),
64+
)
65+
keyMap.Input.Next = key.NewBinding(
66+
key.WithKeys("tab", "down", "enter"),
67+
key.WithHelp("tab/↓/enter", "next"),
68+
)
69+
keyMap.Input.Prev = key.NewBinding(
70+
key.WithKeys("shift+tab", "up"),
71+
key.WithHelp("shift+tab/↑", "previous"),
72+
)
73+
74+
// Create custom theme with bullet point cursor and no borders
75+
theme := huh.ThemeBase()
76+
theme.Focused.Base = theme.Focused.Base.BorderStyle(lipgloss.NormalBorder())
77+
theme.Focused.Title = theme.Focused.Title.Bold(true)
78+
79+
// Get project name from flag or prepare for interactive prompt
6080
projectName := cmd.String("project-name")
81+
var openAPISpec, stainlessConfig string
82+
83+
// If project name wasn't provided via flag, prompt for all fields interactively
6184
if projectName == "" {
6285
projectInfoMap := fetchUserProjects(ctx)
6386

64-
keyMap := huh.NewDefaultKeyMap()
65-
keyMap.Input.AcceptSuggestion = key.NewBinding(
66-
key.WithKeys("tab"),
67-
key.WithHelp("tab", "complete"),
68-
)
69-
70-
// Create custom theme with bullet point cursor and no borders
71-
theme := huh.ThemeBase()
72-
theme.Focused.Base = theme.Focused.Base.BorderStyle(lipgloss.NormalBorder())
73-
theme.Focused.Title = theme.Focused.Title.Bold(true)
7487
form := huh.NewForm(
7588
huh.NewGroup(
7689
huh.NewInput().
@@ -79,16 +92,33 @@ func handleInitWorkspace(ctx context.Context, cmd *cli.Command) error {
7992
Suggestions(slices.Collect(maps.Keys(projectInfoMap))).
8093
Description("Enter the stainless project for this workspace").
8194
Validate(createProjectValidator(projectInfoMap)),
95+
huh.NewInput().
96+
Title("OpenAPI spec path (optional)").
97+
Description("Relative path to your OpenAPI spec file").
98+
Placeholder("openapi.yml").
99+
Value(&openAPISpec),
100+
huh.NewInput().
101+
Title("Stainless config path (optional)").
102+
Description("Relative path to your Stainless config file").
103+
Placeholder("openapi.stainless.yml").
104+
Value(&stainlessConfig),
82105
),
83106
).WithTheme(theme).WithKeyMap(keyMap)
84107

85108
if err := form.Run(); err != nil {
86-
return fmt.Errorf("failed to get project name: %v", err)
109+
return fmt.Errorf("failed to get workspace configuration: %v", err)
87110
}
111+
88112
fmt.Printf("%s project name: %s\n", aurora.Bold("✱"), projectName)
113+
if openAPISpec != "" {
114+
fmt.Printf("%s openapi spec: %s\n", aurora.Bold("✱"), openAPISpec)
115+
}
116+
if stainlessConfig != "" {
117+
fmt.Printf("%s stainless config: %s\n", aurora.Bold("✱"), stainlessConfig)
118+
}
89119
}
90120

91-
if err := InitWorkspaceConfig(projectName); err != nil {
121+
if err := InitWorkspaceConfig(projectName, openAPISpec, stainlessConfig); err != nil {
92122
return fmt.Errorf("failed to initialize workspace: %v", err)
93123
}
94124

@@ -152,7 +182,9 @@ func createProjectValidator(projectInfoMap map[string]projectInfo) func(string)
152182

153183
// WorkspaceConfig stores workspace-level configuration
154184
type WorkspaceConfig struct {
155-
ProjectName string `json:"projectName"`
185+
ProjectName string `json:"projectName"`
186+
OpenAPISpec string `json:"openapi_spec,omitempty"`
187+
StainlessConfig string `json:"stainless_config,omitempty"`
156188
}
157189

158190
// FindWorkspaceConfig searches for a stainless-workspace.json file starting from the current directory
@@ -224,7 +256,7 @@ func GetProjectNameFromConfig() string {
224256
}
225257

226258
// InitWorkspaceConfig initializes a new workspace config in the current directory
227-
func InitWorkspaceConfig(projectName string) error {
259+
func InitWorkspaceConfig(projectName, openAPISpec, stainlessConfig string) error {
228260
// Get current working directory
229261
dir, err := os.Getwd()
230262
if err != nil {
@@ -233,7 +265,9 @@ func InitWorkspaceConfig(projectName string) error {
233265

234266
configPath := filepath.Join(dir, "stainless-workspace.json")
235267
config := WorkspaceConfig{
236-
ProjectName: projectName,
268+
ProjectName: projectName,
269+
OpenAPISpec: openAPISpec,
270+
StainlessConfig: stainlessConfig,
237271
}
238272

239273
return SaveWorkspaceConfig(configPath, &config)

0 commit comments

Comments
 (0)