github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/release/delete-asset/delete_asset.go (about) 1 package deleteasset 2 3 import ( 4 "fmt" 5 "net/http" 6 7 "github.com/AlecAivazis/survey/v2" 8 "github.com/ungtb10d/cli/v2/api" 9 "github.com/ungtb10d/cli/v2/internal/ghrepo" 10 "github.com/ungtb10d/cli/v2/pkg/cmd/release/shared" 11 "github.com/ungtb10d/cli/v2/pkg/cmdutil" 12 "github.com/ungtb10d/cli/v2/pkg/iostreams" 13 "github.com/ungtb10d/cli/v2/pkg/prompt" 14 "github.com/spf13/cobra" 15 ) 16 17 type DeleteAssetOptions struct { 18 HttpClient func() (*http.Client, error) 19 IO *iostreams.IOStreams 20 BaseRepo func() (ghrepo.Interface, error) 21 22 TagName string 23 SkipConfirm bool 24 AssetName string 25 } 26 27 func NewCmdDeleteAsset(f *cmdutil.Factory, runF func(*DeleteAssetOptions) error) *cobra.Command { 28 opts := &DeleteAssetOptions{ 29 IO: f.IOStreams, 30 HttpClient: f.HttpClient, 31 } 32 33 cmd := &cobra.Command{ 34 Use: "delete-asset <tag> <asset-name>", 35 Short: "Delete an asset from a release", 36 Args: cobra.ExactArgs(2), 37 RunE: func(cmd *cobra.Command, args []string) error { 38 // support `-R, --repo` override 39 opts.BaseRepo = f.BaseRepo 40 opts.TagName = args[0] 41 opts.AssetName = args[1] 42 if runF != nil { 43 return runF(opts) 44 } 45 return deleteAssetRun(opts) 46 }, 47 } 48 49 cmd.Flags().BoolVarP(&opts.SkipConfirm, "yes", "y", false, "Skip the confirmation prompt") 50 51 return cmd 52 } 53 54 func deleteAssetRun(opts *DeleteAssetOptions) error { 55 httpClient, err := opts.HttpClient() 56 if err != nil { 57 return err 58 } 59 60 baseRepo, err := opts.BaseRepo() 61 if err != nil { 62 return err 63 } 64 65 release, err := shared.FetchRelease(httpClient, baseRepo, opts.TagName) 66 if err != nil { 67 return err 68 } 69 70 if !opts.SkipConfirm && opts.IO.CanPrompt() { 71 var confirmed bool 72 //nolint:staticcheck // SA1019: prompt.SurveyAskOne is deprecated: use Prompter 73 err := prompt.SurveyAskOne(&survey.Confirm{ 74 Message: fmt.Sprintf("Delete asset %s in release %s in %s?", opts.AssetName, release.TagName, ghrepo.FullName(baseRepo)), 75 Default: true, 76 }, &confirmed) 77 if err != nil { 78 return err 79 } 80 81 if !confirmed { 82 return cmdutil.CancelError 83 } 84 } 85 86 var assetURL string 87 for _, a := range release.Assets { 88 if a.Name == opts.AssetName { 89 assetURL = a.APIURL 90 break 91 } 92 } 93 if assetURL == "" { 94 return fmt.Errorf("asset %s not found in release %s", opts.AssetName, release.TagName) 95 } 96 97 err = deleteAsset(httpClient, assetURL) 98 if err != nil { 99 return err 100 } 101 102 if !opts.IO.IsStdoutTTY() || !opts.IO.IsStderrTTY() { 103 return nil 104 } 105 106 cs := opts.IO.ColorScheme() 107 fmt.Fprintf(opts.IO.ErrOut, "%s Deleted asset %s from release %s\n", cs.SuccessIconWithColor(cs.Red), opts.AssetName, release.TagName) 108 109 return nil 110 } 111 112 func deleteAsset(httpClient *http.Client, assetURL string) error { 113 req, err := http.NewRequest("DELETE", assetURL, nil) 114 if err != nil { 115 return err 116 } 117 118 resp, err := httpClient.Do(req) 119 if err != nil { 120 return err 121 } 122 defer resp.Body.Close() 123 124 if resp.StatusCode > 299 { 125 return api.HandleHTTPError(resp) 126 } 127 return nil 128 }