Skip to content

Commit c837987

Browse files
committed
refactor: fix test and refactor structure
1 parent f54d0d4 commit c837987

File tree

3 files changed

+74
-47
lines changed

3 files changed

+74
-47
lines changed

cmd/create.go

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cmd
22

33
import (
4+
"context"
45
"fmt"
56
"os"
67
"path/filepath"
@@ -10,77 +11,94 @@ import (
1011
"github.com/spf13/cobra"
1112
)
1213

13-
var createCmd = &cobra.Command{
14-
Use: "create",
15-
Short: "Create a new application",
16-
Long: "Commands for creating new Kernel applications",
17-
RunE: runCreateApp,
14+
type CreateInput struct {
15+
Name string
16+
Language string
17+
Template string
1818
}
1919

20-
func init() {
21-
createCmd.Flags().StringP("name", "n", "", "Name of the application")
22-
createCmd.Flags().StringP("language", "l", "", "Language of the application")
23-
createCmd.Flags().StringP("template", "t", "", "Template to use for the application")
24-
}
25-
26-
func runCreateApp(cmd *cobra.Command, args []string) error {
27-
appName, _ := cmd.Flags().GetString("name")
28-
language, _ := cmd.Flags().GetString("language")
29-
template, _ := cmd.Flags().GetString("template")
20+
// CreateCmd is a cobra-independent command handler for create operations
21+
type CreateCmd struct{}
3022

31-
appName, err := create.PromptForAppName(appName)
32-
if err != nil {
33-
return fmt.Errorf("failed to get app name: %w", err)
34-
}
35-
36-
language, err = create.PromptForLanguage(language)
37-
if err != nil {
38-
return fmt.Errorf("failed to get language: %w", err)
39-
}
40-
41-
template, err = create.PromptForTemplate(template)
42-
if err != nil {
43-
return fmt.Errorf("failed to get template: %w", err)
44-
}
45-
46-
// Get absolute path for the app directory
47-
appPath, err := filepath.Abs(appName)
23+
// Create executes the create logic
24+
func (c CreateCmd) Create(ctx context.Context, ci CreateInput) error {
25+
appPath, err := filepath.Abs(ci.Name)
4826
if err != nil {
4927
return fmt.Errorf("failed to resolve app path: %w", err)
5028
}
5129

5230
// TODO: handle overwrite gracefully (prompt user)
5331
// Check if directory already exists
5432
if _, err := os.Stat(appPath); err == nil {
55-
return fmt.Errorf("directory %s already exists", appName)
33+
return fmt.Errorf("directory %s already exists", ci.Name)
5634
}
5735

58-
// Create the app directory
5936
if err := os.MkdirAll(appPath, 0755); err != nil {
6037
return fmt.Errorf("failed to create directory: %w", err)
6138
}
6239

63-
pterm.Println(fmt.Sprintf("\nCreating a new %s %s\n", language, template))
40+
pterm.Println(fmt.Sprintf("\nCreating a new %s %s\n", ci.Language, ci.Template))
6441

6542
spinner, _ := pterm.DefaultSpinner.Start("Copying template files...")
6643

67-
if err := create.CopyTemplateFiles(appPath, language, template); err != nil {
44+
if err := create.CopyTemplateFiles(appPath, ci.Language, ci.Template); err != nil {
6845
spinner.Fail("Failed to copy template files")
6946
return fmt.Errorf("failed to copy template files: %w", err)
7047
}
71-
spinner.Success(fmt.Sprintf("✔ %s environment set up successfully", language))
48+
spinner.Success(fmt.Sprintf("✔ %s environment set up successfully", ci.Language))
7249

7350
nextSteps := fmt.Sprintf(`Next steps:
7451
brew install onkernel/tap/kernel
7552
cd %s
7653
kernel login # or: export KERNEL_API_KEY=<YOUR_API_KEY>
7754
kernel deploy index.ts
7855
kernel invoke ts-basic get-page-title --payload '{"url": "https://www.google.com"}'
79-
`, appName)
56+
`, ci.Name)
8057

8158
pterm.Success.Println("🎉 Kernel app created successfully!")
8259
pterm.Println()
8360
pterm.FgYellow.Println(nextSteps)
8461

8562
return nil
8663
}
64+
65+
var createCmd = &cobra.Command{
66+
Use: "create",
67+
Short: "Create a new application",
68+
Long: "Commands for creating new Kernel applications",
69+
RunE: runCreateApp,
70+
}
71+
72+
func init() {
73+
createCmd.Flags().StringP("name", "n", "", "Name of the application")
74+
createCmd.Flags().StringP("language", "l", "", "Language of the application")
75+
createCmd.Flags().StringP("template", "t", "", "Template to use for the application")
76+
}
77+
78+
func runCreateApp(cmd *cobra.Command, args []string) error {
79+
appName, _ := cmd.Flags().GetString("name")
80+
language, _ := cmd.Flags().GetString("language")
81+
template, _ := cmd.Flags().GetString("template")
82+
83+
appName, err := create.PromptForAppName(appName)
84+
if err != nil {
85+
return fmt.Errorf("failed to get app name: %w", err)
86+
}
87+
88+
language, err = create.PromptForLanguage(language)
89+
if err != nil {
90+
return fmt.Errorf("failed to get language: %w", err)
91+
}
92+
93+
template, err = create.PromptForTemplate(template)
94+
if err != nil {
95+
return fmt.Errorf("failed to get template: %w", err)
96+
}
97+
98+
c := CreateCmd{}
99+
return c.Create(cmd.Context(), CreateInput{
100+
Name: appName,
101+
Language: language,
102+
Template: template,
103+
})
104+
}

cmd/create_test.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cmd
22

33
import (
4+
"context"
45
"os"
56
"path/filepath"
67
"testing"
@@ -12,14 +13,18 @@ import (
1213
func TestCreateCommand(t *testing.T) {
1314
tests := []struct {
1415
name string
15-
args []string
16+
input CreateInput
1617
wantErr bool
1718
errContains string
1819
validate func(t *testing.T, appPath string)
1920
}{
2021
{
2122
name: "create typescript sample-app",
22-
args: []string{"--name", "test-app", "--language", "typescript", "--template", "sample-app"},
23+
input: CreateInput{
24+
Name: "test-app",
25+
Language: "typescript",
26+
Template: "sample-app",
27+
},
2328
validate: func(t *testing.T, appPath string) {
2429
// Verify files were created
2530
assert.FileExists(t, filepath.Join(appPath, "index.ts"))
@@ -29,10 +34,14 @@ func TestCreateCommand(t *testing.T) {
2934
},
3035
},
3136
{
32-
name: "fail with python sample-app (template not found)",
33-
args: []string{"--name", "test-app", "--language", "python", "--template", "sample-app"},
37+
name: "fail with invalid template",
38+
input: CreateInput{
39+
Name: "test-app",
40+
Language: "typescript",
41+
Template: "nonexistent",
42+
},
3443
wantErr: true,
35-
errContains: "template not found: python/sample-app",
44+
errContains: "template not found: typescript/nonexistent",
3645
},
3746
}
3847

@@ -50,8 +59,8 @@ func TestCreateCommand(t *testing.T) {
5059
os.Chdir(orgDir)
5160
})
5261

53-
createCmd.SetArgs(tt.args)
54-
err = createCmd.Execute()
62+
c := CreateCmd{}
63+
err = c.Create(context.Background(), tt.input)
5564

5665
// Check if error is expected
5766
if tt.wantErr {
@@ -65,7 +74,7 @@ func TestCreateCommand(t *testing.T) {
6574
require.NoError(t, err, "failed to execute create command")
6675

6776
// Validate the created app
68-
appPath := filepath.Join(tmpDir, "test-app")
77+
appPath := filepath.Join(tmpDir, tt.input.Name)
6978
assert.DirExists(t, appPath, "app directory should be created")
7079

7180
if tt.validate != nil {

pkg/create/prompts.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func validateAppName(val any) error {
3333

3434
// handleAppNamePrompt prompts the user for an app name interactively.
3535
func handleAppNamePrompt() (string, error) {
36-
promptText := fmt.Sprintf("%s (default: %s)", AppNamePrompt, DefaultAppName)
36+
promptText := fmt.Sprintf("%s (%s)", AppNamePrompt, DefaultAppName)
3737
appName, err := pterm.DefaultInteractiveTextInput.
3838
WithDefaultText(promptText).
3939
Show()

0 commit comments

Comments
 (0)