diff --git a/cmd/repos.go b/cmd/repos.go index 47b54e94..34eefd2d 100644 --- a/cmd/repos.go +++ b/cmd/repos.go @@ -33,6 +33,7 @@ var CmdRepos = cli.Command{ &repos.CmdRepoMigrate, &repos.CmdRepoRm, &repos.CmdRepoEdit, + &repos.CmdReposSettings, }, Flags: repos.CmdReposListFlags, } diff --git a/cmd/repos/settings.go b/cmd/repos/settings.go new file mode 100644 index 00000000..67f79ce3 --- /dev/null +++ b/cmd/repos/settings.go @@ -0,0 +1,143 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repos + +import ( + stdctx "context" + "errors" + "fmt" + + gitea "gitea.dev/sdk" + + "gitea.dev/tea/cmd/flags" + "gitea.dev/tea/modules/context" + "github.com/urfave/cli/v3" +) + +// CmdReposSettings represents a sub command of repos to manage repository +// feature toggles and merge policy settings. +// +// Note: basic repository properties (name, description, website, visibility, +// archived, default branch) are handled by 'repos edit'. 'repos settings' is +// for feature toggles and merge-policy configuration. +var CmdReposSettings = cli.Command{ + Name: "settings", + Aliases: []string{"config"}, + Usage: "Manage repository feature toggles and merge policy", + Description: "Toggle repository features (issues, wiki, pulls, projects, releases, packages, actions) and configure merge policy (default style, allowed merge strategies). For basic properties like name, description, and visibility, use 'repos edit'.", + Action: runReposSettings, + Flags: append([]cli.Flag{ + // Feature toggles + &cli.BoolFlag{Name: "enable-issues", Usage: "enable issues"}, + &cli.BoolFlag{Name: "disable-issues", Usage: "disable issues"}, + &cli.BoolFlag{Name: "enable-wiki", Usage: "enable wiki"}, + &cli.BoolFlag{Name: "disable-wiki", Usage: "disable wiki"}, + &cli.BoolFlag{Name: "enable-pull-requests", Usage: "enable pull requests"}, + &cli.BoolFlag{Name: "disable-pull-requests", Usage: "disable pull requests"}, + &cli.BoolFlag{Name: "enable-projects", Usage: "enable projects"}, + &cli.BoolFlag{Name: "disable-projects", Usage: "disable projects"}, + &cli.BoolFlag{Name: "enable-releases", Usage: "enable releases"}, + &cli.BoolFlag{Name: "disable-releases", Usage: "disable releases"}, + &cli.BoolFlag{Name: "enable-packages", Usage: "enable packages"}, + &cli.BoolFlag{Name: "disable-packages", Usage: "disable packages"}, + &cli.BoolFlag{Name: "enable-actions", Usage: "enable actions"}, + &cli.BoolFlag{Name: "disable-actions", Usage: "disable actions"}, + + // Merge policy + &cli.StringFlag{ + Name: "default-merge-style", + Usage: "default merge style for pull requests (merge, rebase, rebase-merge, squash)", + }, + &cli.BoolFlag{Name: "allow-merge-commits", Usage: "allow merge commits"}, + &cli.BoolFlag{Name: "disallow-merge-commits", Usage: "disallow merge commits"}, + &cli.BoolFlag{Name: "allow-rebase", Usage: "allow rebase merging"}, + &cli.BoolFlag{Name: "disallow-rebase", Usage: "disallow rebase merging"}, + &cli.BoolFlag{Name: "allow-squash", Usage: "allow squash merging"}, + &cli.BoolFlag{Name: "disallow-squash", Usage: "disallow squash merging"}, + }, flags.AllDefaultFlags...), +} + +func runReposSettings(ctx stdctx.Context, cmd *cli.Command) error { + c, err := context.InitCommand(cmd) + if err != nil { + return err + } + if err := c.Ensure(context.CtxRequirement{RemoteRepo: true}); err != nil { + return err + } + client := c.Login.Client() + + opt := gitea.EditRepoOption{} + hasChanges := false + + // Feature toggles + if setBool(cmd, &opt.HasIssues, "enable-issues", "disable-issues") { + hasChanges = true + } + if setBool(cmd, &opt.HasWiki, "enable-wiki", "disable-wiki") { + hasChanges = true + } + if setBool(cmd, &opt.HasPullRequests, "enable-pull-requests", "disable-pull-requests") { + hasChanges = true + } + if setBool(cmd, &opt.HasProjects, "enable-projects", "disable-projects") { + hasChanges = true + } + if setBool(cmd, &opt.HasReleases, "enable-releases", "disable-releases") { + hasChanges = true + } + if setBool(cmd, &opt.HasPackages, "enable-packages", "disable-packages") { + hasChanges = true + } + if setBool(cmd, &opt.HasActions, "enable-actions", "disable-actions") { + hasChanges = true + } + + // Default merge style + if cmd.IsSet("default-merge-style") { + style := gitea.MergeStyle(cmd.String("default-merge-style")) + opt.DefaultMergeStyle = &style + hasChanges = true + } + + // Merge strategy toggles + if setBool(cmd, &opt.AllowMerge, "allow-merge-commits", "disallow-merge-commits") { + hasChanges = true + } + if setBool(cmd, &opt.AllowRebase, "allow-rebase", "disallow-rebase") { + hasChanges = true + } + if setBool(cmd, &opt.AllowSquash, "allow-squash", "disallow-squash") { + hasChanges = true + } + + if !hasChanges { + return errors.New("no settings changes specified; pass at least one --enable-* / --disable-* / --allow-* / --disallow-* flag, or --default-merge-style") + } + + repo, _, err := client.EditRepo(ctx, c.Owner, c.Repo, opt) + if err != nil { + return err + } + + fmt.Printf("Repository settings updated: %s/%s\n", repo.Owner.UserName, repo.Name) + return nil +} + +// setBool applies a pair of mutually exclusive --enable-X / --disable-X +// style flags to a *bool field on the EditRepoOption. Returns true if +// either flag was set, in which case the field has been written. +func setBool(cmd *cli.Command, field **bool, enableFlag, disableFlag string) bool { + if cmd.Bool(enableFlag) { + v := true + *field = &v + return true + } + if cmd.Bool(disableFlag) { + v := false + *field = &v + return true + } + return false +}