99 "github.com/pterm/pterm"
1010 "github.com/samber/lo"
1111 "github.com/spf13/cobra"
12+ "golang.org/x/sync/errgroup"
1213)
1314
1415var appCmd = & cobra.Command {
@@ -25,7 +26,14 @@ var appListCmd = &cobra.Command{
2526 RunE : runAppList ,
2627}
2728
28- // --- app history subcommand (scaffold)
29+ var appDeleteCmd = & cobra.Command {
30+ Use : "delete <app_name>" ,
31+ Short : "Delete an app and all its deployments" ,
32+ Long : "Deletes all deployments for an application. Use --version to scope deletion to a specific version." ,
33+ Args : cobra .ExactArgs (1 ),
34+ RunE : runAppDelete ,
35+ }
36+
2937var appHistoryCmd = & cobra.Command {
3038 Use : "history <app_name>" ,
3139 Short : "Show deployment history for an application" ,
@@ -36,8 +44,13 @@ var appHistoryCmd = &cobra.Command{
3644func init () {
3745 // register subcommands under app
3846 appCmd .AddCommand (appListCmd )
47+ appCmd .AddCommand (appDeleteCmd )
3948 appCmd .AddCommand (appHistoryCmd )
4049
50+ // Flags for delete
51+ appDeleteCmd .Flags ().String ("version" , "" , "Only delete deployments for this version (default: all versions)" )
52+ appDeleteCmd .Flags ().BoolP ("yes" , "y" , false , "Skip confirmation prompt" )
53+
4154 // Add optional filters for list
4255 appListCmd .Flags ().String ("name" , "" , "Filter by application name" )
4356 appListCmd .Flags ().String ("version" , "" , "Filter by version label" )
@@ -206,6 +219,76 @@ func runAppList(cmd *cobra.Command, args []string) error {
206219 return nil
207220}
208221
222+ func runAppDelete (cmd * cobra.Command , args []string ) error {
223+ client := getKernelClient (cmd )
224+ appName := args [0 ]
225+ version , _ := cmd .Flags ().GetString ("version" )
226+ skipConfirm , _ := cmd .Flags ().GetBool ("yes" )
227+
228+ params := kernel.DeploymentListParams {
229+ AppName : kernel .Opt (appName ),
230+ Limit : kernel .Opt (int64 (100 )),
231+ Offset : kernel .Opt (int64 (0 )),
232+ }
233+ if version != "" {
234+ params .AppVersion = kernel .Opt (version )
235+ }
236+
237+ initial , err := client .Deployments .List (cmd .Context (), params )
238+ if err != nil {
239+ return util.CleanedUpSdkError {Err : err }
240+ }
241+ if initial == nil || len (initial .Items ) == 0 {
242+ pterm .Info .Printf ("No deployments found for app '%s'\n " , appName )
243+ return nil
244+ }
245+
246+ if ! skipConfirm {
247+ scope := "all versions"
248+ if version != "" {
249+ scope = fmt .Sprintf ("version '%s'" , version )
250+ }
251+ msg := fmt .Sprintf ("Delete all deployments for app '%s' (%s)? This cannot be undone." , appName , scope )
252+ pterm .DefaultInteractiveConfirm .DefaultText = msg
253+ ok , _ := pterm .DefaultInteractiveConfirm .Show ()
254+ if ! ok {
255+ pterm .Info .Println ("Deletion cancelled" )
256+ return nil
257+ }
258+ }
259+
260+ spinner , _ := pterm .DefaultSpinner .Start (fmt .Sprintf ("Deleting deployments for app '%s'..." , appName ))
261+ deleted := 0
262+
263+ for {
264+ page , err := client .Deployments .List (cmd .Context (), params )
265+ if err != nil {
266+ spinner .Fail ("Failed to list deployments" )
267+ return util.CleanedUpSdkError {Err : err }
268+ }
269+ items := page .Items
270+ if len (items ) == 0 {
271+ break
272+ }
273+
274+ g , gctx := errgroup .WithContext (cmd .Context ())
275+ for _ , dep := range items {
276+ g .Go (func () error {
277+ return client .Deployments .Delete (gctx , dep .ID )
278+ })
279+ }
280+ if err := g .Wait (); err != nil {
281+ spinner .Fail ("Failed to delete deployments" )
282+ return util.CleanedUpSdkError {Err : err }
283+ }
284+ deleted += len (items )
285+ spinner .UpdateText (fmt .Sprintf ("Deleted %d deployment(s) so far..." , deleted ))
286+ }
287+
288+ spinner .Success (fmt .Sprintf ("Deleted %d deployment(s) for app '%s'" , deleted , appName ))
289+ return nil
290+ }
291+
209292func runAppHistory (cmd * cobra.Command , args []string ) error {
210293 client := getKernelClient (cmd )
211294 appName := args [0 ]
0 commit comments