1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-22 18:28:37 +00:00

Refactor repo contents API and add "contents-ext" API (#34822)

See the updated swagger document for details.
This commit is contained in:
wxiaoguang
2025-06-25 10:34:21 +08:00
committed by GitHub
parent 7be1a5e585
commit dbd9c69909
18 changed files with 481 additions and 262 deletions

View File

@@ -905,11 +905,71 @@ func resolveRefCommit(ctx *context.APIContext, ref string, minCommitIDLen ...int
return refCommit
}
func GetContentsExt(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/contents-ext/{filepath} repository repoGetContentsExt
// ---
// summary: The extended "contents" API, to get file metadata and/or content, or list a directory.
// description: It guarantees that only one of the response fields is set if the request succeeds.
// Users can pass "includes=file_content" or "includes=lfs_metadata" to retrieve more fields.
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repo
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo
// type: string
// required: true
// - name: filepath
// in: path
// description: path of the dir, file, symlink or submodule in the repo
// type: string
// required: true
// - name: ref
// in: query
// description: the name of the commit/branch/tag, default to the repositorys default branch.
// type: string
// required: false
// - name: includes
// in: query
// description: By default this API's response only contains file's metadata. Use comma-separated "includes" options to retrieve more fields.
// Option "file_content" will try to retrieve the file content, option "lfs_metadata" will try to retrieve LFS metadata.
// type: string
// required: false
// responses:
// "200":
// "$ref": "#/responses/ContentsExtResponse"
// "404":
// "$ref": "#/responses/notFound"
opts := files_service.GetContentsOrListOptions{TreePath: ctx.PathParam("*")}
for includeOpt := range strings.SplitSeq(ctx.FormString("includes"), ",") {
if includeOpt == "" {
continue
}
switch includeOpt {
case "file_content":
opts.IncludeSingleFileContent = true
case "lfs_metadata":
opts.IncludeLfsMetadata = true
default:
ctx.APIError(http.StatusBadRequest, fmt.Sprintf("unknown include option %q", includeOpt))
return
}
}
ctx.JSON(http.StatusOK, getRepoContents(ctx, opts))
}
// GetContents Get the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir
func GetContents(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/contents/{filepath} repository repoGetContents
// ---
// summary: Gets the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir
// summary: Gets the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir.
// description: This API follows GitHub's design, and it is not easy to use. Recommend to use our "contents-ext" API instead.
// produces:
// - application/json
// parameters:
@@ -938,29 +998,35 @@ func GetContents(ctx *context.APIContext) {
// "$ref": "#/responses/ContentsResponse"
// "404":
// "$ref": "#/responses/notFound"
treePath := ctx.PathParam("*")
refCommit := resolveRefCommit(ctx, ctx.FormTrim("ref"))
ret := getRepoContents(ctx, files_service.GetContentsOrListOptions{TreePath: ctx.PathParam("*"), IncludeSingleFileContent: true})
if ctx.Written() {
return
}
ctx.JSON(http.StatusOK, util.Iif[any](ret.FileContents != nil, ret.FileContents, ret.DirContents))
}
if fileList, err := files_service.GetContentsOrList(ctx, ctx.Repo.Repository, refCommit, treePath); err != nil {
func getRepoContents(ctx *context.APIContext, opts files_service.GetContentsOrListOptions) *api.ContentsExtResponse {
refCommit := resolveRefCommit(ctx, ctx.FormTrim("ref"))
if ctx.Written() {
return nil
}
ret, err := files_service.GetContentsOrList(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, refCommit, opts)
if err != nil {
if git.IsErrNotExist(err) {
ctx.APIErrorNotFound("GetContentsOrList", err)
return
return nil
}
ctx.APIErrorInternal(err)
} else {
ctx.JSON(http.StatusOK, fileList)
}
return &ret
}
// GetContentsList Get the metadata of all the entries of the root dir
func GetContentsList(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/contents repository repoGetContentsList
// ---
// summary: Gets the metadata of all the entries of the root dir
// summary: Gets the metadata of all the entries of the root dir.
// description: This API follows GitHub's design, and it is not easy to use. Recommend to use our "contents-ext" API instead.
// produces:
// - application/json
// parameters:
@@ -1084,6 +1150,6 @@ func handleGetFileContents(ctx *context.APIContext) {
if ctx.Written() {
return
}
filesResponse := files_service.GetContentsListFromTreePaths(ctx, ctx.Repo.Repository, refCommit, opts.Files)
filesResponse := files_service.GetContentsListFromTreePaths(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, refCommit, opts.Files)
ctx.JSON(http.StatusOK, util.SliceNilAsEmpty(filesResponse))
}