Skip to content

Commit cee6fff

Browse files
Support deleting by tag
1 parent 56cf9cd commit cee6fff

File tree

3 files changed

+20
-73
lines changed

3 files changed

+20
-73
lines changed

pkg/cmd/image/list.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"fmt"
88
"os"
99
"sort"
10-
"strings"
1110
"time"
1211

1312
"connectrpc.com/connect"
@@ -160,14 +159,8 @@ func fetchAllImages(ctx context.Context, projectID, token string, client buildv1
160159
t := img.PushedAt.AsTime()
161160
pushedAt = &t
162161
}
163-
// The API returns tags in format: registry.depot.dev/PROJECT:TAG
164-
// We want to show them as PROJECT:TAG
165-
tag := img.Tag
166-
if strings.HasPrefix(tag, "registry.depot.dev/") {
167-
tag = strings.TrimPrefix(tag, "registry.depot.dev/")
168-
}
169162
allImages = append(allImages, DepotImage{
170-
Tag: tag,
163+
Tag: img.Tag,
171164
Digest: img.Digest,
172165
SizeBytes: img.SizeBytes,
173166
PushedAt: pushedAt,

pkg/cmd/image/rm.go

Lines changed: 15 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
package image
22

33
import (
4-
"context"
54
"fmt"
6-
"strings"
7-
"time"
85

96
"connectrpc.com/connect"
107
"github.com/depot/cli/pkg/api"
@@ -16,46 +13,24 @@ import (
1613

1714
func NewCmdRM() *cobra.Command {
1815
var token string
19-
var force bool
20-
var digests []string
16+
var projectID string
2117

2218
cmd := &cobra.Command{
23-
Use: "rm PROJECT --digest DIGEST [--digest DIGEST...]",
19+
Use: "rm <tag> [<tag>...]",
2420
Aliases: []string{"remove", "delete"},
25-
Short: "Remove images from the registry by digest",
26-
Long: `Remove images from the registry by digest.
27-
28-
To find image digests, use 'depot image list --project PROJECT'.
29-
Images are referenced by their sha256 digest.`,
30-
Example: ` # Delete a single image by digest
31-
depot image rm myproject --digest sha256:abc123...
32-
33-
# Delete multiple images
34-
depot image rm myproject --digest sha256:abc123... --digest sha256:def456...
35-
36-
# Force deletion without confirmation
37-
depot image rm myproject --digest sha256:abc123... --force`,
38-
Args: cobra.ExactArgs(1),
21+
Short: "Remove images from the registry by tag",
22+
Args: cobra.MinimumNArgs(1),
3923
RunE: func(cmd *cobra.Command, args []string) error {
40-
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
41-
defer cancel()
42-
43-
projectID := args[0]
24+
ctx := cmd.Context()
4425

45-
if len(digests) == 0 {
46-
return errors.New("at least one --digest is required")
26+
projectID = helpers.ResolveProjectID(projectID)
27+
if projectID == "" {
28+
return errors.New("please specify a project ID")
4729
}
4830

49-
// Convert digests to the format ECR expects
50-
var imageTags []string
51-
for _, digest := range digests {
52-
// The ECR API expects image tags in the format "sha256-<digest>" rather than the standard "sha256:<digest>".
53-
// This transformation ensures compatibility with the ECR API by converting the prefix.
54-
digest = strings.TrimPrefix(digest, "sha256:")
55-
imageTags = append(imageTags, "sha256-"+digest)
56-
}
31+
imageTags := args
5732

58-
token, err := helpers.ResolveProjectAuth(context.Background(), token)
33+
token, err := helpers.ResolveProjectAuth(ctx, token)
5934
if err != nil {
6035
return err
6136
}
@@ -64,34 +39,16 @@ Images are referenced by their sha256 digest.`,
6439
return fmt.Errorf("missing API token, please run `depot login`")
6540
}
6641

67-
totalImages := len(digests)
68-
if !force {
69-
fmt.Printf("Are you sure you want to delete %d image(s)? [y/N]: ", totalImages)
70-
var response string
71-
if _, err := fmt.Scanln(&response); err != nil {
72-
return fmt.Errorf("error reading input: %w", err)
73-
}
74-
if response != "y" && response != "Y" {
75-
fmt.Println("Operation cancelled")
76-
return nil
77-
}
78-
}
79-
8042
client := api.NewRegistryClient()
81-
82-
req := connect.NewRequest(&v1.DeleteImageRequest{
83-
ProjectId: projectID,
84-
ImageTags: imageTags,
85-
})
86-
87-
req = api.WithAuthentication(req, token)
88-
_, err = client.DeleteImage(ctx, req)
43+
req := connect.NewRequest(&v1.DeleteImageRequest{ProjectId: projectID, ImageTags: imageTags})
44+
_, err = client.DeleteImage(ctx, api.WithAuthentication(req, token))
8945
if err != nil {
9046
return fmt.Errorf("failed to delete images: %v", err)
9147
}
9248

49+
totalImages := len(imageTags)
9350
if totalImages == 1 {
94-
fmt.Printf("Successfully deleted image with digest: %s\n", digests[0])
51+
fmt.Printf("Successfully deleted image with tag: %s\n", imageTags[0])
9552
} else {
9653
fmt.Printf("Successfully deleted %d images\n", totalImages)
9754
}
@@ -101,11 +58,8 @@ Images are referenced by their sha256 digest.`,
10158
}
10259

10360
flags := cmd.Flags()
104-
flags.StringSliceVar(&digests, "digest", []string{}, "Image digest(s) to delete (can be specified multiple times)")
61+
flags.StringVar(&projectID, "project", "", "Depot project ID")
10562
flags.StringVar(&token, "token", "", "Depot token")
106-
flags.BoolVarP(&force, "force", "f", false, "Force deletion without confirmation")
107-
108-
cmd.MarkFlagRequired("digest")
10963

11064
return cmd
11165
}

proto/depot/build/v1/registry.proto

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ service RegistryService {
1313

1414
message ListImagesRequest {
1515
string project_id = 1;
16-
16+
1717
// The maximum number of results to return per page
1818
optional int32 page_size = 2;
19-
19+
2020
// The page token indicating which page of results to return
2121
optional string page_token = 3;
2222
}
@@ -30,7 +30,7 @@ message Image {
3030

3131
message ListImagesResponse {
3232
repeated Image images = 1;
33-
33+
3434
// The next page token, if there are more results
3535
optional string next_page_token = 2;
3636
}
@@ -40,4 +40,4 @@ message DeleteImageRequest {
4040
repeated string image_tags = 2;
4141
}
4242

43-
message DeleteImageResponse {}
43+
message DeleteImageResponse {}

0 commit comments

Comments
 (0)