mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
feat(repo): show repository columns, state and README
repo list and search repo printed bare names. They now render a table with NAME, DESCRIPTION, INFO (public or private, fork, mirror, template, archived, empty) and UPDATED under "Showing N of M repositories ...", an empty-state message on stderr, and tab-separated rows with the URL when piped. --type, --sort and --order complete and validate their values. repo view shows the visibility and kind badges, stars, forks, open issues and pull requests, the parent of a fork, the source of a mirror, the default branch and the clone URLs, followed by the README of the default branch (or --branch), rendered on a terminal. The repository JSON gains empty, stars_count, forks_count, open_issues_count, open_pr_count, topics and updated_at. Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
10 files changed
+456
-152
No files matched your search
@@ -5,6 +5,10 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"gitea.dev/tea/internal/transport"
|
||||
@@ -30,6 +34,13 @@ type Repository struct {
|
||||
Template bool `json:"template"`
|
||||
Fork bool `json:"fork"`
|
||||
Mirror bool `json:"mirror"`
|
||||
Empty bool `json:"empty"`
|
||||
Stars int `json:"stars_count"`
|
||||
Forks int `json:"forks_count"`
|
||||
OpenIssues int `json:"open_issues_count"`
|
||||
OpenPulls int `json:"open_pr_count"`
|
||||
Topics []string `json:"topics"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
Parent *Repository `json:"parent,omitempty"`
|
||||
// OriginalURL stays out of JSON output: migration sources may embed credentials.
|
||||
OriginalURL string `json:"-"`
|
||||
@@ -78,6 +89,36 @@ func (s Repositories) get(ctx context.Context, repo string) (*gitea.Repository,
|
||||
})
|
||||
}
|
||||
|
||||
// readmeNames are the README file names that Gitea shows, in order of preference.
|
||||
var readmeNames = []string{"readme.md", "readme.markdown", "readme", "readme.txt"}
|
||||
|
||||
// Readme returns the README in the top directory of the repository at ref: its file name and its
|
||||
// content, or "" when there is none.
|
||||
func (s Repositories) Readme(ctx context.Context, repo, ref string) (name, content string, err error) {
|
||||
entries, err := repoCall(ctx, s.Client, repo, func(ctx context.Context, c *gitea.Client, owner, name string) ([]*gitea.ContentsResponse, *gitea.Response, error) {
|
||||
return c.Repositories.ListContents(ctx, owner, name, ref, "")
|
||||
})
|
||||
if err != nil {
|
||||
if apiErr, ok := errors.AsType[*transport.APIError](err); ok && apiErr.Status == http.StatusNotFound {
|
||||
return "", "", nil
|
||||
}
|
||||
return "", "", err
|
||||
}
|
||||
rank := len(readmeNames)
|
||||
for _, entry := range entries {
|
||||
if i := slices.Index(readmeNames, strings.ToLower(entry.Name)); entry.Type == "file" && i >= 0 && i < rank {
|
||||
name, rank = entry.Name, i
|
||||
}
|
||||
}
|
||||
if name == "" {
|
||||
return "", "", nil
|
||||
}
|
||||
data, err := repoCall(ctx, s.Client, repo, func(ctx context.Context, c *gitea.Client, owner, repo string) ([]byte, *gitea.Response, error) {
|
||||
return c.Repositories.GetFile(ctx, owner, repo, ref, name)
|
||||
})
|
||||
return name, string(data), err
|
||||
}
|
||||
|
||||
// RepositoryPermissions holds server-side access flags used only for local decisions.
|
||||
// It is intentionally omitted from the stable Repository JSON schema.
|
||||
type RepositoryPermissions struct {
|
||||
|
||||
Reference in new issue
Block a user