Files
gitea-tea/cmd/repos/list.go
techknowlogick f638dba99b More improvements (#870)
- no duplicate logins
- link to html page rather than api in output
- client side pagination of watched repos

Reviewed-on: https://gitea.com/gitea/tea/pulls/870
Co-authored-by: techknowlogick <techknowlogick@gitea.com>
Co-committed-by: techknowlogick <techknowlogick@gitea.com>
2026-02-02 22:58:25 +00:00

159 lines
3.5 KiB
Go

// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repos
import (
stdctx "context"
"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/v3"
)
var repoFieldsFlag = flags.FieldsFlag(print.RepoFields, []string{
"owner", "name", "type", "ssh",
})
// CmdReposListFlags contains all flags needed for repo listing
var CmdReposListFlags = append([]cli.Flag{
&cli.BoolFlag{
Name: "watched",
Aliases: []string{"w"},
Required: false,
Usage: "List your watched repos instead",
},
&cli.BoolFlag{
Name: "starred",
Aliases: []string{"s"},
Required: false,
Usage: "List your starred repos instead",
},
repoFieldsFlag,
&typeFilterFlag,
&flags.PaginationPageFlag,
&flags.PaginationLimitFlag,
}, flags.LoginOutputFlags...)
// CmdReposList represents a sub command of repos to list them
var CmdReposList = cli.Command{
Name: "list",
Aliases: []string{"ls"},
Usage: "List repositories you have access to",
Description: "List repositories you have access to",
Action: RunReposList,
Flags: CmdReposListFlags,
}
// RunReposList list repositories
func RunReposList(_ stdctx.Context, cmd *cli.Command) error {
teaCmd := context.InitCommand(cmd)
client := teaCmd.Login.Client()
typeFilter, err := getTypeFilter(cmd)
if err != nil {
return err
}
var rps []*gitea.Repository
if teaCmd.Bool("starred") {
user, _, err := client.GetMyUserInfo()
if err != nil {
return err
}
rps, _, err = client.SearchRepos(gitea.SearchRepoOptions{
ListOptions: flags.GetListOptions(),
StarredByUserID: user.ID,
})
if err != nil {
return err
}
} else if teaCmd.Bool("watched") {
// GetMyWatchedRepos doesn't expose server-side pagination,
// so we implement client-side pagination as a workaround
allRepos, _, err := client.GetMyWatchedRepos()
if err != nil {
return err
}
rps = paginateRepos(allRepos, flags.GetListOptions())
} else {
var err error
rps, _, err = client.ListMyRepos(gitea.ListReposOptions{
ListOptions: flags.GetListOptions(),
})
if err != nil {
return err
}
}
reposFiltered := rps
if typeFilter != gitea.RepoTypeNone {
reposFiltered = filterReposByType(rps, typeFilter)
}
fields, err := repoFieldsFlag.GetValues(cmd)
if err != nil {
return err
}
print.ReposList(reposFiltered, teaCmd.Output, fields)
return nil
}
func filterReposByType(repos []*gitea.Repository, t gitea.RepoType) []*gitea.Repository {
var filtered []*gitea.Repository
for _, r := range repos {
switch t {
case gitea.RepoTypeFork:
if !r.Fork {
continue
}
case gitea.RepoTypeMirror:
if !r.Mirror {
continue
}
case gitea.RepoTypeSource:
if r.Fork || r.Mirror {
continue
}
}
filtered = append(filtered, r)
}
return filtered
}
// paginateRepos implements client-side pagination for repositories.
// This is a workaround for API endpoints that don't support server-side pagination.
func paginateRepos(repos []*gitea.Repository, opts gitea.ListOptions) []*gitea.Repository {
if len(repos) == 0 {
return repos
}
pageSize := opts.PageSize
if pageSize <= 0 {
pageSize = flags.PaginationLimitFlag.Value
}
page := opts.Page
if page < 1 {
page = 1
}
start := (page - 1) * pageSize
end := start + pageSize
if start >= len(repos) {
return []*gitea.Repository{}
}
if end > len(repos) {
end = len(repos)
}
return repos[start:end]
}