package deleteasset
import (
"fmt"
"net/http"
"github.com/MakeNowJust/heredoc/v2"
"github.com/spf13/cobra"
"gitcode.com/gitcode-cli/cli/api"
cmdutil "gitcode.com/gitcode-cli/cli/pkg/cmdutil"
"gitcode.com/gitcode-cli/cli/pkg/iostreams"
)
type DeleteAssetOptions struct {
IO *iostreams.IOStreams
HttpClient func() (*http.Client, error)
BaseRepo func() (string, error)
TagName string
AttachFileID string
Repository string
Yes bool
DryRun bool
}
func NewCmdDeleteAsset(f *cmdutil.Factory, runF func(*DeleteAssetOptions) error) *cobra.Command {
opts := &DeleteAssetOptions{
IO: f.IOStreams,
HttpClient: f.HttpClient,
BaseRepo: f.BaseRepo,
}
cmd := &cobra.Command{
Use: "delete-asset <tag> <asset-id>",
Short: "Delete a release asset",
Long: heredoc.Doc(`
Delete an attached file (asset) from a release.
The asset-id can be obtained from "gc release view <tag> --json"
(the id field of each asset).
Non-interactive mode: requires --yes to skip confirmation.
`),
Example: heredoc.Doc(`
# Delete a release asset
$ gc release delete-asset v1.0.0 12345 -R owner/repo
# Delete without confirmation
$ gc release delete-asset v1.0.0 12345 -R owner/repo --yes
# Preview the deletion
$ gc release delete-asset v1.0.0 12345 -R owner/repo --dry-run
`),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
opts.TagName = args[0]
opts.AttachFileID = args[1]
if runF != nil {
return runF(opts)
}
return deleteAssetRun(opts)
},
}
cmd.Flags().StringVarP(&opts.Repository, "repo", "R", "", "Repository (owner/repo)")
cmd.Flags().BoolVarP(&opts.Yes, "yes", "y", false, "Skip confirmation")
cmd.Flags().BoolVar(&opts.DryRun, "dry-run", false, "Preview the deletion without deleting the asset")
return cmd
}
func deleteAssetRun(opts *DeleteAssetOptions) error {
cs := opts.IO.ColorScheme()
repository, err := cmdutil.ResolveRepo(opts.Repository, opts.BaseRepo)
if err != nil {
return err
}
owner, repo, err := parseRepo(repository)
if err != nil {
return err
}
if opts.DryRun {
fmt.Fprintf(opts.IO.Out, "Dry run: would delete asset %s from release %s in %s/%s\n", opts.AttachFileID, opts.TagName, owner, repo)
return nil
}
httpClient, err := opts.HttpClient()
if err != nil {
return fmt.Errorf("failed to create HTTP client: %w", err)
}
client, err := cmdutil.AuthenticatedClient(httpClient)
if err != nil {
return err
}
if err := cmdutil.ConfirmOrAbort(cmdutil.ConfirmOptions{
IO: opts.IO,
Yes: opts.Yes,
Expected: opts.AttachFileID,
Prompt: fmt.Sprintf("! This will delete asset %s from release %s\nType the asset id to confirm: ", cs.Bold(opts.AttachFileID), opts.TagName),
}); err != nil {
return err
}
if err := api.DeleteReleaseAssetByTag(client, owner, repo, opts.TagName, opts.AttachFileID); err != nil {
return cmdutil.WrapNotFound(err, "asset %s not found in release %s in %s/%s", opts.AttachFileID, opts.TagName, owner, repo)
}
fmt.Fprintf(opts.IO.Out, "%s Deleted asset %s from release %s\n", cs.Red("✓"), opts.AttachFileID, opts.TagName)
return nil
}
func parseRepo(repo string) (string, string, error) {
return cmdutil.ParseRepo(repo)
}