Skip to content

Commit 41e60d6

Browse files
committed
fix(apps): align missing app name errors
Reuse the shared missing-name validation for logs and render each command's documented positional argument name.
1 parent 7eea43d commit 41e60d6

4 files changed

Lines changed: 55 additions & 19 deletions

File tree

cmd/apps/bundle_helpers.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,22 @@ func makeArgsOptionalWithBundle(cmd *cobra.Command, usage string) {
4242
func missingAppNameError(cmd *cobra.Command) error {
4343
hint := inferAppNameHint()
4444
commandPath := "databricks apps <command>"
45+
argName := "APP_NAME"
4546
if cmd != nil {
4647
if p := cmd.CommandPath(); p != "" {
4748
commandPath = p
4849
}
50+
if name := positionalArgName(cmd.Use); name != "" {
51+
argName = name
52+
}
4953
}
50-
msg := fmt.Sprintf(`missing required argument: APP_NAME
54+
msg := fmt.Sprintf(`missing required argument: %s
5155
52-
Usage: %s APP_NAME
56+
Usage: %s %s
5357
54-
APP_NAME is the name of the Databricks app to operate on.
58+
%s is the name of the Databricks app to operate on.
5559
Alternatively, run this command from a project directory containing
56-
databricks.yml to auto-detect the app name.`, commandPath)
60+
databricks.yml to auto-detect the app name.`, argName, commandPath, argName, argName)
5761

5862
if hint != "" {
5963
msg += fmt.Sprintf("\n\nDid you mean?\n %s %s", commandPath, hint)
@@ -62,6 +66,15 @@ databricks.yml to auto-detect the app name.`, commandPath)
6266
return errors.New(msg)
6367
}
6468

69+
func positionalArgName(use string) string {
70+
start := strings.Index(use, "[")
71+
end := strings.Index(use, "]")
72+
if start < 0 || end <= start {
73+
return ""
74+
}
75+
return use[start+1 : end]
76+
}
77+
6578
// inferAppNameHint tries to suggest an app name from the local environment.
6679
// Only returns a hint if the current directory looks like a Databricks app
6780
// (contains app.yml or app.yaml), using the directory name as the suggestion.

cmd/apps/bundle_helpers_test.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,17 +178,27 @@ func TestMissingAppNameError(t *testing.T) {
178178
writeErr := os.WriteFile(filepath.Join(dir, "app.yml"), []byte("command: [\"python\"]"), 0o644)
179179
assert.NoError(t, writeErr)
180180

181-
for _, verb := range []string{"deploy", "start", "stop", "delete"} {
182-
t.Run(verb, func(t *testing.T) {
181+
for _, tc := range []struct {
182+
verb string
183+
use string
184+
arg string
185+
}{
186+
{"deploy", "deploy [APP_NAME]", "APP_NAME"},
187+
{"start", "start [NAME]", "NAME"},
188+
{"stop", "stop [NAME]", "NAME"},
189+
{"delete", "delete [NAME]", "NAME"},
190+
} {
191+
t.Run(tc.verb, func(t *testing.T) {
183192
root := &cobra.Command{Use: "databricks"}
184193
apps := &cobra.Command{Use: "apps"}
185-
sub := &cobra.Command{Use: verb}
194+
sub := &cobra.Command{Use: tc.use}
186195
root.AddCommand(apps)
187196
apps.AddCommand(sub)
188197

189198
err := missingAppNameError(sub)
190-
assert.Contains(t, err.Error(), "Usage: databricks apps "+verb+" APP_NAME")
191-
assert.Contains(t, err.Error(), "databricks apps "+verb+" "+filepath.Base(dir))
199+
assert.Contains(t, err.Error(), "missing required argument: "+tc.arg)
200+
assert.Contains(t, err.Error(), "Usage: databricks apps "+tc.verb+" "+tc.arg)
201+
assert.Contains(t, err.Error(), "databricks apps "+tc.verb+" "+filepath.Base(dir))
192202
})
193203
}
194204
})
@@ -215,6 +225,17 @@ func TestMakeArgsOptionalWithBundle(t *testing.T) {
215225
makeArgsOptionalWithBundle(cmd, "test [NAME]")
216226
assert.NotNil(t, cmd.Args)
217227
})
228+
229+
t.Run("returns missing app name error when no bundle config exists", func(t *testing.T) {
230+
t.Chdir(t.TempDir())
231+
232+
cmd := &cobra.Command{}
233+
makeArgsOptionalWithBundle(cmd, "test [NAME]")
234+
235+
err := cmd.Args(cmd, nil)
236+
assert.Error(t, err)
237+
assert.Contains(t, err.Error(), "missing required argument: NAME")
238+
})
218239
}
219240

220241
func TestGetAppNameFromArgs(t *testing.T) {

cmd/apps/logs.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ func newLogsCommand() *cobra.Command {
4646
)
4747

4848
cmd := &cobra.Command{
49-
Use: "logs [NAME]",
5049
Short: "Show Databricks app logs",
5150
Long: `Show Databricks app logs.
5251
@@ -78,15 +77,6 @@ Examples:
7877
7978
# Mirror streamed logs to a local file while following for up to 5 minutes
8079
databricks apps logs my-app --follow --timeout 5m --output-file /tmp/my-app.log`,
81-
Args: func(cmd *cobra.Command, args []string) error {
82-
if len(args) > 1 {
83-
return fmt.Errorf("accepts at most 1 arg(s), received %d", len(args))
84-
}
85-
if !hasBundleConfig() && len(args) != 1 {
86-
return fmt.Errorf("accepts 1 arg(s), received %d", len(args))
87-
}
88-
return nil
89-
},
9080
PreRunE: root.MustWorkspaceClient,
9181
RunE: func(cmd *cobra.Command, args []string) error {
9282
appName, fromBundle, err := getAppNameFromArgs(cmd, args)
@@ -207,6 +197,7 @@ Examples:
207197
})
208198
},
209199
}
200+
makeArgsOptionalWithBundle(cmd, "logs [NAME]")
210201

211202
streamGroup := cmdgroup.NewFlagGroup("Streaming")
212203
streamGroup.FlagSet().IntVar(&tailLines, "tail-lines", defaultTailLines, "Number of recent log lines to show before streaming. Set to 0 to show everything.")

cmd/apps/logs_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,17 @@ func TestBuildLogsURLRejectsUnknownScheme(t *testing.T) {
6464
require.Error(t, err)
6565
}
6666

67+
func TestLogsMissingNameError(t *testing.T) {
68+
t.Chdir(t.TempDir())
69+
70+
cmd := newLogsCommand()
71+
err := cmd.Args(cmd, nil)
72+
73+
require.Error(t, err)
74+
assert.Contains(t, err.Error(), "missing required argument: NAME")
75+
assert.Contains(t, err.Error(), "Usage: logs NAME")
76+
}
77+
6778
func TestNormalizeOrigin(t *testing.T) {
6879
assert.Equal(t, "https://example.com", normalizeOrigin("https://example.com/foo"))
6980
assert.Equal(t, "http://example.com", normalizeOrigin("ws://example.com/foo"))

0 commit comments

Comments
 (0)