feat(repos): add 'repos settings' subcommand for feature toggles and merge policy

Adds a new 'repos settings' (alias: config) subcommand that complements
the existing 'repos edit' command:

- 'repos edit'   - basic properties (name, description, website,
                   private/template/archived, default-branch)
- 'repos settings' - feature toggles (issues, wiki, pulls, projects,
                     releases, packages, actions) and merge policy
                     (default style, allowed merge strategies)

The split keeps each command focused and avoids duplicating flags
already present on 'repos edit' (PR #928). Trying to set both
--enable-X and --disable-X in the same invocation will fail at the
Gitea API layer; the command emits a clear error if no changes are
requested.
This commit is contained in:
Ross Golder 2026-07-30 10:10:20 +07:00
parent 58931b5d17
commit 42a85f603e
No known key found for this signature in database
GPG key ID: 253A7E508D2D59CD
2 changed files with 144 additions and 0 deletions

View file

@ -33,6 +33,7 @@ var CmdRepos = cli.Command{
&repos.CmdRepoMigrate,
&repos.CmdRepoRm,
&repos.CmdRepoEdit,
&repos.CmdReposSettings,
},
Flags: repos.CmdReposListFlags,
}

143
cmd/repos/settings.go Normal file
View file

@ -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
}