Release Asset Management (#619)
Add release asset management. This includes a series of subcommands under `tea release assets`: - `tea release assets create <release-tag> <asset> [<asset>...]`: Upload one or more release attachments - `tea release assets delete <release tag> <attachment name> [<attachment name>...]`: Delete one or more release attachments - `tea release assets list <release tag>`: List Release Attachments Co-authored-by: Dane Bouchie <dbouchie@iradimed.com> Reviewed-on: https://gitea.com/gitea/tea/pulls/619 Co-authored-by: danebou <danebou@noreply.gitea.com> Co-committed-by: danebou <danebou@noreply.gitea.com>
This commit is contained in:
parent
20479663f0
commit
4c0cef090d
|
@ -34,6 +34,7 @@
|
|||
labels, label Manage issue labels
|
||||
milestones, milestone, ms List and create milestones
|
||||
releases, release, r Manage releases
|
||||
release assets, release asset, r a Manage release attachments
|
||||
times, time, t Operate on tracked times of a repository's issues & pulls
|
||||
organizations, organization, org List, create, delete organizations
|
||||
repos, repo Show repository details
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"code.gitea.io/tea/cmd/attachments"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// CmdReleaseAttachments represents a release attachment (file attachment)
|
||||
var CmdReleaseAttachments = cli.Command{
|
||||
Name: "assets",
|
||||
Aliases: []string{"asset", "a"},
|
||||
Category: catEntities,
|
||||
Usage: "Manage release assets",
|
||||
Description: "Manage release assets",
|
||||
ArgsUsage: " ", // command does not accept arguments
|
||||
Action: attachments.RunReleaseAttachmentList,
|
||||
Subcommands: []*cli.Command{
|
||||
&attachments.CmdReleaseAttachmentList,
|
||||
&attachments.CmdReleaseAttachmentCreate,
|
||||
&attachments.CmdReleaseAttachmentDelete,
|
||||
},
|
||||
Flags: flags.AllDefaultFlags,
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package attachments
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// CmdReleaseAttachmentCreate represents a sub command of Release Attachments to create a release attachment
|
||||
var CmdReleaseAttachmentCreate = cli.Command{
|
||||
Name: "create",
|
||||
Aliases: []string{"c"},
|
||||
Usage: "Create one or more release attachments",
|
||||
Description: `Create one or more release attachments`,
|
||||
ArgsUsage: "<release-tag> <asset> [<asset>...]",
|
||||
Action: runReleaseAttachmentCreate,
|
||||
Flags: flags.AllDefaultFlags,
|
||||
}
|
||||
|
||||
func runReleaseAttachmentCreate(cmd *cli.Context) error {
|
||||
ctx := context.InitCommand(cmd)
|
||||
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
|
||||
client := ctx.Login.Client()
|
||||
|
||||
if ctx.Args().Len() < 2 {
|
||||
return fmt.Errorf("No release tag or assets specified.\nUsage:\t%s", ctx.Command.UsageText)
|
||||
}
|
||||
|
||||
tag := ctx.Args().First()
|
||||
if len(tag) == 0 {
|
||||
return fmt.Errorf("Release tag needed to create attachment")
|
||||
}
|
||||
|
||||
release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, asset := range ctx.Args().Slice()[1:] {
|
||||
var file *os.File
|
||||
if file, err = os.Open(asset); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
filePath := filepath.Base(asset)
|
||||
|
||||
if _, _, err = ctx.Login.Client().CreateReleaseAttachment(ctx.Owner, ctx.Repo, release.ID, file, filePath); err != nil {
|
||||
file.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
file.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package attachments
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// CmdReleaseAttachmentDelete represents a sub command of Release Attachments to delete a release attachment
|
||||
var CmdReleaseAttachmentDelete = cli.Command{
|
||||
Name: "delete",
|
||||
Aliases: []string{"rm"},
|
||||
Usage: "Delete one or more release attachments",
|
||||
Description: `Delete one or more release attachments`,
|
||||
ArgsUsage: "<release tag> <attachment name> [<attachment name>...]",
|
||||
Action: runReleaseAttachmentDelete,
|
||||
Flags: append([]cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "confirm",
|
||||
Aliases: []string{"y"},
|
||||
Usage: "Confirm deletion (required)",
|
||||
},
|
||||
}, flags.AllDefaultFlags...),
|
||||
}
|
||||
|
||||
func runReleaseAttachmentDelete(cmd *cli.Context) error {
|
||||
ctx := context.InitCommand(cmd)
|
||||
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
|
||||
client := ctx.Login.Client()
|
||||
|
||||
if ctx.Args().Len() < 2 {
|
||||
return fmt.Errorf("No release tag or attachment names specified.\nUsage:\t%s", ctx.Command.UsageText)
|
||||
}
|
||||
|
||||
tag := ctx.Args().First()
|
||||
if len(tag) == 0 {
|
||||
return fmt.Errorf("Release tag needed to delete attachment")
|
||||
}
|
||||
|
||||
if !ctx.Bool("confirm") {
|
||||
fmt.Println("Are you sure? Please confirm with -y or --confirm.")
|
||||
return nil
|
||||
}
|
||||
|
||||
release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
existing, _, err := client.ListReleaseAttachments(ctx.Owner, ctx.Repo, release.ID, gitea.ListReleaseAttachmentsOptions{
|
||||
ListOptions: gitea.ListOptions{Page: -1},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, name := range ctx.Args().Slice()[1:] {
|
||||
var attachment *gitea.Attachment
|
||||
for _, a := range existing {
|
||||
if a.Name == name {
|
||||
attachment = a
|
||||
}
|
||||
}
|
||||
if attachment == nil {
|
||||
return fmt.Errorf("Release does not have attachment named '%s'", name)
|
||||
}
|
||||
|
||||
_, err = client.DeleteReleaseAttachment(ctx.Owner, ctx.Repo, release.ID, attachment.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getReleaseAttachmentByName(owner, repo string, release int64, name string, client *gitea.Client) (*gitea.Attachment, error) {
|
||||
al, _, err := client.ListReleaseAttachments(owner, repo, release, gitea.ListReleaseAttachmentsOptions{
|
||||
ListOptions: gitea.ListOptions{Page: -1},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(al) == 0 {
|
||||
return nil, fmt.Errorf("Release does not have any attachments")
|
||||
}
|
||||
for _, a := range al {
|
||||
if a.Name == name {
|
||||
return a, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("Attachment does not exist")
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package attachments
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// CmdReleaseAttachmentList represents a sub command of release attachment to list release attachments
|
||||
var CmdReleaseAttachmentList = cli.Command{
|
||||
Name: "list",
|
||||
Aliases: []string{"ls"},
|
||||
Usage: "List Release Attachments",
|
||||
Description: "List Release Attachments",
|
||||
ArgsUsage: "<release-tag>", // command does not accept arguments
|
||||
Action: RunReleaseAttachmentList,
|
||||
Flags: append([]cli.Flag{
|
||||
&flags.PaginationPageFlag,
|
||||
&flags.PaginationLimitFlag,
|
||||
}, flags.AllDefaultFlags...),
|
||||
}
|
||||
|
||||
// RunReleaseAttachmentList list release attachments
|
||||
func RunReleaseAttachmentList(cmd *cli.Context) error {
|
||||
ctx := context.InitCommand(cmd)
|
||||
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
|
||||
client := ctx.Login.Client()
|
||||
|
||||
tag := ctx.Args().First()
|
||||
if len(tag) == 0 {
|
||||
return fmt.Errorf("Release tag needed to list attachments")
|
||||
}
|
||||
|
||||
release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
attachments, _, err := ctx.Login.Client().ListReleaseAttachments(ctx.Owner, ctx.Repo, release.ID, gitea.ListReleaseAttachmentsOptions{
|
||||
ListOptions: ctx.GetListOptions(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
print.ReleaseAttachmentsList(attachments, ctx.Output)
|
||||
return nil
|
||||
}
|
||||
|
||||
func getReleaseByTag(owner, repo, tag string, client *gitea.Client) (*gitea.Release, error) {
|
||||
rl, _, err := client.ListReleases(owner, repo, gitea.ListReleasesOptions{
|
||||
ListOptions: gitea.ListOptions{Page: -1},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(rl) == 0 {
|
||||
return nil, fmt.Errorf("Repo does not have any release")
|
||||
}
|
||||
for _, r := range rl {
|
||||
if r.TagName == tag {
|
||||
return r, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("Release tag does not exist")
|
||||
}
|
|
@ -25,6 +25,7 @@ var CmdReleases = cli.Command{
|
|||
&releases.CmdReleaseCreate,
|
||||
&releases.CmdReleaseDelete,
|
||||
&releases.CmdReleaseEdit,
|
||||
&CmdReleaseAttachments,
|
||||
},
|
||||
Flags: flags.AllDefaultFlags,
|
||||
}
|
||||
|
|
54
docs/CLI.md
54
docs/CLI.md
|
@ -789,6 +789,60 @@ Edit one or more releases
|
|||
|
||||
**--title, -t**="": Change Title
|
||||
|
||||
### assets, asset, a
|
||||
|
||||
Manage release assets
|
||||
|
||||
**--login, -l**="": Use a different Gitea Login. Optional
|
||||
|
||||
**--output, -o**="": Output format. (simple, table, csv, tsv, yaml, json)
|
||||
|
||||
**--remote, -R**="": Discover Gitea login from remote. Optional
|
||||
|
||||
**--repo, -r**="": Override local repository path or gitea repository slug to interact with. Optional
|
||||
|
||||
#### list, ls
|
||||
|
||||
List Release Attachments
|
||||
|
||||
**--limit, --lm**="": specify limit of items per page
|
||||
|
||||
**--login, -l**="": Use a different Gitea Login. Optional
|
||||
|
||||
**--output, -o**="": Output format. (simple, table, csv, tsv, yaml, json)
|
||||
|
||||
**--page, -p**="": specify page, default is 1
|
||||
|
||||
**--remote, -R**="": Discover Gitea login from remote. Optional
|
||||
|
||||
**--repo, -r**="": Override local repository path or gitea repository slug to interact with. Optional
|
||||
|
||||
#### create, c
|
||||
|
||||
Create one or more release attachments
|
||||
|
||||
**--login, -l**="": Use a different Gitea Login. Optional
|
||||
|
||||
**--output, -o**="": Output format. (simple, table, csv, tsv, yaml, json)
|
||||
|
||||
**--remote, -R**="": Discover Gitea login from remote. Optional
|
||||
|
||||
**--repo, -r**="": Override local repository path or gitea repository slug to interact with. Optional
|
||||
|
||||
#### delete, rm
|
||||
|
||||
Delete one or more release attachments
|
||||
|
||||
**--confirm, -y**: Confirm deletion (required)
|
||||
|
||||
**--login, -l**="": Use a different Gitea Login. Optional
|
||||
|
||||
**--output, -o**="": Output format. (simple, table, csv, tsv, yaml, json)
|
||||
|
||||
**--remote, -R**="": Discover Gitea login from remote. Optional
|
||||
|
||||
**--repo, -r**="": Override local repository path or gitea repository slug to interact with. Optional
|
||||
|
||||
## times, time, t
|
||||
|
||||
Operate on tracked times of a repository's issues & pulls
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package print
|
||||
|
||||
import (
|
||||
"code.gitea.io/sdk/gitea"
|
||||
)
|
||||
|
||||
// ReleaseAttachmentsList prints a listing of release attachments
|
||||
func ReleaseAttachmentsList(attachments []*gitea.Attachment, output string) {
|
||||
t := tableWithHeader(
|
||||
"Name",
|
||||
"Size",
|
||||
)
|
||||
|
||||
for _, attachment := range attachments {
|
||||
t.addRow(
|
||||
attachment.Name,
|
||||
formatSize(attachment.Size),
|
||||
)
|
||||
}
|
||||
|
||||
t.print(output)
|
||||
}
|
Loading…
Reference in New Issue