From ff7717c3d108d824b5051e244765c51cf3a05b7a Mon Sep 17 00:00:00 2001 From: Zach Casper Date: Tue, 28 Apr 2026 11:00:26 -0500 Subject: [PATCH 1/6] Update rad commands with concise output Signed-off-by: Zach Casper --- pkg/cli/cmd/app/delete/delete.go | 8 +- pkg/cli/cmd/app/delete/delete_test.go | 8 +- pkg/cli/cmd/env/create/create.go | 4 +- pkg/cli/cmd/env/create/create_test.go | 14 +-- pkg/cli/cmd/env/create/preview/create.go | 4 +- pkg/cli/cmd/env/create/preview/create_test.go | 6 +- pkg/cli/cmd/env/delete/delete.go | 15 +-- pkg/cli/cmd/env/delete/delete_test.go | 42 ++------ pkg/cli/cmd/env/delete/preview/delete.go | 12 +-- pkg/cli/cmd/env/delete/preview/delete_test.go | 5 +- pkg/cli/cmd/env/update/preview/update.go | 30 +----- pkg/cli/cmd/env/update/preview/update_test.go | 14 +-- pkg/cli/cmd/env/update/update.go | 33 +----- pkg/cli/cmd/env/update/update_test.go | 44 +------- pkg/cli/cmd/group/create/create.go | 4 +- pkg/cli/cmd/group/create/create_test.go | 6 +- pkg/cli/cmd/group/delete/delete.go | 14 +-- pkg/cli/cmd/group/delete/delete_test.go | 101 +++++------------- pkg/cli/cmd/recipepack/delete/delete.go | 11 +- pkg/cli/cmd/resource/create/create.go | 9 +- pkg/cli/cmd/resource/delete/delete.go | 7 +- pkg/cli/cmd/resourceprovider/create/create.go | 19 +--- .../resourceprovider/create/create_test.go | 22 ++-- pkg/cli/cmd/resourceprovider/delete/delete.go | 4 +- .../resourceprovider/delete/delete_test.go | 6 +- pkg/cli/cmd/resourcetype/create/create.go | 18 ++-- .../cmd/resourcetype/create/create_test.go | 66 ++++-------- pkg/cli/cmd/resourcetype/delete/delete.go | 4 +- .../cmd/resourcetype/delete/delete_test.go | 6 +- pkg/cli/cmd/workspace/create/create.go | 4 +- pkg/cli/cmd/workspace/delete/delete.go | 1 + pkg/cli/cmd/workspace/delete/delete_test.go | 14 ++- 32 files changed, 134 insertions(+), 421 deletions(-) diff --git a/pkg/cli/cmd/app/delete/delete.go b/pkg/cli/cmd/app/delete/delete.go index a6b23af773..581af73c89 100644 --- a/pkg/cli/cmd/app/delete/delete.go +++ b/pkg/cli/cmd/app/delete/delete.go @@ -163,7 +163,7 @@ func (r *Runner) Run(ctx context.Context) error { app, err := client.GetApplication(ctx, r.ApplicationName) if clients.Is404Error(err) { - r.Output.LogInfo("Application '%s' does not exist or has already been deleted.", r.ApplicationName) + r.Output.LogInfo("Applications.Core/applications/%s not found", r.ApplicationName) return nil } else if err != nil { return err @@ -194,15 +194,15 @@ func (r *Runner) Run(ctx context.Context) error { }) if err != nil { if strings.Contains(err.Error(), "not found") { - r.Output.LogInfo("Application '%s' does not exist or has already been deleted.", r.ApplicationName) + r.Output.LogInfo("Applications.Core/applications/%s not found", r.ApplicationName) return nil } return clierrors.Message("Failed to delete application '%s': %v", r.ApplicationName, err) } if deleted { - r.Output.LogInfo("Application %s deleted successfully", r.ApplicationName) + r.Output.LogInfo("Applications.Core/applications/%s deleted", r.ApplicationName) } else { - r.Output.LogInfo("Application '%s' does not exist or has already been deleted.", r.ApplicationName) + r.Output.LogInfo("Applications.Core/applications/%s not found", r.ApplicationName) return nil } diff --git a/pkg/cli/cmd/app/delete/delete_test.go b/pkg/cli/cmd/app/delete/delete_test.go index 3ce36e9712..e89457d54e 100644 --- a/pkg/cli/cmd/app/delete/delete_test.go +++ b/pkg/cli/cmd/app/delete/delete_test.go @@ -171,7 +171,7 @@ func Test_Delete(t *testing.T) { expected := []any{ output.LogOutput{ - Format: "Application %s deleted successfully", + Format: "Applications.Core/applications/%s deleted", Params: []any{"test-app"}, }, } @@ -240,7 +240,7 @@ func Test_Delete(t *testing.T) { expected := []any{ output.LogOutput{ - Format: "Application %s deleted successfully", + Format: "Applications.Core/applications/%s deleted", Params: []any{"test-app"}, }, } @@ -354,7 +354,7 @@ func Test_Delete(t *testing.T) { expected := []any{ output.LogOutput{ - Format: "Application '%s' does not exist or has already been deleted.", + Format: "Applications.Core/applications/%s not found", Params: []any{"test-app"}, }, } @@ -522,7 +522,7 @@ func Test_Delete(t *testing.T) { expected := []any{ output.LogOutput{ - Format: "Application '%s' does not exist or has already been deleted.", + Format: "Applications.Core/applications/%s not found", Params: []any{"test-app"}, }, } diff --git a/pkg/cli/cmd/env/create/create.go b/pkg/cli/cmd/env/create/create.go index de04f3acb0..548d0ad1a3 100644 --- a/pkg/cli/cmd/env/create/create.go +++ b/pkg/cli/cmd/env/create/create.go @@ -150,8 +150,6 @@ func (r *Runner) Validate(cmd *cobra.Command, args []string) error { // Run creates an environment in the specified resource group using the provided environment name and namespace, and // returns an error if unsuccessful. func (r *Runner) Run(ctx context.Context) error { - r.Output.LogInfo("Creating Environment...") - client, err := r.ConnectionFactory.CreateApplicationsManagementClient(ctx, *r.Workspace) if err != nil { return err @@ -170,7 +168,7 @@ func (r *Runner) Run(ctx context.Context) error { if err != nil { return err } - r.Output.LogInfo("Successfully created environment %q in resource group %q", r.EnvironmentName, r.ResourceGroupName) + r.Output.LogInfo("Applications.Core/environments/%s created", r.EnvironmentName) return nil } diff --git a/pkg/cli/cmd/env/create/create_test.go b/pkg/cli/cmd/env/create/create_test.go index ed5df50d23..2450ff707a 100644 --- a/pkg/cli/cmd/env/create/create_test.go +++ b/pkg/cli/cmd/env/create/create_test.go @@ -188,13 +188,9 @@ func Test_Run(t *testing.T) { expectedOutput := []any{ output.LogOutput{ - Format: "Creating Environment...", - }, - output.LogOutput{ - Format: "Successfully created environment %q in resource group %q", + Format: "Applications.Core/environments/%s created", Params: []any{ "default", - "test-group", }, }, } @@ -247,16 +243,10 @@ func Test_Run(t *testing.T) { ConfigFileInterface: configFileInterface, } - expectedOutput := []any{ - output.LogOutput{ - Format: "Creating Environment...", - }, - } - err := runner.Run(context.Background()) require.Error(t, err) require.Equal(t, expectedError, err) - require.Equal(t, expectedOutput, outputSink.Writes) + require.Empty(t, outputSink.Writes) }) } diff --git a/pkg/cli/cmd/env/create/preview/create.go b/pkg/cli/cmd/env/create/preview/create.go index 9d5d723a78..bd26bc2f89 100644 --- a/pkg/cli/cmd/env/create/preview/create.go +++ b/pkg/cli/cmd/env/create/preview/create.go @@ -141,8 +141,6 @@ func (r *Runner) Run(ctx context.Context) error { r.RadiusCoreClientFactory = clientFactory } - r.Output.LogInfo("Creating Radius Core Environment...") - resource := &corerpv20250801.EnvironmentResource{ Location: to.Ptr(v1.LocationGlobal), Properties: &corerpv20250801.EnvironmentProperties{}, @@ -153,7 +151,7 @@ func (r *Runner) Run(ctx context.Context) error { if err != nil { return err } - r.Output.LogInfo("Successfully created environment %q in resource group %q", r.EnvironmentName, r.ResourceGroupName) + r.Output.LogInfo("Radius.Core/environments/%s created", r.EnvironmentName) return nil } diff --git a/pkg/cli/cmd/env/create/preview/create_test.go b/pkg/cli/cmd/env/create/preview/create_test.go index 09749fd05a..809e135a9f 100644 --- a/pkg/cli/cmd/env/create/preview/create_test.go +++ b/pkg/cli/cmd/env/create/preview/create_test.go @@ -167,13 +167,9 @@ func Test_Run(t *testing.T) { expectedOutput := []any{ output.LogOutput{ - Format: "Creating Radius Core Environment...", - }, - output.LogOutput{ - Format: "Successfully created environment %q in resource group %q", + Format: "Radius.Core/environments/%s created", Params: []any{ "testenv", - "test-resource-group", }, }, } diff --git a/pkg/cli/cmd/env/delete/delete.go b/pkg/cli/cmd/env/delete/delete.go index 520937643a..b9b1d98d42 100644 --- a/pkg/cli/cmd/env/delete/delete.go +++ b/pkg/cli/cmd/env/delete/delete.go @@ -31,10 +31,8 @@ import ( ) const ( - msgEnvironmentDeleted = "Environment deleted" - msgEnvironmentNotFound = "Environment '%s' does not exist or has already been deleted." - msgDeletingEnvironment = "Deleting environment %s...\n" - msgDeletingResourceCount = "Deleting %d resource(s) in environment %s...\n" + msgEnvironmentDeleted = "Applications.Core/environments/%s deleted" + msgEnvironmentNotFound = "Applications.Core/environments/%s not found" ) // NewCommand creates an instance of the command and runner for the `rad env delete` command. @@ -166,24 +164,17 @@ func (r *Runner) Run(ctx context.Context) error { return err } if !confirmed { - r.Output.LogInfo("Environment %q NOT deleted", r.EnvironmentName) return nil } } - // Show progress messages - if totalResourceCount > 0 { - r.Output.LogInfo(msgDeletingResourceCount, totalResourceCount, r.EnvironmentName) - } - r.Output.LogInfo(msgDeletingEnvironment, r.EnvironmentName) - deleted, err := client.DeleteEnvironment(ctx, r.EnvironmentName) if err != nil { return err } if deleted { - r.Output.LogInfo(msgEnvironmentDeleted) + r.Output.LogInfo(msgEnvironmentDeleted, r.EnvironmentName) } else { r.Output.LogInfo(msgEnvironmentNotFound, r.EnvironmentName) } diff --git a/pkg/cli/cmd/env/delete/delete_test.go b/pkg/cli/cmd/env/delete/delete_test.go index 0c528d9b16..9c3aebf5b5 100644 --- a/pkg/cli/cmd/env/delete/delete_test.go +++ b/pkg/cli/cmd/env/delete/delete_test.go @@ -39,7 +39,7 @@ func Test_CommandValidation(t *testing.T) { } const ( - deleteConfirmationEmpty = "The environment %s is empty. Are you sure you want to delete the environment?" + deleteConfirmationEmpty = "The environment %s is empty. Are you sure you want to delete the environment?" deleteConfirmationWithResources = "The environment %s contains %d deployed resource(s). Are you sure you want to delete the environment and its resources?" ) @@ -145,12 +145,9 @@ func Test_Show(t *testing.T) { require.NoError(t, err) expected := []any{ - output.LogOutput{ - Format: msgDeletingEnvironment, - Params: []any{"test-env"}, - }, output.LogOutput{ Format: msgEnvironmentDeleted, + Params: []any{"test-env"}, }, } @@ -201,12 +198,9 @@ func Test_Show(t *testing.T) { require.NoError(t, err) expected := []any{ - output.LogOutput{ - Format: msgDeletingEnvironment, - Params: []any{"test-env"}, - }, output.LogOutput{ Format: msgEnvironmentDeleted, + Params: []any{"test-env"}, }, } @@ -260,16 +254,9 @@ func Test_Show(t *testing.T) { require.NoError(t, err) expected := []any{ - output.LogOutput{ - Format: msgDeletingResourceCount, - Params: []any{1, "test-env"}, - }, - output.LogOutput{ - Format: msgDeletingEnvironment, - Params: []any{"test-env"}, - }, output.LogOutput{ Format: msgEnvironmentDeleted, + Params: []any{"test-env"}, }, } @@ -323,16 +310,9 @@ func Test_Show(t *testing.T) { require.NoError(t, err) expected := []any{ - output.LogOutput{ - Format: msgDeletingResourceCount, - Params: []any{1, "test-env"}, - }, - output.LogOutput{ - Format: msgDeletingEnvironment, - Params: []any{"test-env"}, - }, output.LogOutput{ Format: msgEnvironmentDeleted, + Params: []any{"test-env"}, }, } @@ -376,13 +356,7 @@ func Test_Show(t *testing.T) { err := runner.Run(context.Background()) require.NoError(t, err) - expected := []any{ - output.LogOutput{ - Format: "Environment %q NOT deleted", - Params: []any{"test-env"}, - }, - } - require.Equal(t, expected, outputSink.Writes) + require.Empty(t, outputSink.Writes) }) // YES, this is a success case. Delete means "make it be gone", so if the environment is already @@ -428,10 +402,6 @@ func Test_Show(t *testing.T) { require.NoError(t, err) expected := []any{ - output.LogOutput{ - Format: msgDeletingEnvironment, - Params: []any{"test-env"}, - }, output.LogOutput{ Format: msgEnvironmentNotFound, Params: []any{"test-env"}, diff --git a/pkg/cli/cmd/env/delete/preview/delete.go b/pkg/cli/cmd/env/delete/preview/delete.go index 3d27dbf01c..8733a6fb0a 100644 --- a/pkg/cli/cmd/env/delete/preview/delete.go +++ b/pkg/cli/cmd/env/delete/preview/delete.go @@ -33,10 +33,8 @@ import ( ) const ( - msgEnvironmentDeletedPreview = "Environment deleted" - msgEnvironmentNotFoundPreview = "Environment '%s' does not exist or has already been deleted." - msgDeletingEnvironmentPreview = "Deleting environment %s...\n" - msgDeletingResourceCountPreview = "Deleting %d resource(s) in environment %s...\n" + msgEnvironmentDeletedPreview = "Radius.Core/environments/%s deleted" + msgEnvironmentNotFoundPreview = "Radius.Core/environments/%s not found" ) // NewCommand creates an instance of the command and runner for the `rad env delete --preview` command. @@ -138,14 +136,10 @@ func (r *Runner) Run(ctx context.Context) error { return err } if !confirmed { - r.Output.LogInfo("Environment %q NOT deleted", r.EnvironmentName) return nil } } - // Show progress messages (without resource count for preview, since we don't enumerate here) - r.Output.LogInfo(msgDeletingEnvironmentPreview, r.EnvironmentName) - client := r.RadiusCoreClientFactory.NewEnvironmentsClient() _, err := client.Delete(ctx, r.EnvironmentName, &corerpv20250801.EnvironmentsClientDeleteOptions{}) if err != nil { @@ -154,7 +148,7 @@ func (r *Runner) Run(ctx context.Context) error { return err } - r.Output.LogInfo(msgEnvironmentDeletedPreview) + r.Output.LogInfo(msgEnvironmentDeletedPreview, r.EnvironmentName) return nil } diff --git a/pkg/cli/cmd/env/delete/preview/delete_test.go b/pkg/cli/cmd/env/delete/preview/delete_test.go index 320cb5a9ea..463075273a 100644 --- a/pkg/cli/cmd/env/delete/preview/delete_test.go +++ b/pkg/cli/cmd/env/delete/preview/delete_test.go @@ -98,12 +98,9 @@ func Test_Run(t *testing.T) { name: "Success: environment deleted", serverFactory: test_client_factory.WithEnvironmentServerNoError, expectedLogs: []any{ - output.LogOutput{ - Format: msgDeletingEnvironmentPreview, - Params: []any{"test-env"}, - }, output.LogOutput{ Format: msgEnvironmentDeletedPreview, + Params: []any{"test-env"}, }, }, }, diff --git a/pkg/cli/cmd/env/update/preview/update.go b/pkg/cli/cmd/env/update/preview/update.go index 215a2841a7..4c5c12b64b 100644 --- a/pkg/cli/cmd/env/update/preview/update.go +++ b/pkg/cli/cmd/env/update/preview/update.go @@ -312,40 +312,12 @@ func (r *Runner) Run(ctx context.Context) error { } } - r.Output.LogInfo("Updating Environment...") _, err = envClient.CreateOrUpdate(ctx, r.EnvironmentName, env, &corerpv20250801.EnvironmentsClientCreateOrUpdateOptions{}) if err != nil { return clierrors.MessageWithCause(err, "Failed to update environment %q.", r.EnvironmentName) } - recipePackCount := 0 - if env.Properties.RecipePacks != nil { - recipePackCount = len(env.Properties.RecipePacks) - } - providerCount := 0 - if env.Properties.Providers != nil { - if env.Properties.Providers.Azure != nil { - providerCount++ - } - if env.Properties.Providers.Aws != nil { - providerCount++ - } - if env.Properties.Providers.Kubernetes != nil { - providerCount++ - } - } - obj := environmentForDisplay{ - Name: *env.Name, - RecipePacks: recipePackCount, - Providers: providerCount, - } - - err = r.Output.WriteFormatted("table", obj, environmentFormat()) - if err != nil { - return err - } - - r.Output.LogInfo("Successfully updated environment %q.", r.EnvironmentName) + r.Output.LogInfo("Radius.Core/environments/%s updated", r.EnvironmentName) return nil } diff --git a/pkg/cli/cmd/env/update/preview/update_test.go b/pkg/cli/cmd/env/update/preview/update_test.go index d98f59474e..b171906790 100644 --- a/pkg/cli/cmd/env/update/preview/update_test.go +++ b/pkg/cli/cmd/env/update/preview/update_test.go @@ -108,19 +108,7 @@ func Test_Run(t *testing.T) { serverFactory: test_client_factory.WithEnvironmentServerNoError, expectedOutput: []any{ output.LogOutput{ - Format: "Updating Environment...", - }, - output.FormattedOutput{ - Format: "table", - Obj: environmentForDisplay{ - Name: "test-env", - RecipePacks: 3, - Providers: 3, - }, - Options: environmentFormat(), - }, - output.LogOutput{ - Format: "Successfully updated environment %q.", + Format: "Radius.Core/environments/%s updated", Params: []any{"test-env"}, }, }, diff --git a/pkg/cli/cmd/env/update/update.go b/pkg/cli/cmd/env/update/update.go index 3187bee205..86259c79fb 100644 --- a/pkg/cli/cmd/env/update/update.go +++ b/pkg/cli/cmd/env/update/update.go @@ -228,8 +228,6 @@ func (r *Runner) Run(ctx context.Context) error { env.Properties.Providers.Aws = r.providers.Aws } - r.Output.LogInfo("Updating Environment...") - err = client.CreateOrUpdateEnvironment(ctx, r.EnvName, &corerp.EnvironmentResource{ Location: to.Ptr(v1.LocationGlobal), Properties: env.Properties, @@ -238,36 +236,7 @@ func (r *Runner) Run(ctx context.Context) error { return clierrors.MessageWithCause(err, "Failed to apply cloud provider scope to the environment %q.", r.EnvName) } - recipeCount := 0 - if env.Properties.Recipes != nil { - recipeCount = len(env.Properties.Recipes) - } - providerCount := 0 - if env.Properties.Providers != nil { - if env.Properties.Providers.Azure != nil { - providerCount++ - } - if env.Properties.Providers.Aws != nil { - providerCount++ - } - } - computeKind := "" - if env.Properties.Compute != nil { - computeKind = *env.Properties.Compute.GetEnvironmentCompute().Kind - } - obj := environmentForDisplay{ - Name: *env.Name, - ComputeKind: computeKind, - Recipes: recipeCount, - Providers: providerCount, - } - - err = r.Output.WriteFormatted("table", obj, environmentFormat()) - if err != nil { - return err - } - - r.Output.LogInfo("Successfully updated environment %q.", r.EnvName) + r.Output.LogInfo("Applications.Core/environments/%s updated", r.EnvName) return nil } diff --git a/pkg/cli/cmd/env/update/update_test.go b/pkg/cli/cmd/env/update/update_test.go index 44f7b7fb40..7f6a5a97fe 100644 --- a/pkg/cli/cmd/env/update/update_test.go +++ b/pkg/cli/cmd/env/update/update_test.go @@ -341,24 +341,11 @@ func Test_Update(t *testing.T) { require.NoError(t, err) environment.Properties.Providers = testProviders - obj := environmentForDisplay{ - Name: "test-env", - Recipes: 0, - Providers: 2, - ComputeKind: "kubernetes", - } + _ = environment expected := []any{ output.LogOutput{ - Format: "Updating Environment...", - }, - output.FormattedOutput{ - Format: "table", - Obj: obj, - Options: environmentFormat(), - }, - output.LogOutput{ - Format: "Successfully updated environment %q.", + Format: "Applications.Core/environments/%s updated", Params: []any{"test-env"}, }, } @@ -510,34 +497,9 @@ func Test_Update(t *testing.T) { err := runner.Run(context.Background()) require.NoError(t, err) - numberOfProviders := func() int { - numberOfProviders := 0 - if tc.expectedProviders.Azure != nil { - numberOfProviders++ - } - if tc.expectedProviders.Aws != nil { - numberOfProviders++ - } - return numberOfProviders - } - - obj := environmentForDisplay{ - Name: "test-env", - Recipes: 0, - Providers: numberOfProviders(), - } - expected := []any{ output.LogOutput{ - Format: "Updating Environment...", - }, - output.FormattedOutput{ - Format: "table", - Obj: obj, - Options: environmentFormat(), - }, - output.LogOutput{ - Format: "Successfully updated environment %q.", + Format: "Applications.Core/environments/%s updated", Params: []any{"test-env"}, }, } diff --git a/pkg/cli/cmd/group/create/create.go b/pkg/cli/cmd/group/create/create.go index cdcca08f1d..35f3218a4b 100644 --- a/pkg/cli/cmd/group/create/create.go +++ b/pkg/cli/cmd/group/create/create.go @@ -119,8 +119,6 @@ func (r *Runner) Run(ctx context.Context) error { return err } - r.Output.LogInfo("creating resource group %q in workspace %q...\n", r.UCPResourceGroupName, r.Workspace.Name) - err = client.CreateOrUpdateResourceGroup(ctx, "local", r.UCPResourceGroupName, &v20231001preview.ResourceGroupResource{ Location: to.Ptr(v1.LocationGlobal), }) @@ -128,7 +126,7 @@ func (r *Runner) Run(ctx context.Context) error { return err } - r.Output.LogInfo("resource group %q created", r.UCPResourceGroupName) + r.Output.LogInfo("System.Resources/resourceGroups/%s created", r.UCPResourceGroupName) return nil } diff --git a/pkg/cli/cmd/group/create/create_test.go b/pkg/cli/cmd/group/create/create_test.go index df31fbca74..1a3514162c 100644 --- a/pkg/cli/cmd/group/create/create_test.go +++ b/pkg/cli/cmd/group/create/create_test.go @@ -116,11 +116,7 @@ func Test_Run(t *testing.T) { expected := []any{ output.LogOutput{ - Format: "creating resource group %q in workspace %q...\n", - Params: []any{"testrg", "kind-kind"}, - }, - output.LogOutput{ - Format: "resource group %q created", + Format: "System.Resources/resourceGroups/%s created", Params: []any{"testrg"}, }, } diff --git a/pkg/cli/cmd/group/delete/delete.go b/pkg/cli/cmd/group/delete/delete.go index 005b628822..724b2f0741 100644 --- a/pkg/cli/cmd/group/delete/delete.go +++ b/pkg/cli/cmd/group/delete/delete.go @@ -36,11 +36,8 @@ const ( scopeLocal = "local" // Message templates - msgResourceGroupDeleted = "Resource group %s deleted." - msgResourceGroupNotFound = "Resource group %s does not exist or has already been deleted." - msgResourceGroupNotDeleted = "Resource group %q NOT deleted" - msgDeletingResourceGroup = "Deleting resource group %s...\n" - msgDeletingResourcesWithCount = "Deleting %d resource(s) in group %s..." + msgResourceGroupDeleted = "System.Resources/resourceGroups/%s deleted" + msgResourceGroupNotFound = "System.Resources/resourceGroups/%s not found" ) // NewCommand creates an instance of the command and runner for the `rad group delete` command. @@ -153,17 +150,10 @@ func (r *Runner) Run(ctx context.Context) error { } if !confirmed { - r.Output.LogInfo(msgResourceGroupNotDeleted, r.UCPResourceGroupName) return nil } } - // Show appropriate progress messages with resource count when available - if hasResources { - r.Output.LogInfo(msgDeletingResourcesWithCount, len(resources), r.UCPResourceGroupName) - } - r.Output.LogInfo(msgDeletingResourceGroup, r.UCPResourceGroupName) - // Actually delete the resource group (which will now handle resource deletion internally) deleted, err := client.DeleteResourceGroup(ctx, scopeLocal, r.UCPResourceGroupName) if err != nil { diff --git a/pkg/cli/cmd/group/delete/delete_test.go b/pkg/cli/cmd/group/delete/delete_test.go index 298630166a..891e17963c 100644 --- a/pkg/cli/cmd/group/delete/delete_test.go +++ b/pkg/cli/cmd/group/delete/delete_test.go @@ -97,11 +97,7 @@ func Test_Run(t *testing.T) { skipPrompt: true, expectedOutputs: []any{ output.LogOutput{ - Format: "Deleting resource group %s...\n", - Params: []any{"testrg"}, - }, - output.LogOutput{ - Format: "Resource group %s deleted.", + Format: "System.Resources/resourceGroups/%s deleted", Params: []any{"testrg"}, }, }, @@ -117,15 +113,7 @@ func Test_Run(t *testing.T) { skipPrompt: true, expectedOutputs: []any{ output.LogOutput{ - Format: "Deleting %d resource(s) in group %s...", - Params: []any{2, "testrg"}, - }, - output.LogOutput{ - Format: "Deleting resource group %s...\n", - Params: []any{"testrg"}, - }, - output.LogOutput{ - Format: "Resource group %s deleted.", + Format: "System.Resources/resourceGroups/%s deleted", Params: []any{"testrg"}, }, }, @@ -138,11 +126,7 @@ func Test_Run(t *testing.T) { skipPrompt: true, expectedOutputs: []any{ output.LogOutput{ - Format: "Deleting resource group %s...\n", - Params: []any{"testrg"}, - }, - output.LogOutput{ - Format: "Resource group %s does not exist or has already been deleted.", + Format: "System.Resources/resourceGroups/%s not found", Params: []any{"testrg"}, }, }, @@ -156,28 +140,19 @@ func Test_Run(t *testing.T) { deleteResult: true, expectedOutputs: []any{ output.LogOutput{ - Format: "Deleting resource group %s...\n", - Params: []any{"testrg"}, - }, - output.LogOutput{ - Format: "Resource group %s deleted.", + Format: "System.Resources/resourceGroups/%s deleted", Params: []any{"testrg"}, }, }, }, { - name: "Empty group - user cancels deletion", - confirmation: false, - resources: []generated.GenericResource{}, - promptResponse: prompt.ConfirmNo, - expectedPrompt: "The resource group testrg is empty. Are you sure you want to delete the resource group?", - deleteResult: false, // Won't be called - expectedOutputs: []any{ - output.LogOutput{ - Format: "Resource group %q NOT deleted", - Params: []any{"testrg"}, - }, - }, + name: "Empty group - user cancels deletion", + confirmation: false, + resources: []generated.GenericResource{}, + promptResponse: prompt.ConfirmNo, + expectedPrompt: "The resource group testrg is empty. Are you sure you want to delete the resource group?", + deleteResult: false, // Won't be called + expectedOutputs: nil, }, { name: "Group with resources - user confirms deletion", @@ -191,15 +166,7 @@ func Test_Run(t *testing.T) { deleteResult: true, expectedOutputs: []any{ output.LogOutput{ - Format: "Deleting %d resource(s) in group %s...", - Params: []any{2, "testrg"}, - }, - output.LogOutput{ - Format: "Deleting resource group %s...\n", - Params: []any{"testrg"}, - }, - output.LogOutput{ - Format: "Resource group %s deleted.", + Format: "System.Resources/resourceGroups/%s deleted", Params: []any{"testrg"}, }, }, @@ -210,15 +177,10 @@ func Test_Run(t *testing.T) { resources: []generated.GenericResource{ {Name: new("resource1"), Type: new("Applications.Core/containers")}, }, - promptResponse: prompt.ConfirmNo, - expectedPrompt: "The resource group testrg contains deployed resources. Are you sure you want to delete the resource group and its resources?", - deleteResult: false, // Won't be called - expectedOutputs: []any{ - output.LogOutput{ - Format: "Resource group %q NOT deleted", - Params: []any{"testrg"}, - }, - }, + promptResponse: prompt.ConfirmNo, + expectedPrompt: "The resource group testrg contains deployed resources. Are you sure you want to delete the resource group and its resources?", + deleteResult: false, // Won't be called + expectedOutputs: nil, }, { name: "List resources fails - should not proceed", @@ -238,18 +200,13 @@ func Test_Run(t *testing.T) { expectedOutputs: nil, // No output expected }, { - name: "Delete operation fails", - confirmation: true, - resources: []generated.GenericResource{}, - deleteError: fmt.Errorf("deletion failed"), - skipPrompt: true, - expectedError: fmt.Errorf("deletion failed"), - expectedOutputs: []any{ - output.LogOutput{ - Format: "Deleting resource group %s...\n", - Params: []any{"testrg"}, - }, - }, + name: "Delete operation fails", + confirmation: true, + resources: []generated.GenericResource{}, + deleteError: fmt.Errorf("deletion failed"), + skipPrompt: true, + expectedError: fmt.Errorf("deletion failed"), + expectedOutputs: nil, }, { name: "List returns 404 - group doesn't exist", @@ -260,11 +217,7 @@ func Test_Run(t *testing.T) { deleteResult: false, expectedOutputs: []any{ output.LogOutput{ - Format: "Deleting resource group %s...\n", - Params: []any{"testrg"}, - }, - output.LogOutput{ - Format: "Resource group %s does not exist or has already been deleted.", + Format: "System.Resources/resourceGroups/%s not found", Params: []any{"testrg"}, }, }, @@ -277,11 +230,7 @@ func Test_Run(t *testing.T) { deleteResult: false, expectedOutputs: []any{ output.LogOutput{ - Format: "Deleting resource group %s...\n", - Params: []any{"testrg"}, - }, - output.LogOutput{ - Format: "Resource group %s does not exist or has already been deleted.", + Format: "System.Resources/resourceGroups/%s not found", Params: []any{"testrg"}, }, }, diff --git a/pkg/cli/cmd/recipepack/delete/delete.go b/pkg/cli/cmd/recipepack/delete/delete.go index aba5002833..6f8ac14e2a 100644 --- a/pkg/cli/cmd/recipepack/delete/delete.go +++ b/pkg/cli/cmd/recipepack/delete/delete.go @@ -37,11 +37,9 @@ import ( ) const ( - deleteConfirmationMsg = "Are you sure you want to delete recipe pack '%s'?" - msgDeletingRecipePack = "Deleting recipe pack %s...\n" - msgRecipePackDeleted = "Recipe pack %s deleted." - msgRecipePackNotFound = "Recipe pack %s does not exist or has already been deleted." - msgRecipePackNotDeleted = "Recipe pack %q NOT deleted" + deleteConfirmationMsg = "Are you sure you want to delete recipe pack '%s'?" + msgRecipePackDeleted = "Radius.Core/recipePacks/%s deleted" + msgRecipePackNotFound = "Radius.Core/recipePacks/%s not found" ) // NewCommand creates a new Cobra command for deleting a recipe pack. @@ -138,13 +136,10 @@ func (r *Runner) Run(ctx context.Context) error { } if !confirmed { - r.Output.LogInfo(msgRecipePackNotDeleted, r.RecipePackName) return nil } } - r.Output.LogInfo(msgDeletingRecipePack, r.RecipePackName) - recipePack, err := client.GetRecipePack(ctx, r.RecipePackName) if clients.Is404Error(err) { return clierrors.Message("The recipe pack %q was not found or has been deleted.", r.RecipePackName) diff --git a/pkg/cli/cmd/resource/create/create.go b/pkg/cli/cmd/resource/create/create.go index 004bacf88c..b0d30a12f9 100644 --- a/pkg/cli/cmd/resource/create/create.go +++ b/pkg/cli/cmd/resource/create/create.go @@ -26,7 +26,6 @@ import ( "github.com/radius-project/radius/pkg/cli/clients_new/generated" "github.com/radius-project/radius/pkg/cli/clierrors" "github.com/radius-project/radius/pkg/cli/cmd/commonflags" - "github.com/radius-project/radius/pkg/cli/cmd/resourceprovider/common" "github.com/radius-project/radius/pkg/cli/connections" "github.com/radius-project/radius/pkg/cli/framework" "github.com/radius-project/radius/pkg/cli/output" @@ -139,15 +138,11 @@ func (r *Runner) Run(ctx context.Context) error { return err } - response, err := client.CreateOrUpdateResource(ctx, r.FullyQualifiedResourceTypeName, r.ResourceName, r.Resource) - if err != nil { - return err - } - - err = r.Output.WriteFormatted(r.Format, response, common.GetResourceProviderTableFormat()) + _, err = client.CreateOrUpdateResource(ctx, r.FullyQualifiedResourceTypeName, r.ResourceName, r.Resource) if err != nil { return err } + r.Output.LogInfo("%s/%s created", r.FullyQualifiedResourceTypeName, r.ResourceName) return nil } diff --git a/pkg/cli/cmd/resource/delete/delete.go b/pkg/cli/cmd/resource/delete/delete.go index 8b8ce57336..5eb320a14b 100644 --- a/pkg/cli/cmd/resource/delete/delete.go +++ b/pkg/cli/cmd/resource/delete/delete.go @@ -145,7 +145,7 @@ func (r *Runner) Run(ctx context.Context) error { environmentID, applicationID, err := r.extractEnvironmentAndApplicationIDs(ctx, client) if clients.Is404Error(err) { - r.Output.LogInfo("Resource '%s' of type '%s' does not exist or has already been deleted", r.ResourceName, r.FullyQualifiedResourceTypeName) + r.Output.LogInfo("%s/%s not found", r.FullyQualifiedResourceTypeName, r.ResourceName) return nil } else if err != nil { return err @@ -167,7 +167,6 @@ func (r *Runner) Run(ctx context.Context) error { return err } if !confirmed { - r.Output.LogInfo("resource %q of type %q NOT deleted", r.ResourceName, r.FullyQualifiedResourceTypeName) return nil } } @@ -178,9 +177,9 @@ func (r *Runner) Run(ctx context.Context) error { } if deleted { - r.Output.LogInfo("Resource deleted") + r.Output.LogInfo("%s/%s deleted", r.FullyQualifiedResourceTypeName, r.ResourceName) } else { - r.Output.LogInfo("Resource '%s' of type '%s' does not exist or has already been deleted", r.ResourceName, r.FullyQualifiedResourceTypeName) + r.Output.LogInfo("%s/%s not found", r.FullyQualifiedResourceTypeName, r.ResourceName) } return nil diff --git a/pkg/cli/cmd/resourceprovider/create/create.go b/pkg/cli/cmd/resourceprovider/create/create.go index befc928e8d..f4e93feca8 100644 --- a/pkg/cli/cmd/resourceprovider/create/create.go +++ b/pkg/cli/cmd/resourceprovider/create/create.go @@ -22,7 +22,6 @@ import ( aztoken "github.com/radius-project/radius/pkg/azure/tokencredentials" "github.com/radius-project/radius/pkg/cli" "github.com/radius-project/radius/pkg/cli/cmd/commonflags" - "github.com/radius-project/radius/pkg/cli/cmd/resourceprovider/common" "github.com/radius-project/radius/pkg/cli/framework" "github.com/radius-project/radius/pkg/cli/manifest" "github.com/radius-project/radius/pkg/cli/output" @@ -126,23 +125,13 @@ func (r *Runner) Run(ctx context.Context) error { } } - // Proceed with registering manifests - if err := manifest.RegisterFile(ctx, r.UCPClientFactory, "local", r.ResourceProviderManifestFilePath, r.Logger); err != nil { - return err - } - - response, err := r.UCPClientFactory.NewResourceProvidersClient().Get(ctx, "local", r.ResourceProvider.Namespace, nil) - if err != nil { - return err - } - - r.Output.LogInfo("") - - err = r.Output.WriteFormatted(r.Format, response, common.GetResourceProviderTableFormat()) - if err != nil { + // Proceed with registering manifests. Use a nil logger to suppress verbose + // progress messages; the concise success line is emitted below. + if err := manifest.RegisterFile(ctx, r.UCPClientFactory, "local", r.ResourceProviderManifestFilePath, nil); err != nil { return err } + r.Output.LogInfo("System.Resources/resourceProviders/%s created", r.ResourceProvider.Namespace) return nil } diff --git a/pkg/cli/cmd/resourceprovider/create/create_test.go b/pkg/cli/cmd/resourceprovider/create/create_test.go index 35db8b574f..b8fb2ee367 100644 --- a/pkg/cli/cmd/resourceprovider/create/create_test.go +++ b/pkg/cli/cmd/resourceprovider/create/create_test.go @@ -17,9 +17,7 @@ limitations under the License. package create import ( - "bytes" "context" - "fmt" "testing" "github.com/radius-project/radius/pkg/cli/framework" @@ -73,32 +71,28 @@ func Test_Run(t *testing.T) { resourceProviderData, err := manifest.ReadFile("testdata/valid.yaml") require.NoError(t, err) - expectedResourceType := "testResources" - expectedAPIVersion := "2025-01-01-preview" - clientFactory, err := manifest.NewTestClientFactory(manifest.WithResourceProviderServerNoError) require.NoError(t, err) - var logBuffer bytes.Buffer - logger := func(format string, args ...any) { - fmt.Fprintf(&logBuffer, format+"\n", args...) - } + outputSink := &output.MockOutput{} runner := &Runner{ UCPClientFactory: clientFactory, - Output: &output.MockOutput{}, + Output: outputSink, Workspace: &workspaces.Workspace{}, ResourceProvider: resourceProviderData, Format: "table", - Logger: logger, ResourceProviderManifestFilePath: "testdata/valid.yaml", } err = runner.Run(context.Background()) require.NoError(t, err) - logOutput := logBuffer.String() - require.Contains(t, logOutput, fmt.Sprintf("Creating resource type %s/%s", resourceProviderData.Namespace, expectedResourceType)) - require.Contains(t, logOutput, fmt.Sprintf("Creating API Version %s/%s@%s", resourceProviderData.Namespace, expectedResourceType, expectedAPIVersion)) + require.Equal(t, []any{ + output.LogOutput{ + Format: "System.Resources/resourceProviders/%s created", + Params: []any{resourceProviderData.Namespace}, + }, + }, outputSink.Writes) }) } diff --git a/pkg/cli/cmd/resourceprovider/delete/delete.go b/pkg/cli/cmd/resourceprovider/delete/delete.go index 248f5b7e65..1aefb01fcc 100644 --- a/pkg/cli/cmd/resourceprovider/delete/delete.go +++ b/pkg/cli/cmd/resourceprovider/delete/delete.go @@ -140,9 +140,9 @@ func (r *Runner) Run(ctx context.Context) error { } if deleted { - r.Output.LogInfo("Resource provider %q deleted.", r.ResourceProviderNamespace) + r.Output.LogInfo("System.Resources/resourceProviders/%s deleted", r.ResourceProviderNamespace) } else { - r.Output.LogInfo("Resource provider %q does not exist or has already been deleted.", r.ResourceProviderNamespace) + r.Output.LogInfo("System.Resources/resourceProviders/%s not found", r.ResourceProviderNamespace) } return nil diff --git a/pkg/cli/cmd/resourceprovider/delete/delete_test.go b/pkg/cli/cmd/resourceprovider/delete/delete_test.go index d427343db9..cec586691d 100644 --- a/pkg/cli/cmd/resourceprovider/delete/delete_test.go +++ b/pkg/cli/cmd/resourceprovider/delete/delete_test.go @@ -95,7 +95,7 @@ func Test_Run(t *testing.T) { expected := []any{ output.LogOutput{ - Format: "Resource provider %q deleted.", + Format: "System.Resources/resourceProviders/%s deleted", Params: []any{"Applications.Test"}, }, } @@ -136,7 +136,7 @@ func Test_Run(t *testing.T) { expected := []any{ output.LogOutput{ - Format: "Resource provider %q does not exist or has already been deleted.", + Format: "System.Resources/resourceProviders/%s not found", Params: []any{"Applications.Test"}, }, } @@ -183,7 +183,7 @@ func Test_Run(t *testing.T) { expected := []any{ output.LogOutput{ - Format: "Resource provider %q deleted.", + Format: "System.Resources/resourceProviders/%s deleted", Params: []any{"Applications.Test"}, }, } diff --git a/pkg/cli/cmd/resourcetype/create/create.go b/pkg/cli/cmd/resourcetype/create/create.go index da631f0052..b8638041c2 100644 --- a/pkg/cli/cmd/resourcetype/create/create.go +++ b/pkg/cli/cmd/resourcetype/create/create.go @@ -149,7 +149,6 @@ func (r *Runner) Run(ctx context.Context) error { } if r.ResourceTypeName == "" { - r.Output.LogInfo(msgNoResourceTypeNameProvided) return r.registerTypes(ctx, nil) // Register all types } @@ -158,8 +157,9 @@ func (r *Runner) Run(ctx context.Context) error { // registerTypes registers the specified resource types (or all types if typeNames is nil) func (r *Runner) registerTypes(ctx context.Context, typeNames []string) error { - // Always ensure the resource provider exists first - err := manifest.EnsureResourceProviderExists(ctx, r.UCPClientFactory, defaultPlaneName, *r.ResourceProvider, r.Logger) + // Always ensure the resource provider exists first. Use a nil logger to suppress + // verbose progress messages; the concise success line is emitted below. + err := manifest.EnsureResourceProviderExists(ctx, r.UCPClientFactory, defaultPlaneName, *r.ResourceProvider, nil) if err != nil { return err } @@ -176,19 +176,13 @@ func (r *Runner) registerTypes(ctx context.Context, typeNames []string) error { } } - // Register each type individually using the unified approach + // Register each type individually and emit a single concise line per type. for _, typeName := range typesToRegister { - err = manifest.RegisterType(ctx, r.UCPClientFactory, defaultPlaneName, r.ResourceProviderManifestFilePath, typeName, r.Logger) + err = manifest.RegisterType(ctx, r.UCPClientFactory, defaultPlaneName, r.ResourceProviderManifestFilePath, typeName, nil) if err != nil { return err } - } - - // Provide appropriate success message - if len(typesToRegister) == 1 { - // Single type - success message already logged by RegisterType - } else { - r.Output.LogInfo(msgAllResourceTypesCreated) + r.Output.LogInfo("%s/%s created", r.ResourceProvider.Namespace, typeName) } return nil diff --git a/pkg/cli/cmd/resourcetype/create/create_test.go b/pkg/cli/cmd/resourcetype/create/create_test.go index c56fb66547..f4aafb5495 100644 --- a/pkg/cli/cmd/resourcetype/create/create_test.go +++ b/pkg/cli/cmd/resourcetype/create/create_test.go @@ -17,9 +17,7 @@ limitations under the License. package create import ( - "bytes" "context" - "fmt" "testing" "github.com/radius-project/radius/pkg/cli/framework" @@ -73,11 +71,6 @@ func Test_Run(t *testing.T) { clientFactory, err := manifest.NewTestClientFactory(manifest.WithResourceProviderServerNoError) require.NoError(t, err) - var logBuffer bytes.Buffer - logger := func(format string, args ...any) { - fmt.Fprintf(&logBuffer, format+"\n", args...) - } - outputSink := &output.MockOutput{} runner := &Runner{ UCPClientFactory: clientFactory, @@ -85,7 +78,6 @@ func Test_Run(t *testing.T) { Workspace: &workspaces.Workspace{}, ResourceProvider: resourceProviderData, Format: "table", - Logger: logger, ResourceProviderManifestFilePath: "testdata/valid.yaml", ResourceTypeName: "testResources", } @@ -93,9 +85,10 @@ func Test_Run(t *testing.T) { err = runner.Run(context.Background()) require.NoError(t, err) - // Verify RegisterType was called (should see specific log messages) - logOutput := logBuffer.String() - require.Contains(t, logOutput, fmt.Sprintf("Creating resource type %s/%s", runner.ResourceProvider.Namespace, "testResources")) + require.Contains(t, outputSink.Writes, output.LogOutput{ + Format: "%s/%s created", + Params: []any{runner.ResourceProvider.Namespace, "testResources"}, + }) }) t.Run("No resource type name provided - registers entire manifest", func(t *testing.T) { @@ -108,11 +101,6 @@ func Test_Run(t *testing.T) { clientFactory, err := manifest.NewTestClientFactory(manifest.WithResourceProviderServerNoError) require.NoError(t, err) - var logBuffer bytes.Buffer - logger := func(format string, args ...any) { - fmt.Fprintf(&logBuffer, format+"\n", args...) - } - outputSink := &output.MockOutput{} runner := &Runner{ UCPClientFactory: clientFactory, @@ -120,7 +108,6 @@ func Test_Run(t *testing.T) { Workspace: &workspaces.Workspace{}, ResourceProvider: resourceProviderData, Format: "table", - Logger: logger, ResourceProviderManifestFilePath: "testdata/valid.yaml", ResourceTypeName: "", // Empty resource type name } @@ -128,17 +115,15 @@ func Test_Run(t *testing.T) { err = runner.Run(context.Background()) require.NoError(t, err) - // Verify the correct log message is output - expectedLog := output.LogOutput{ - Format: "No resource type name provided. Creating all resource types in the manifest.", - Params: nil, - } - require.Contains(t, outputSink.Writes, expectedLog, "Expected log message for no resource type name provided") - - // Verify RegisterResourceProvider was called - logOutput := logBuffer.String() - require.Contains(t, logOutput, fmt.Sprintf("Creating resource type %s/%s", runner.ResourceProvider.Namespace, "testResources")) - require.Contains(t, logOutput, fmt.Sprintf("Creating resource type %s/%s", runner.ResourceProvider.Namespace, "prodResources")) + // Verify the concise success log lines for both resource types are emitted + require.Contains(t, outputSink.Writes, output.LogOutput{ + Format: "%s/%s created", + Params: []any{runner.ResourceProvider.Namespace, "testResources"}, + }) + require.Contains(t, outputSink.Writes, output.LogOutput{ + Format: "%s/%s created", + Params: []any{runner.ResourceProvider.Namespace, "prodResources"}, + }) }) t.Run("Resource provider does not exist - registers resource provider with single type", func(t *testing.T) { @@ -153,11 +138,6 @@ func Test_Run(t *testing.T) { clientFactory, err := manifest.NewTestClientFactory(manifest.WithResourceProviderServerNotFoundError) require.NoError(t, err) - var logBuffer bytes.Buffer - logger := func(format string, args ...any) { - fmt.Fprintf(&logBuffer, format+"\n", args...) - } - outputSink := &output.MockOutput{} runner := &Runner{ UCPClientFactory: clientFactory, @@ -165,17 +145,21 @@ func Test_Run(t *testing.T) { Workspace: &workspaces.Workspace{}, ResourceProvider: resourceProviderData, Format: "table", - Logger: logger, ResourceProviderManifestFilePath: "testdata/valid.yaml", ResourceTypeName: expectedResourceType, } _ = runner.Run(context.Background()) - // Verify RegisterResourceProvider was called with only the specified resource type - logOutput := logBuffer.String() - require.Contains(t, logOutput, fmt.Sprintf("Creating resource type %s/%s", runner.ResourceProvider.Namespace, "testResources")) - require.NotContains(t, logOutput, fmt.Sprintf("Creating resource type %s/%s", runner.ResourceProvider.Namespace, "prodResources")) + // Verify only the specified resource type produced a success line. + require.Contains(t, outputSink.Writes, output.LogOutput{ + Format: "%s/%s created", + Params: []any{runner.ResourceProvider.Namespace, "testResources"}, + }) + require.NotContains(t, outputSink.Writes, output.LogOutput{ + Format: "%s/%s created", + Params: []any{runner.ResourceProvider.Namespace, "prodResources"}, + }) }) t.Run("Get Resource provider Internal Error", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -189,18 +173,12 @@ func Test_Run(t *testing.T) { clientFactory, err := manifest.NewTestClientFactory(manifest.WithResourceProviderServerInternalError) require.NoError(t, err) - var logBuffer bytes.Buffer - logger := func(format string, args ...any) { - fmt.Fprintf(&logBuffer, format+"\n", args...) - } - runner := &Runner{ UCPClientFactory: clientFactory, Output: &output.MockOutput{}, Workspace: &workspaces.Workspace{}, ResourceProvider: resourceProviderData, Format: "table", - Logger: logger, ResourceProviderManifestFilePath: "testdata/valid.yaml", ResourceTypeName: expectedResourceType, } diff --git a/pkg/cli/cmd/resourcetype/delete/delete.go b/pkg/cli/cmd/resourcetype/delete/delete.go index 0c3533029a..e7fd7c5d2d 100644 --- a/pkg/cli/cmd/resourcetype/delete/delete.go +++ b/pkg/cli/cmd/resourcetype/delete/delete.go @@ -145,9 +145,9 @@ func (r *Runner) Run(ctx context.Context) error { } if deleted { - r.Output.LogInfo("Resource type %q deleted.", r.ResourceTypeName) + r.Output.LogInfo("%s deleted", r.ResourceTypeName) } else { - r.Output.LogInfo("Resource type %q does not exist or has already been deleted.", r.ResourceTypeName) + r.Output.LogInfo("%s not found", r.ResourceTypeName) } return nil diff --git a/pkg/cli/cmd/resourcetype/delete/delete_test.go b/pkg/cli/cmd/resourcetype/delete/delete_test.go index 331d2b560d..686fd3bb4a 100644 --- a/pkg/cli/cmd/resourcetype/delete/delete_test.go +++ b/pkg/cli/cmd/resourcetype/delete/delete_test.go @@ -103,7 +103,7 @@ func Test_Run(t *testing.T) { expected := []any{ output.LogOutput{ - Format: "Resource type %q deleted.", + Format: "%s deleted", Params: []any{"Applications.Test/testResources"}, }, } @@ -146,7 +146,7 @@ func Test_Run(t *testing.T) { expected := []any{ output.LogOutput{ - Format: "Resource type %q does not exist or has already been deleted.", + Format: "%s not found", Params: []any{"Applications.Test/testResources"}, }, } @@ -195,7 +195,7 @@ func Test_Run(t *testing.T) { expected := []any{ output.LogOutput{ - Format: "Resource type %q deleted.", + Format: "%s deleted", Params: []any{"Applications.Test/testResources"}, }, } diff --git a/pkg/cli/cmd/workspace/create/create.go b/pkg/cli/cmd/workspace/create/create.go index 64e77f154b..cbfd3186f5 100644 --- a/pkg/cli/cmd/workspace/create/create.go +++ b/pkg/cli/cmd/workspace/create/create.go @@ -208,12 +208,12 @@ func (r *Runner) Validate(cmd *cobra.Command, args []string) error { // Run creates a workspace and sets it as the current workspace, returning an error if any occurs during the process." func (r *Runner) Run(ctx context.Context) error { - r.Output.LogInfo("Creating workspace...") err := r.ConfigFileInterface.EditWorkspaces(ctx, r.ConfigHolder.Config, r.Workspace) if err != nil { return err } - output.LogInfo("Set %q as current workspace", r.Workspace.Name) + r.Output.LogInfo("workspace/%s created", r.Workspace.Name) + r.Output.LogInfo("workspace/%s set as current", r.Workspace.Name) return nil } diff --git a/pkg/cli/cmd/workspace/delete/delete.go b/pkg/cli/cmd/workspace/delete/delete.go index 29c83b9eb3..f0c8ec7665 100644 --- a/pkg/cli/cmd/workspace/delete/delete.go +++ b/pkg/cli/cmd/workspace/delete/delete.go @@ -131,5 +131,6 @@ func (r *Runner) Run(ctx context.Context) error { return err } + r.Output.LogInfo("workspace/%s deleted", r.Workspace.Name) return nil } diff --git a/pkg/cli/cmd/workspace/delete/delete_test.go b/pkg/cli/cmd/workspace/delete/delete_test.go index 37b9051774..ed2429cfa7 100644 --- a/pkg/cli/cmd/workspace/delete/delete_test.go +++ b/pkg/cli/cmd/workspace/delete/delete_test.go @@ -115,7 +115,12 @@ func Test_Run(t *testing.T) { err := runner.Run(context.Background()) require.NoError(t, err) - require.Empty(t, outputSink.Writes) + require.Equal(t, []any{ + output.LogOutput{ + Format: "workspace/%s deleted", + Params: []any{"test-workspace"}, + }, + }, outputSink.Writes) }) t.Run("Delete workspace bypass confirmation", func(t *testing.T) { outputSink := &output.MockOutput{} @@ -147,7 +152,12 @@ func Test_Run(t *testing.T) { err := runner.Run(context.Background()) require.NoError(t, err) - require.Empty(t, outputSink.Writes) + require.Equal(t, []any{ + output.LogOutput{ + Format: "workspace/%s deleted", + Params: []any{"test-workspace"}, + }, + }, outputSink.Writes) }) t.Run("Delete workspace not confirmed", func(t *testing.T) { outputSink := &output.MockOutput{} From 360f24807f14886b9da5eeb6bb5c5b241ef652e7 Mon Sep 17 00:00:00 2001 From: Zach Casper Date: Tue, 28 Apr 2026 11:17:39 -0500 Subject: [PATCH 2/6] Deleted table formatter which is no longer used Signed-off-by: Zach Casper --- .../cmd/env/update/preview/objectformats.go | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 pkg/cli/cmd/env/update/preview/objectformats.go diff --git a/pkg/cli/cmd/env/update/preview/objectformats.go b/pkg/cli/cmd/env/update/preview/objectformats.go deleted file mode 100644 index 4b250d7c69..0000000000 --- a/pkg/cli/cmd/env/update/preview/objectformats.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2023 The Radius Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package preview - -import "github.com/radius-project/radius/pkg/cli/output" - -type environmentForDisplay struct { - Name string - RecipePacks int - Providers int -} - -// environmentFormat returns a FormatterOptions object containing the column headings and JSONPaths for the -// environment table. -func environmentFormat() output.FormatterOptions { - return output.FormatterOptions{ - Columns: []output.Column{ - { - Heading: "NAME", - JSONPath: "{ .Name }", - }, - { - Heading: "RECIPE PACKS", - JSONPath: "{ .RecipePacks }", - }, - { - Heading: "PROVIDERS", - JSONPath: "{ .Providers }", - }, - }, - } -} From 76966000e107420ebfe9bae37ada35c10d3da701 Mon Sep 17 00:00:00 2001 From: Zach Casper Date: Tue, 28 Apr 2026 11:54:34 -0500 Subject: [PATCH 3/6] Update tests based on codecov report Signed-off-by: Zach Casper --- pkg/cli/cmd/app/delete/delete_test.go | 62 ++ pkg/cli/cmd/resource/delete/delete_test.go | 728 +++++++++--------- .../resourceprovider/create/create_test.go | 22 + 3 files changed, 449 insertions(+), 363 deletions(-) diff --git a/pkg/cli/cmd/app/delete/delete_test.go b/pkg/cli/cmd/app/delete/delete_test.go index e89457d54e..28db688d11 100644 --- a/pkg/cli/cmd/app/delete/delete_test.go +++ b/pkg/cli/cmd/app/delete/delete_test.go @@ -529,4 +529,66 @@ func Test_Delete(t *testing.T) { require.Equal(t, expected, outputSink.Writes) }) + + t.Run("Success: Delete Returns False (already gone)", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) + deleteMock := delete.NewMockInterface(ctrl) + + appManagementClient.EXPECT(). + GetApplication(gomock.Any(), "test-app"). + Return(v20231001preview.ApplicationResource{ + Properties: &v20231001preview.ApplicationProperties{ + Environment: new("/planes/radius/local/resourceGroups/default/providers/Applications.Core/environments/default"), + }, + }, nil). + Times(1) + + progressText := fmt.Sprintf("Deleting application '%s' from environment '%s'...", "test-app", "default") + deleteMock.EXPECT(). + DeleteApplicationWithProgress( + gomock.Any(), + appManagementClient, + clients.DeleteOptions{ + ApplicationNameOrID: "test-app", + ProgressText: progressText, + }, + ). + Return(false, nil). + Times(1) + + workspace := &workspaces.Workspace{ + Connection: map[string]any{ + "kind": "kubernetes", + "context": "kind-kind", + }, + Name: "kind-kind", + Scope: "/planes/radius/local/resourceGroups/test-group", + Environment: "/planes/radius/local/resourceGroups/default/providers/Applications.Core/environments/default", + } + outputSink := &output.MockOutput{} + runner := &Runner{ + Delete: deleteMock, + ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, + Workspace: workspace, + Output: outputSink, + ApplicationName: "test-app", + EnvironmentName: "default", + Confirm: true, + } + + err := runner.Run(context.Background()) + require.NoError(t, err) + + expected := []any{ + output.LogOutput{ + Format: "Applications.Core/applications/%s not found", + Params: []any{"test-app"}, + }, + } + + require.Equal(t, expected, outputSink.Writes) + }) } diff --git a/pkg/cli/cmd/resource/delete/delete_test.go b/pkg/cli/cmd/resource/delete/delete_test.go index f2cfe7654d..2bd95e3a5a 100644 --- a/pkg/cli/cmd/resource/delete/delete_test.go +++ b/pkg/cli/cmd/resource/delete/delete_test.go @@ -18,6 +18,7 @@ package delete import ( "context" + "fmt" "net/http" "net/url" "testing" @@ -28,7 +29,10 @@ import ( "github.com/radius-project/radius/pkg/cli/connections" "github.com/radius-project/radius/pkg/cli/framework" "github.com/radius-project/radius/pkg/cli/output" + "github.com/radius-project/radius/pkg/cli/prompt" "github.com/radius-project/radius/pkg/cli/workspaces" + v20231001preview "github.com/radius-project/radius/pkg/corerp/api/v20231001preview" + "github.com/radius-project/radius/pkg/to" "github.com/radius-project/radius/test/radcli" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -132,376 +136,374 @@ func Test_Run(t *testing.T) { require.Error(t, err) require.Equal(t, responseError, err) }) - /* - - t.Run("Success (non-existent)", func(t *testing.T) { - ctrl := gomock.NewController(t) - - appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) - appManagementClient.EXPECT(). - GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(generated.GenericResource{ - Properties: map[string]interface{}{ - "environment": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/environments/my-test-env", - "application": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/applications/my-test-app", - }, - }, nil). - Times(1) - - appManagementClient.EXPECT(). - DeleteResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(false, nil). - Times(1) - - outputSink := &output.MockOutput{} - - runner := &Runner{ - ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, - Output: outputSink, - Workspace: &workspaces.Workspace{}, - FullyQualifiedResourceTypeName: "Applications.Core/containers", - ResourceName: "test-container", - Format: "table", - Confirm: true, - } - - err := runner.Run(context.Background()) - require.NoError(t, err) - - expected := []any{ - output.LogOutput{ - Format: "Resource '%s' of type '%s' does not exist or has already been deleted", - Params: []any{"test-container", "Applications.Core/containers"}, - }, - } - require.Equal(t, expected, outputSink.Writes) - }) - - t.Run("Success (deleted)", func(t *testing.T) { - ctrl := gomock.NewController(t) - - appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) - appManagementClient.EXPECT(). - GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(generated.GenericResource{ - Properties: map[string]interface{}{ - "environment": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/environments/my-test-env", - "application": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/applications/my-test-app", - }, - }, nil). - Times(1) - appManagementClient.EXPECT(). - DeleteResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(true, nil). - Times(1) - - outputSink := &output.MockOutput{} - - runner := &Runner{ - ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, - Output: outputSink, - Workspace: &workspaces.Workspace{}, - FullyQualifiedResourceTypeName: "Applications.Core/containers", - ResourceName: "test-container", - Format: "table", - Confirm: true, - } - - err := runner.Run(context.Background()) - require.NoError(t, err) - - expected := []any{ - output.LogOutput{ - Format: "Resource deleted", - }, - } - require.Equal(t, expected, outputSink.Writes) - }) - - t.Run("Success: Prompt Confirmed (case 1: application-scoped standard resource)", func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - promptMock := prompt.NewMockInterface(ctrl) - promptMock.EXPECT(). - GetListInput([]string{prompt.ConfirmNo, prompt.ConfirmYes}, fmt.Sprintf(deleteConfirmationWithApplication, "test-container", "Applications.Core/containers", "my-test-app", "my-test-env")). - Return(prompt.ConfirmYes, nil). - Times(1) - - appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) - appManagementClient.EXPECT(). - GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(generated.GenericResource{ - Properties: map[string]interface{}{ - "environment": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/environments/my-test-env", - "application": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/applications/my-test-app", - }, - }, nil). - Times(1) - appManagementClient.EXPECT(). - DeleteResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(true, nil). - Times(1) - - workspace := &workspaces.Workspace{ - Connection: map[string]any{ - "kind": "kubernetes", - "context": "kind-kind", - }, - Name: "kind-kind", - Scope: "/planes/radius/local/resourceGroups/test-group", - } - outputSink := &output.MockOutput{} - runner := &Runner{ - ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, - Output: outputSink, - Workspace: workspace, - FullyQualifiedResourceTypeName: "Applications.Core/containers", - ResourceName: "test-container", - Format: "table", - InputPrompter: promptMock, - } - - err := runner.Run(context.Background()) - require.NoError(t, err) - - expected := []any{ - output.LogOutput{ - Format: "Resource deleted", - }, - } - - require.Equal(t, expected, outputSink.Writes) - }) - - t.Run("Success: Prompt Confirmed (case 2: environment-scoped standard resource)", func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - promptMock := prompt.NewMockInterface(ctrl) - promptMock.EXPECT(). - GetListInput([]string{prompt.ConfirmNo, prompt.ConfirmYes}, fmt.Sprintf(deleteConfirmationWithoutApplication, "test-container", "Applications.Core/containers", "my-test-env")). - Return(prompt.ConfirmYes, nil). - Times(1) - - appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) - appManagementClient.EXPECT(). - GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(generated.GenericResource{ - Properties: map[string]interface{}{ - "environment": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/environments/my-test-env", - }, - }, nil). - Times(1) - appManagementClient.EXPECT(). - DeleteResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(true, nil). - Times(1) - - workspace := &workspaces.Workspace{ - Connection: map[string]any{ - "kind": "kubernetes", - "context": "kind-kind", - }, - Name: "kind-kind", - Scope: "/planes/radius/local/resourceGroups/test-group", - } - - outputSink := &output.MockOutput{} - runner := &Runner{ - ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, - Output: outputSink, - Workspace: workspace, - FullyQualifiedResourceTypeName: "Applications.Core/containers", - ResourceName: "test-container", - Format: "table", - InputPrompter: promptMock, - } - - err := runner.Run(context.Background()) - require.NoError(t, err) - - expected := []any{ - output.LogOutput{ - Format: "Resource deleted", + + t.Run("Success (non-existent)", func(t *testing.T) { + ctrl := gomock.NewController(t) + + appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) + appManagementClient.EXPECT(). + GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(generated.GenericResource{ + Properties: map[string]interface{}{ + "environment": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/environments/my-test-env", + "application": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/applications/my-test-app", }, - } - - require.Equal(t, expected, outputSink.Writes) - }) - - // NOTE: this case requires an extra lookup to get the environment name. - t.Run("Success: Prompt Confirmed (case 3: application-scoped core resource)", func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - promptMock := prompt.NewMockInterface(ctrl) - promptMock.EXPECT(). - GetListInput([]string{prompt.ConfirmNo, prompt.ConfirmYes}, fmt.Sprintf(deleteConfirmationWithApplication, "test-container", "Applications.Core/containers", "my-test-app", "my-test-env")). - Return(prompt.ConfirmYes, nil). - Times(1) - - appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) - appManagementClient.EXPECT(). - GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(generated.GenericResource{ - Properties: map[string]interface{}{ - "application": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/applications/my-test-app", - }, - }, nil). - Times(1) - - appManagementClient.EXPECT(). - GetApplication(gomock.Any(), "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/applications/my-test-app"). - Return(v20231001preview.ApplicationResource{ - Properties: &v20231001preview.ApplicationProperties{ - Environment: to.Ptr("/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/environments/my-test-env"), - }, - }, nil). - Times(1) - appManagementClient.EXPECT(). - DeleteResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(true, nil). - Times(1) - - workspace := &workspaces.Workspace{ - Connection: map[string]any{ - "kind": "kubernetes", - "context": "kind-kind", + }, nil). + Times(1) + + appManagementClient.EXPECT(). + DeleteResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(false, nil). + Times(1) + + outputSink := &output.MockOutput{} + + runner := &Runner{ + ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, + Output: outputSink, + Workspace: &workspaces.Workspace{}, + FullyQualifiedResourceTypeName: "Applications.Core/containers", + ResourceName: "test-container", + Format: "table", + Confirm: true, + } + + err := runner.Run(context.Background()) + require.NoError(t, err) + + expected := []any{ + output.LogOutput{ + Format: "%s/%s not found", + Params: []any{"Applications.Core/containers", "test-container"}, + }, + } + require.Equal(t, expected, outputSink.Writes) + }) + + t.Run("Success (deleted)", func(t *testing.T) { + ctrl := gomock.NewController(t) + + appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) + appManagementClient.EXPECT(). + GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(generated.GenericResource{ + Properties: map[string]interface{}{ + "environment": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/environments/my-test-env", + "application": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/applications/my-test-app", }, - Name: "kind-kind", - Scope: "/planes/radius/local/resourceGroups/test-group", - } - - outputSink := &output.MockOutput{} - runner := &Runner{ - ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, - Output: outputSink, - Workspace: workspace, - FullyQualifiedResourceTypeName: "Applications.Core/containers", - ResourceName: "test-container", - Format: "table", - InputPrompter: promptMock, - } - - err := runner.Run(context.Background()) - require.NoError(t, err) - - expected := []any{ - output.LogOutput{ - Format: "Resource deleted", + }, nil). + Times(1) + appManagementClient.EXPECT(). + DeleteResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(true, nil). + Times(1) + + outputSink := &output.MockOutput{} + + runner := &Runner{ + ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, + Output: outputSink, + Workspace: &workspaces.Workspace{}, + FullyQualifiedResourceTypeName: "Applications.Core/containers", + ResourceName: "test-container", + Format: "table", + Confirm: true, + } + + err := runner.Run(context.Background()) + require.NoError(t, err) + + expected := []any{ + output.LogOutput{ + Format: "%s/%s deleted", + Params: []any{"Applications.Core/containers", "test-container"}, + }, + } + require.Equal(t, expected, outputSink.Writes) + }) + + t.Run("Success: Prompt Confirmed (case 1: application-scoped standard resource)", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + promptMock := prompt.NewMockInterface(ctrl) + promptMock.EXPECT(). + GetListInput([]string{prompt.ConfirmNo, prompt.ConfirmYes}, fmt.Sprintf(deleteConfirmationWithApplication, "test-container", "Applications.Core/containers", "my-test-app", "my-test-env")). + Return(prompt.ConfirmYes, nil). + Times(1) + + appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) + appManagementClient.EXPECT(). + GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(generated.GenericResource{ + Properties: map[string]interface{}{ + "environment": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/environments/my-test-env", + "application": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/applications/my-test-app", }, - } - - require.Equal(t, expected, outputSink.Writes) - }) - - t.Run("Success: Prompt Confirmed (case 4: no application or environment)", func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - promptMock := prompt.NewMockInterface(ctrl) - promptMock.EXPECT(). - GetListInput([]string{prompt.ConfirmNo, prompt.ConfirmYes}, fmt.Sprintf(deleteConfirmationWithoutApplicationOrEnvironment, "test-container", "Applications.Core/containers")). - Return(prompt.ConfirmYes, nil). - Times(1) - - appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) - appManagementClient.EXPECT(). - GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(generated.GenericResource{ - Properties: map[string]interface{}{}, - }, nil). - Times(1) - - appManagementClient.EXPECT(). - DeleteResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(true, nil). - Times(1) - - workspace := &workspaces.Workspace{ - Connection: map[string]any{ - "kind": "kubernetes", - "context": "kind-kind", + }, nil). + Times(1) + appManagementClient.EXPECT(). + DeleteResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(true, nil). + Times(1) + + workspace := &workspaces.Workspace{ + Connection: map[string]any{ + "kind": "kubernetes", + "context": "kind-kind", + }, + Name: "kind-kind", + Scope: "/planes/radius/local/resourceGroups/test-group", + } + outputSink := &output.MockOutput{} + runner := &Runner{ + ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, + Output: outputSink, + Workspace: workspace, + FullyQualifiedResourceTypeName: "Applications.Core/containers", + ResourceName: "test-container", + Format: "table", + InputPrompter: promptMock, + } + + err := runner.Run(context.Background()) + require.NoError(t, err) + + expected := []any{ + output.LogOutput{ + Format: "%s/%s deleted", + Params: []any{"Applications.Core/containers", "test-container"}, + }, + } + + require.Equal(t, expected, outputSink.Writes) + }) + + t.Run("Success: Prompt Confirmed (case 2: environment-scoped standard resource)", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + promptMock := prompt.NewMockInterface(ctrl) + promptMock.EXPECT(). + GetListInput([]string{prompt.ConfirmNo, prompt.ConfirmYes}, fmt.Sprintf(deleteConfirmationWithoutApplication, "test-container", "Applications.Core/containers", "my-test-env")). + Return(prompt.ConfirmYes, nil). + Times(1) + + appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) + appManagementClient.EXPECT(). + GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(generated.GenericResource{ + Properties: map[string]interface{}{ + "environment": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/environments/my-test-env", }, - Name: "kind-kind", - Scope: "/planes/radius/local/resourceGroups/test-group", - } - outputSink := &output.MockOutput{} - runner := &Runner{ - ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, - Output: outputSink, - Workspace: workspace, - FullyQualifiedResourceTypeName: "Applications.Core/containers", - ResourceName: "test-container", - Format: "table", - InputPrompter: promptMock, - } - - err := runner.Run(context.Background()) - require.NoError(t, err) - - expected := []any{ - output.LogOutput{ - Format: "Resource deleted", + }, nil). + Times(1) + appManagementClient.EXPECT(). + DeleteResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(true, nil). + Times(1) + + workspace := &workspaces.Workspace{ + Connection: map[string]any{ + "kind": "kubernetes", + "context": "kind-kind", + }, + Name: "kind-kind", + Scope: "/planes/radius/local/resourceGroups/test-group", + } + + outputSink := &output.MockOutput{} + runner := &Runner{ + ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, + Output: outputSink, + Workspace: workspace, + FullyQualifiedResourceTypeName: "Applications.Core/containers", + ResourceName: "test-container", + Format: "table", + InputPrompter: promptMock, + } + + err := runner.Run(context.Background()) + require.NoError(t, err) + + expected := []any{ + output.LogOutput{ + Format: "%s/%s deleted", + Params: []any{"Applications.Core/containers", "test-container"}, + }, + } + + require.Equal(t, expected, outputSink.Writes) + }) + + // NOTE: this case requires an extra lookup to get the environment name. + t.Run("Success: Prompt Confirmed (case 3: application-scoped core resource)", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + promptMock := prompt.NewMockInterface(ctrl) + promptMock.EXPECT(). + GetListInput([]string{prompt.ConfirmNo, prompt.ConfirmYes}, fmt.Sprintf(deleteConfirmationWithApplication, "test-container", "Applications.Core/containers", "my-test-app", "my-test-env")). + Return(prompt.ConfirmYes, nil). + Times(1) + + appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) + appManagementClient.EXPECT(). + GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(generated.GenericResource{ + Properties: map[string]interface{}{ + "application": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/applications/my-test-app", }, - } - - require.Equal(t, expected, outputSink.Writes) - }) - - t.Run("Success: Prompt Cancelled", func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) - appManagementClient.EXPECT(). - GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). - Return(generated.GenericResource{ - Properties: map[string]interface{}{ - "environment": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/environments/my-test-env", - "application": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/applications/my-test-app", - }, - }, nil). - Times(1) - - promptMock := prompt.NewMockInterface(ctrl) - promptMock.EXPECT(). - GetListInput([]string{prompt.ConfirmNo, prompt.ConfirmYes}, fmt.Sprintf(deleteConfirmationWithApplication, "test-container", "Applications.Core/containers", "my-test-app", "my-test-env")). - Return(prompt.ConfirmNo, nil). - Times(1) - - workspace := &workspaces.Workspace{ - Connection: map[string]any{ - "kind": "kubernetes", - "context": "kind-kind", + }, nil). + Times(1) + + appManagementClient.EXPECT(). + GetApplication(gomock.Any(), "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/applications/my-test-app"). + Return(v20231001preview.ApplicationResource{ + Properties: &v20231001preview.ApplicationProperties{ + Environment: to.Ptr("/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/environments/my-test-env"), }, - Name: "kind-kind", - Scope: "/planes/radius/local/resourceGroups/test-group", - } - - outputSink := &output.MockOutput{} - runner := &Runner{ - ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, - InputPrompter: promptMock, - Workspace: workspace, - Format: "table", - Output: outputSink, - FullyQualifiedResourceTypeName: "Applications.Core/containers", - ResourceName: "test-container", - } - - err := runner.Run(context.Background()) - require.NoError(t, err) - - expected := []any{ - output.LogOutput{ - Format: "resource %q of type %q NOT deleted", - Params: []any{"test-container", "Applications.Core/containers"}, + }, nil). + Times(1) + appManagementClient.EXPECT(). + DeleteResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(true, nil). + Times(1) + + workspace := &workspaces.Workspace{ + Connection: map[string]any{ + "kind": "kubernetes", + "context": "kind-kind", + }, + Name: "kind-kind", + Scope: "/planes/radius/local/resourceGroups/test-group", + } + + outputSink := &output.MockOutput{} + runner := &Runner{ + ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, + Output: outputSink, + Workspace: workspace, + FullyQualifiedResourceTypeName: "Applications.Core/containers", + ResourceName: "test-container", + Format: "table", + InputPrompter: promptMock, + } + + err := runner.Run(context.Background()) + require.NoError(t, err) + + expected := []any{ + output.LogOutput{ + Format: "%s/%s deleted", + Params: []any{"Applications.Core/containers", "test-container"}, + }, + } + + require.Equal(t, expected, outputSink.Writes) + }) + + t.Run("Success: Prompt Confirmed (case 4: no application or environment)", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + promptMock := prompt.NewMockInterface(ctrl) + promptMock.EXPECT(). + GetListInput([]string{prompt.ConfirmNo, prompt.ConfirmYes}, fmt.Sprintf(deleteConfirmationWithoutApplicationOrEnvironment, "test-container", "Applications.Core/containers")). + Return(prompt.ConfirmYes, nil). + Times(1) + + appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) + appManagementClient.EXPECT(). + GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(generated.GenericResource{ + Properties: map[string]interface{}{}, + }, nil). + Times(1) + + appManagementClient.EXPECT(). + DeleteResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(true, nil). + Times(1) + + workspace := &workspaces.Workspace{ + Connection: map[string]any{ + "kind": "kubernetes", + "context": "kind-kind", + }, + Name: "kind-kind", + Scope: "/planes/radius/local/resourceGroups/test-group", + } + outputSink := &output.MockOutput{} + runner := &Runner{ + ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, + Output: outputSink, + Workspace: workspace, + FullyQualifiedResourceTypeName: "Applications.Core/containers", + ResourceName: "test-container", + Format: "table", + InputPrompter: promptMock, + } + + err := runner.Run(context.Background()) + require.NoError(t, err) + + expected := []any{ + output.LogOutput{ + Format: "%s/%s deleted", + Params: []any{"Applications.Core/containers", "test-container"}, + }, + } + + require.Equal(t, expected, outputSink.Writes) + }) + + t.Run("Success: Prompt Cancelled", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + appManagementClient := clients.NewMockApplicationsManagementClient(ctrl) + appManagementClient.EXPECT(). + GetResource(gomock.Any(), "Applications.Core/containers", "test-container"). + Return(generated.GenericResource{ + Properties: map[string]interface{}{ + "environment": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/environments/my-test-env", + "application": "/planes/radius/local/resourceGroups/test-group/providers/Applications.Core/applications/my-test-app", }, - } - require.Equal(t, expected, outputSink.Writes) - })*/ + }, nil). + Times(1) + + promptMock := prompt.NewMockInterface(ctrl) + promptMock.EXPECT(). + GetListInput([]string{prompt.ConfirmNo, prompt.ConfirmYes}, fmt.Sprintf(deleteConfirmationWithApplication, "test-container", "Applications.Core/containers", "my-test-app", "my-test-env")). + Return(prompt.ConfirmNo, nil). + Times(1) + + workspace := &workspaces.Workspace{ + Connection: map[string]any{ + "kind": "kubernetes", + "context": "kind-kind", + }, + Name: "kind-kind", + Scope: "/planes/radius/local/resourceGroups/test-group", + } + + outputSink := &output.MockOutput{} + runner := &Runner{ + ConnectionFactory: &connections.MockFactory{ApplicationsManagementClient: appManagementClient}, + InputPrompter: promptMock, + Workspace: workspace, + Format: "table", + Output: outputSink, + FullyQualifiedResourceTypeName: "Applications.Core/containers", + ResourceName: "test-container", + } + + err := runner.Run(context.Background()) + require.NoError(t, err) + + require.Empty(t, outputSink.Writes) + }) }) } diff --git a/pkg/cli/cmd/resourceprovider/create/create_test.go b/pkg/cli/cmd/resourceprovider/create/create_test.go index b8fb2ee367..8f394f8230 100644 --- a/pkg/cli/cmd/resourceprovider/create/create_test.go +++ b/pkg/cli/cmd/resourceprovider/create/create_test.go @@ -95,4 +95,26 @@ func Test_Run(t *testing.T) { }, }, outputSink.Writes) }) + + t.Run("Failure: RegisterFile returns error", func(t *testing.T) { + resourceProviderData, err := manifest.ReadFile("testdata/valid.yaml") + require.NoError(t, err) + + clientFactory, err := manifest.NewTestClientFactory(manifest.WithResourceProviderServerInternalError) + require.NoError(t, err) + + outputSink := &output.MockOutput{} + runner := &Runner{ + UCPClientFactory: clientFactory, + Output: outputSink, + Workspace: &workspaces.Workspace{}, + ResourceProvider: resourceProviderData, + Format: "table", + ResourceProviderManifestFilePath: "testdata/valid.yaml", + } + + err = runner.Run(context.Background()) + require.Error(t, err) + require.Empty(t, outputSink.Writes) + }) } From 63cc19b82dfa3bcbfdecc80d121ec86183e6e0e5 Mon Sep 17 00:00:00 2001 From: Zach Casper Date: Thu, 7 May 2026 09:09:14 -0500 Subject: [PATCH 4/6] Corrected failing unit tests Signed-off-by: Zach Casper --- pkg/cli/cmd/env/create/preview/create_test.go | 5 +++-- pkg/cli/cmd/env/update/preview/update_test.go | 1 + pkg/cli/cmd/recipepack/delete/delete.go | 8 +++++--- pkg/cli/cmd/recipepack/delete/delete_test.go | 4 ---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/cli/cmd/env/create/preview/create_test.go b/pkg/cli/cmd/env/create/preview/create_test.go index fc4db18e0a..a9bbfcda94 100644 --- a/pkg/cli/cmd/env/create/preview/create_test.go +++ b/pkg/cli/cmd/env/create/preview/create_test.go @@ -196,10 +196,11 @@ func Test_Run(t *testing.T) { "testenv", }, }, + } - err := runner.Run(context.Background()) + err = runner.Run(context.Background()) require.NoError(t, err) - require.Equal(t, expectedOutput, outputSink.Writes) + require.Equal(t, expectedOutput, outputSink.Writes) }) t.Run("creates default recipe pack when not found", func(t *testing.T) { diff --git a/pkg/cli/cmd/env/update/preview/update_test.go b/pkg/cli/cmd/env/update/preview/update_test.go index d1cc4207ad..437ce1013a 100644 --- a/pkg/cli/cmd/env/update/preview/update_test.go +++ b/pkg/cli/cmd/env/update/preview/update_test.go @@ -307,6 +307,7 @@ func Test_Run(t *testing.T) { }, output.LogOutput{ Format: "Radius.Core/environments/%s updated", + Params: []any{"test-env"}, }, }, }, diff --git a/pkg/cli/cmd/recipepack/delete/delete.go b/pkg/cli/cmd/recipepack/delete/delete.go index 5d2f7c9c95..23899d1441 100644 --- a/pkg/cli/cmd/recipepack/delete/delete.go +++ b/pkg/cli/cmd/recipepack/delete/delete.go @@ -38,9 +38,10 @@ import ( ) const ( - deleteConfirmationMsg = "Are you sure you want to delete recipe pack '%s'?" - msgRecipePackDeleted = "Radius.Core/recipePacks/%s deleted" - msgRecipePackNotFound = "Radius.Core/recipePacks/%s not found" + deleteConfirmationMsg = "Are you sure you want to delete recipe pack '%s'?" + msgRecipePackDeleted = "Radius.Core/recipePacks/%s deleted" + msgRecipePackNotDeleted = "Radius.Core/recipePacks/%s not deleted" + msgRecipePackNotFound = "Radius.Core/recipePacks/%s not found" ) // NewCommand creates a new Cobra command for deleting a recipe pack. @@ -137,6 +138,7 @@ func (r *Runner) Run(ctx context.Context) error { } if !confirmed { + r.Output.LogInfo(msgRecipePackNotDeleted, r.RecipePackName) return nil } } diff --git a/pkg/cli/cmd/recipepack/delete/delete_test.go b/pkg/cli/cmd/recipepack/delete/delete_test.go index 109d73d1fb..45cbbc69f7 100644 --- a/pkg/cli/cmd/recipepack/delete/delete_test.go +++ b/pkg/cli/cmd/recipepack/delete/delete_test.go @@ -163,7 +163,6 @@ func Test_Run(t *testing.T) { require.Empty(t, capturedEnv.Properties.RecipePacks) require.Equal(t, []any{ - output.LogOutput{Format: msgDeletingRecipePack, Params: []any{packName}}, output.LogOutput{Format: msgRecipePackDeleted, Params: []any{packName}}, }, outputSink.Writes) }) @@ -199,7 +198,6 @@ func Test_Run(t *testing.T) { err := runner.Run(context.Background()) require.NoError(t, err) require.Equal(t, []any{ - output.LogOutput{Format: msgDeletingRecipePack, Params: []any{packName}}, output.LogOutput{Format: msgRecipePackDeleted, Params: []any{packName}}, }, outputSink.Writes) }) @@ -249,7 +247,6 @@ func Test_Run(t *testing.T) { err = runner.Run(context.Background()) require.NoError(t, err) require.Equal(t, []any{ - output.LogOutput{Format: msgDeletingRecipePack, Params: []any{packName}}, output.LogOutput{Format: msgRecipePackDeleted, Params: []any{packName}}, }, outputSink.Writes) }) @@ -461,7 +458,6 @@ func Test_Run(t *testing.T) { err := runner.Run(context.Background()) require.NoError(t, err) require.Equal(t, []any{ - output.LogOutput{Format: msgDeletingRecipePack, Params: []any{packName}}, output.LogOutput{Format: msgRecipePackNotFound, Params: []any{packName}}, }, outputSink.Writes) }) From 0060f187ea2515e94b7fce47b3245b309df9eb67 Mon Sep 17 00:00:00 2001 From: Zach Casper Date: Mon, 11 May 2026 15:29:58 -0500 Subject: [PATCH 5/6] Address comments Signed-off-by: Zach Casper --- pkg/cli/cmd/env/update/objectformats.go | 51 ------------------- pkg/cli/cmd/env/update/objectformats_test.go | 41 --------------- pkg/cli/cmd/recipepack/delete/delete.go | 8 ++- pkg/cli/cmd/recipepack/delete/delete_test.go | 4 +- pkg/cli/cmd/resource/create/create.go | 10 +++- pkg/cli/cmd/resource/create/create_test.go | 6 +++ pkg/cli/cmd/resourceprovider/create/create.go | 7 +-- pkg/cli/cmd/resourcetype/create/create.go | 8 +-- pkg/cli/cmd/workspace/create/create.go | 3 +- pkg/cli/cmd/workspace/create/create_test.go | 6 +++ pkg/cli/cmd/workspace/delete/delete.go | 2 +- pkg/cli/cmd/workspace/delete/delete_test.go | 4 +- 12 files changed, 31 insertions(+), 119 deletions(-) delete mode 100644 pkg/cli/cmd/env/update/objectformats.go delete mode 100644 pkg/cli/cmd/env/update/objectformats_test.go diff --git a/pkg/cli/cmd/env/update/objectformats.go b/pkg/cli/cmd/env/update/objectformats.go deleted file mode 100644 index 5db2208194..0000000000 --- a/pkg/cli/cmd/env/update/objectformats.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright 2023 The Radius Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package update - -import "github.com/radius-project/radius/pkg/cli/output" - -type environmentForDisplay struct { - Name string - ComputeKind string - Recipes int - Providers int -} - -// environmentFormat returns a FormatterOptions object containing the column headings and JSONPaths for the -// environment table. -func environmentFormat() output.FormatterOptions { - return output.FormatterOptions{ - Columns: []output.Column{ - { - Heading: "NAME", - JSONPath: "{ .Name }", - }, - { - Heading: "COMPUTE", - JSONPath: "{ .ComputeKind }", - }, - { - Heading: "RECIPES", - JSONPath: "{ .Recipes }", - }, - { - Heading: "PROVIDERS", - JSONPath: "{ .Providers }", - }, - }, - } -} diff --git a/pkg/cli/cmd/env/update/objectformats_test.go b/pkg/cli/cmd/env/update/objectformats_test.go deleted file mode 100644 index b8ffecc228..0000000000 --- a/pkg/cli/cmd/env/update/objectformats_test.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2023 The Radius Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package update - -import ( - "bytes" - "testing" - - "github.com/radius-project/radius/pkg/cli/output" - "github.com/stretchr/testify/require" -) - -func Test_environmentFormat(t *testing.T) { - obj := environmentForDisplay{ - Name: "test_env_resource", - ComputeKind: "kubernetes", - Recipes: 3, - Providers: 2, - } - - buffer := &bytes.Buffer{} - err := output.Write(output.FormatTable, obj, buffer, environmentFormat()) - require.NoError(t, err) - - expected := "NAME COMPUTE RECIPES PROVIDERS\ntest_env_resource kubernetes 3 2\n" - require.Equal(t, expected, buffer.String()) -} diff --git a/pkg/cli/cmd/recipepack/delete/delete.go b/pkg/cli/cmd/recipepack/delete/delete.go index 23899d1441..5d2f7c9c95 100644 --- a/pkg/cli/cmd/recipepack/delete/delete.go +++ b/pkg/cli/cmd/recipepack/delete/delete.go @@ -38,10 +38,9 @@ import ( ) const ( - deleteConfirmationMsg = "Are you sure you want to delete recipe pack '%s'?" - msgRecipePackDeleted = "Radius.Core/recipePacks/%s deleted" - msgRecipePackNotDeleted = "Radius.Core/recipePacks/%s not deleted" - msgRecipePackNotFound = "Radius.Core/recipePacks/%s not found" + deleteConfirmationMsg = "Are you sure you want to delete recipe pack '%s'?" + msgRecipePackDeleted = "Radius.Core/recipePacks/%s deleted" + msgRecipePackNotFound = "Radius.Core/recipePacks/%s not found" ) // NewCommand creates a new Cobra command for deleting a recipe pack. @@ -138,7 +137,6 @@ func (r *Runner) Run(ctx context.Context) error { } if !confirmed { - r.Output.LogInfo(msgRecipePackNotDeleted, r.RecipePackName) return nil } } diff --git a/pkg/cli/cmd/recipepack/delete/delete_test.go b/pkg/cli/cmd/recipepack/delete/delete_test.go index 45cbbc69f7..73edfe94ba 100644 --- a/pkg/cli/cmd/recipepack/delete/delete_test.go +++ b/pkg/cli/cmd/recipepack/delete/delete_test.go @@ -274,9 +274,7 @@ func Test_Run(t *testing.T) { err := runner.Run(context.Background()) require.NoError(t, err) - require.Equal(t, []any{ - output.LogOutput{Format: msgRecipePackNotDeleted, Params: []any{packName}}, - }, outputSink.Writes) + require.Empty(t, outputSink.Writes) }) t.Run("get recipe pack returns 404 — returns error", func(t *testing.T) { diff --git a/pkg/cli/cmd/resource/create/create.go b/pkg/cli/cmd/resource/create/create.go index b0d30a12f9..23db0377da 100644 --- a/pkg/cli/cmd/resource/create/create.go +++ b/pkg/cli/cmd/resource/create/create.go @@ -26,6 +26,7 @@ import ( "github.com/radius-project/radius/pkg/cli/clients_new/generated" "github.com/radius-project/radius/pkg/cli/clierrors" "github.com/radius-project/radius/pkg/cli/cmd/commonflags" + "github.com/radius-project/radius/pkg/cli/cmd/resourceprovider/common" "github.com/radius-project/radius/pkg/cli/connections" "github.com/radius-project/radius/pkg/cli/framework" "github.com/radius-project/radius/pkg/cli/output" @@ -98,6 +99,7 @@ func (r *Runner) Validate(cmd *cobra.Command, args []string) error { return err } r.Format = format + resourceProviderName, resourceTypeName, err := cli.RequireFullyQualifiedResourceType(args) if err != nil { return err @@ -138,11 +140,17 @@ func (r *Runner) Run(ctx context.Context) error { return err } - _, err = client.CreateOrUpdateResource(ctx, r.FullyQualifiedResourceTypeName, r.ResourceName, r.Resource) + response, err := client.CreateOrUpdateResource(ctx, r.FullyQualifiedResourceTypeName, r.ResourceName, r.Resource) if err != nil { return err } + // For non-default output formats (json), emit the full resource representation + // so callers can script against it. For the default/table format, emit a concise line. + if r.Format == output.FormatJson { + return r.Output.WriteFormatted(r.Format, response, common.GetResourceProviderTableFormat()) + } + r.Output.LogInfo("%s/%s created", r.FullyQualifiedResourceTypeName, r.ResourceName) return nil } diff --git a/pkg/cli/cmd/resource/create/create_test.go b/pkg/cli/cmd/resource/create/create_test.go index 1beab31ebb..e4a43048fc 100644 --- a/pkg/cli/cmd/resource/create/create_test.go +++ b/pkg/cli/cmd/resource/create/create_test.go @@ -116,5 +116,11 @@ func Test_Run(t *testing.T) { err := runner.Run(context.Background()) require.NoError(t, err) + require.Equal(t, []any{ + output.LogOutput{ + Format: "%s/%s created", + Params: []any{"Applications.Test/exampleResources", "my-example"}, + }, + }, outputSink.Writes) }) } diff --git a/pkg/cli/cmd/resourceprovider/create/create.go b/pkg/cli/cmd/resourceprovider/create/create.go index f4e93feca8..e6692d0b87 100644 --- a/pkg/cli/cmd/resourceprovider/create/create.go +++ b/pkg/cli/cmd/resourceprovider/create/create.go @@ -76,18 +76,13 @@ type Runner struct { ResourceProviderManifestFilePath string ResourceProvider *manifest.ResourceProvider - Logger func(format string, args ...any) } // NewRunner creates an instance of the runner for the `rad resource-provider create` command. func NewRunner(factory framework.Factory) *Runner { - output := factory.GetOutput() return &Runner{ ConfigHolder: factory.GetConfigHolder(), - Output: output, - Logger: func(format string, args ...any) { - output.LogInfo(format, args...) - }, + Output: factory.GetOutput(), } } diff --git a/pkg/cli/cmd/resourcetype/create/create.go b/pkg/cli/cmd/resourcetype/create/create.go index b8638041c2..635844db7c 100644 --- a/pkg/cli/cmd/resourcetype/create/create.go +++ b/pkg/cli/cmd/resourcetype/create/create.go @@ -32,9 +32,7 @@ import ( ) const ( - defaultPlaneName = "local" - msgNoResourceTypeNameProvided = "No resource type name provided. Creating all resource types in the manifest." - msgAllResourceTypesCreated = "All resource types in the manifest created successfully" + defaultPlaneName = "local" ) // NewCommand creates an instance of the `rad resource-type create` command and runner. @@ -89,7 +87,6 @@ type Runner struct { ResourceProviderManifestFilePath string ResourceProvider *manifest.ResourceProvider ResourceTypeName string - Logger func(format string, args ...any) } // NewRunner creates an instance of the runner for the `rad resource-type create` command. @@ -97,9 +94,6 @@ func NewRunner(factory framework.Factory) *Runner { return &Runner{ ConfigHolder: factory.GetConfigHolder(), Output: factory.GetOutput(), - Logger: func(format string, args ...any) { - output.LogInfo(format, args...) - }, } } diff --git a/pkg/cli/cmd/workspace/create/create.go b/pkg/cli/cmd/workspace/create/create.go index cbfd3186f5..fe56291b75 100644 --- a/pkg/cli/cmd/workspace/create/create.go +++ b/pkg/cli/cmd/workspace/create/create.go @@ -212,8 +212,7 @@ func (r *Runner) Run(ctx context.Context) error { if err != nil { return err } - r.Output.LogInfo("workspace/%s created", r.Workspace.Name) - r.Output.LogInfo("workspace/%s set as current", r.Workspace.Name) + r.Output.LogInfo("Local workspace %s created (current)", r.Workspace.Name) return nil } diff --git a/pkg/cli/cmd/workspace/create/create_test.go b/pkg/cli/cmd/workspace/create/create_test.go index 7929acfbc8..02940cf4de 100644 --- a/pkg/cli/cmd/workspace/create/create_test.go +++ b/pkg/cli/cmd/workspace/create/create_test.go @@ -161,6 +161,12 @@ func Test_Run(t *testing.T) { err := runner.Run(context.Background()) require.NoError(t, err) + require.Equal(t, []any{ + output.LogOutput{ + Format: "Local workspace %s created (current)", + Params: []any{"defaultWorkspace"}, + }, + }, outputSink.Writes) }) } diff --git a/pkg/cli/cmd/workspace/delete/delete.go b/pkg/cli/cmd/workspace/delete/delete.go index f0c8ec7665..4c8f6a2a33 100644 --- a/pkg/cli/cmd/workspace/delete/delete.go +++ b/pkg/cli/cmd/workspace/delete/delete.go @@ -131,6 +131,6 @@ func (r *Runner) Run(ctx context.Context) error { return err } - r.Output.LogInfo("workspace/%s deleted", r.Workspace.Name) + r.Output.LogInfo("Local workspace %s deleted", r.Workspace.Name) return nil } diff --git a/pkg/cli/cmd/workspace/delete/delete_test.go b/pkg/cli/cmd/workspace/delete/delete_test.go index ed2429cfa7..deb23ae7ad 100644 --- a/pkg/cli/cmd/workspace/delete/delete_test.go +++ b/pkg/cli/cmd/workspace/delete/delete_test.go @@ -117,7 +117,7 @@ func Test_Run(t *testing.T) { require.Equal(t, []any{ output.LogOutput{ - Format: "workspace/%s deleted", + Format: "Local workspace %s deleted", Params: []any{"test-workspace"}, }, }, outputSink.Writes) @@ -154,7 +154,7 @@ func Test_Run(t *testing.T) { require.Equal(t, []any{ output.LogOutput{ - Format: "workspace/%s deleted", + Format: "Local workspace %s deleted", Params: []any{"test-workspace"}, }, }, outputSink.Writes) From 62eb13f910fe2b358c1e45cf9367001b9cea260b Mon Sep 17 00:00:00 2001 From: Zach Casper Date: Mon, 18 May 2026 10:11:32 -0500 Subject: [PATCH 6/6] Resolved merge conflicts Signed-off-by: Zach Casper --- pkg/cli/cmd/resource/delete/delete_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cli/cmd/resource/delete/delete_test.go b/pkg/cli/cmd/resource/delete/delete_test.go index a2909976f6..fd597677bc 100644 --- a/pkg/cli/cmd/resource/delete/delete_test.go +++ b/pkg/cli/cmd/resource/delete/delete_test.go @@ -552,4 +552,4 @@ func Test_Run(t *testing.T) { }) }) -} \ No newline at end of file +}