Second pass of tea-parity work:
- fgj webhook {list,create,update,delete}: full CRUD over repo webhooks.
Create supports all standard hook types (gitea, slack, discord, etc.),
event selection, content type, secret, branch filter, auth header.
Update is partial — flags you omit leave existing config unchanged.
- fgj repo delete: type-to-confirm deletion; --yes skips for scripts;
refuses without a TTY unless --yes is passed.
- fgj repo search: SDK SearchRepos with query, topic/description,
private/archived, --type (source/fork/mirror), owner, sort/order.
- fgj admin user list: admin-gated user enumeration.
- fgj pr clean: delete the local branch from 'pr checkout'. Refuses
if the PR is still open (use --force) or if the branch is currently
checked out.
- fgj pr review-comments: list inline review comments across every
review on a PR (ListPullReviews + ListPullReviewComments per review).
- fgj pr resolve / unresolve: mark review comments as (un)resolved.
Uses raw POST since SDK v0.22.1 predates these endpoints; requires
Forgejo 8.x+ / Gitea 1.22+ server-side.
All share the standard parseRepo + config.Load + NewClientFromConfig
pattern; list commands support --json / --jq.
85 lines
1.8 KiB
Go
85 lines
1.8 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"code.gitea.io/sdk/gitea"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var adminCmd = &cobra.Command{
|
|
Use: "admin",
|
|
Aliases: []string{"a"},
|
|
Short: "Operations requiring admin access",
|
|
Long: "Administrative operations on the current host. These require an admin-scoped token.",
|
|
}
|
|
|
|
var adminUserCmd = &cobra.Command{
|
|
Use: "user",
|
|
Aliases: []string{"users", "u"},
|
|
Short: "Manage users on the host",
|
|
Long: "Admin-scoped user management.",
|
|
}
|
|
|
|
var adminUserListCmd = &cobra.Command{
|
|
Use: "list",
|
|
Aliases: []string{"ls"},
|
|
Short: "List all users on the host",
|
|
Example: ` # List users
|
|
fgj admin user list
|
|
|
|
# Limit and output as JSON
|
|
fgj admin user list --limit 100 --json`,
|
|
RunE: runAdminUserList,
|
|
}
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(adminCmd)
|
|
adminCmd.AddCommand(adminUserCmd)
|
|
adminUserCmd.AddCommand(adminUserListCmd)
|
|
|
|
adminUserListCmd.Flags().IntP("limit", "L", 50, "Maximum number of users to list")
|
|
addJSONFlags(adminUserListCmd, "Output as JSON")
|
|
}
|
|
|
|
func runAdminUserList(cmd *cobra.Command, args []string) error {
|
|
client, err := loadClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
limit, _ := cmd.Flags().GetInt("limit")
|
|
if limit <= 0 {
|
|
limit = 50
|
|
}
|
|
|
|
users, _, err := client.AdminListUsers(gitea.AdminListUsersOptions{
|
|
ListOptions: gitea.ListOptions{PageSize: limit},
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to list users (admin token required): %w", err)
|
|
}
|
|
|
|
if wantJSON(cmd) {
|
|
return outputJSON(cmd, users)
|
|
}
|
|
|
|
if len(users) == 0 {
|
|
fmt.Fprintln(ios.Out, "No users found.")
|
|
return nil
|
|
}
|
|
|
|
tp := ios.NewTablePrinter()
|
|
tp.AddHeader("LOGIN", "FULL NAME", "EMAIL", "ADMIN", "ACTIVE")
|
|
for _, u := range users {
|
|
admin, active := "", "yes"
|
|
if u.IsAdmin {
|
|
admin = "yes"
|
|
}
|
|
if !u.IsActive {
|
|
active = "no"
|
|
}
|
|
tp.AddRow(u.UserName, u.FullName, u.Email, admin, active)
|
|
}
|
|
return tp.Render()
|
|
}
|