diff options
author | ᴜɴᴋɴᴡᴏɴ <u@gogs.io> | 2020-03-10 22:15:55 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-10 22:15:55 +0800 |
commit | 880d0ec19f488001a90b3e370a992eaabac89e70 (patch) | |
tree | 97bcb926b3c94f56cc0367a7a405df1a2d6ad06a /internal/route/api | |
parent | 2430612ad4190fe81bfb8b64c92fe1883188f856 (diff) |
api: overhaul `/repos/owner/repos/contents` (#5980)
* Fix import path renaming
* api: overhaul /repos/owner/repos/contents
Diffstat (limited to 'internal/route/api')
-rw-r--r-- | internal/route/api/v1/api.go | 210 | ||||
-rw-r--r-- | internal/route/api/v1/repo/contents.go | 251 |
2 files changed, 220 insertions, 241 deletions
diff --git a/internal/route/api/v1/api.go b/internal/route/api/v1/api.go index afc50191..c0cdcaa5 100644 --- a/internal/route/api/v1/api.go +++ b/internal/route/api/v1/api.go @@ -5,11 +5,6 @@ package v1 import ( - admin2 "gogs.io/gogs/internal/route/api/v1/admin" - misc2 "gogs.io/gogs/internal/route/api/v1/misc" - org2 "gogs.io/gogs/internal/route/api/v1/org" - repo2 "gogs.io/gogs/internal/route/api/v1/repo" - user2 "gogs.io/gogs/internal/route/api/v1/user" "net/http" "strings" @@ -22,6 +17,11 @@ import ( "gogs.io/gogs/internal/db" "gogs.io/gogs/internal/db/errors" "gogs.io/gogs/internal/form" + "gogs.io/gogs/internal/route/api/v1/admin" + "gogs.io/gogs/internal/route/api/v1/misc" + "gogs.io/gogs/internal/route/api/v1/org" + "gogs.io/gogs/internal/route/api/v1/repo" + "gogs.io/gogs/internal/route/api/v1/user" ) // repoAssignment extracts information from URL parameters to retrieve the repository, @@ -176,229 +176,229 @@ func RegisterRoutes(m *macaron.Macaron) { m.Options("/*", func() {}) // Miscellaneous - m.Post("/markdown", bind(api.MarkdownOption{}), misc2.Markdown) - m.Post("/markdown/raw", misc2.MarkdownRaw) + m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown) + m.Post("/markdown/raw", misc.MarkdownRaw) // Users m.Group("/users", func() { - m.Get("/search", user2.Search) + m.Get("/search", user.Search) m.Group("/:username", func() { - m.Get("", user2.GetInfo) + m.Get("", user.GetInfo) m.Group("/tokens", func() { m.Combo(""). - Get(user2.ListAccessTokens). - Post(bind(api.CreateAccessTokenOption{}), user2.CreateAccessToken) + Get(user.ListAccessTokens). + Post(bind(api.CreateAccessTokenOption{}), user.CreateAccessToken) }, reqBasicAuth()) }) }) m.Group("/users", func() { m.Group("/:username", func() { - m.Get("/keys", user2.ListPublicKeys) + m.Get("/keys", user.ListPublicKeys) - m.Get("/followers", user2.ListFollowers) + m.Get("/followers", user.ListFollowers) m.Group("/following", func() { - m.Get("", user2.ListFollowing) - m.Get("/:target", user2.CheckFollowing) + m.Get("", user.ListFollowing) + m.Get("/:target", user.CheckFollowing) }) }) }, reqToken()) m.Group("/user", func() { - m.Get("", user2.GetAuthenticatedUser) + m.Get("", user.GetAuthenticatedUser) m.Combo("/emails"). - Get(user2.ListEmails). - Post(bind(api.CreateEmailOption{}), user2.AddEmail). - Delete(bind(api.CreateEmailOption{}), user2.DeleteEmail) + Get(user.ListEmails). + Post(bind(api.CreateEmailOption{}), user.AddEmail). + Delete(bind(api.CreateEmailOption{}), user.DeleteEmail) - m.Get("/followers", user2.ListMyFollowers) + m.Get("/followers", user.ListMyFollowers) m.Group("/following", func() { - m.Get("", user2.ListMyFollowing) + m.Get("", user.ListMyFollowing) m.Combo("/:username"). - Get(user2.CheckMyFollowing). - Put(user2.Follow). - Delete(user2.Unfollow) + Get(user.CheckMyFollowing). + Put(user.Follow). + Delete(user.Unfollow) }) m.Group("/keys", func() { m.Combo(""). - Get(user2.ListMyPublicKeys). - Post(bind(api.CreateKeyOption{}), user2.CreatePublicKey) + Get(user.ListMyPublicKeys). + Post(bind(api.CreateKeyOption{}), user.CreatePublicKey) m.Combo("/:id"). - Get(user2.GetPublicKey). - Delete(user2.DeletePublicKey) + Get(user.GetPublicKey). + Delete(user.DeletePublicKey) }) - m.Get("/issues", repo2.ListUserIssues) + m.Get("/issues", repo.ListUserIssues) }, reqToken()) // Repositories - m.Get("/users/:username/repos", reqToken(), repo2.ListUserRepositories) - m.Get("/orgs/:org/repos", reqToken(), repo2.ListOrgRepositories) + m.Get("/users/:username/repos", reqToken(), repo.ListUserRepositories) + m.Get("/orgs/:org/repos", reqToken(), repo.ListOrgRepositories) m.Combo("/user/repos", reqToken()). - Get(repo2.ListMyRepos). - Post(bind(api.CreateRepoOption{}), repo2.Create) - m.Post("/org/:org/repos", reqToken(), bind(api.CreateRepoOption{}), repo2.CreateOrgRepo) + Get(repo.ListMyRepos). + Post(bind(api.CreateRepoOption{}), repo.Create) + m.Post("/org/:org/repos", reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo) m.Group("/repos", func() { - m.Get("/search", repo2.Search) + m.Get("/search", repo.Search) - m.Get("/:username/:reponame", repoAssignment(), repo2.Get) + m.Get("/:username/:reponame", repoAssignment(), repo.Get) }) m.Group("/repos", func() { - m.Post("/migrate", bind(form.MigrateRepo{}), repo2.Migrate) - m.Delete("/:username/:reponame", repoAssignment(), repo2.Delete) + m.Post("/migrate", bind(form.MigrateRepo{}), repo.Migrate) + m.Delete("/:username/:reponame", repoAssignment(), repo.Delete) m.Group("/:username/:reponame", func() { m.Group("/hooks", func() { m.Combo(""). - Get(repo2.ListHooks). - Post(bind(api.CreateHookOption{}), repo2.CreateHook) + Get(repo.ListHooks). + Post(bind(api.CreateHookOption{}), repo.CreateHook) m.Combo("/:id"). - Patch(bind(api.EditHookOption{}), repo2.EditHook). - Delete(repo2.DeleteHook) + Patch(bind(api.EditHookOption{}), repo.EditHook). + Delete(repo.DeleteHook) }, reqRepoAdmin()) m.Group("/collaborators", func() { - m.Get("", repo2.ListCollaborators) + m.Get("", repo.ListCollaborators) m.Combo("/:collaborator"). - Get(repo2.IsCollaborator). - Put(bind(api.AddCollaboratorOption{}), repo2.AddCollaborator). - Delete(repo2.DeleteCollaborator) + Get(repo.IsCollaborator). + Put(bind(api.AddCollaboratorOption{}), repo.AddCollaborator). + Delete(repo.DeleteCollaborator) }, reqRepoAdmin()) - m.Get("/raw/*", context.RepoRef(), repo2.GetRawFile) - m.Get("/contents/*", context.RepoRef(), repo2.GetContents) - m.Get("/archive/*", repo2.GetArchive) + m.Get("/raw/*", context.RepoRef(), repo.GetRawFile) + m.Get("/contents/*", repo.GetContents) + m.Get("/archive/*", repo.GetArchive) m.Group("/git/trees", func() { - m.Get("/:sha", context.RepoRef(), repo2.GetRepoGitTree) + m.Get("/:sha", context.RepoRef(), repo.GetRepoGitTree) }) - m.Get("/forks", repo2.ListForks) + m.Get("/forks", repo.ListForks) m.Group("/branches", func() { - m.Get("", repo2.ListBranches) - m.Get("/*", repo2.GetBranch) + m.Get("", repo.ListBranches) + m.Get("/*", repo.GetBranch) }) m.Group("/commits", func() { - m.Get("/:sha", repo2.GetSingleCommit) - m.Get("/*", repo2.GetReferenceSHA) + m.Get("/:sha", repo.GetSingleCommit) + m.Get("/*", repo.GetReferenceSHA) }) m.Group("/keys", func() { m.Combo(""). - Get(repo2.ListDeployKeys). - Post(bind(api.CreateKeyOption{}), repo2.CreateDeployKey) + Get(repo.ListDeployKeys). + Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey) m.Combo("/:id"). - Get(repo2.GetDeployKey). - Delete(repo2.DeleteDeploykey) + Get(repo.GetDeployKey). + Delete(repo.DeleteDeploykey) }, reqRepoAdmin()) m.Group("/issues", func() { m.Combo(""). - Get(repo2.ListIssues). - Post(bind(api.CreateIssueOption{}), repo2.CreateIssue) + Get(repo.ListIssues). + Post(bind(api.CreateIssueOption{}), repo.CreateIssue) m.Group("/comments", func() { - m.Get("", repo2.ListRepoIssueComments) - m.Patch("/:id", bind(api.EditIssueCommentOption{}), repo2.EditIssueComment) + m.Get("", repo.ListRepoIssueComments) + m.Patch("/:id", bind(api.EditIssueCommentOption{}), repo.EditIssueComment) }) m.Group("/:index", func() { m.Combo(""). - Get(repo2.GetIssue). - Patch(bind(api.EditIssueOption{}), repo2.EditIssue) + Get(repo.GetIssue). + Patch(bind(api.EditIssueOption{}), repo.EditIssue) m.Group("/comments", func() { m.Combo(""). - Get(repo2.ListIssueComments). - Post(bind(api.CreateIssueCommentOption{}), repo2.CreateIssueComment) + Get(repo.ListIssueComments). + Post(bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment) m.Combo("/:id"). - Patch(bind(api.EditIssueCommentOption{}), repo2.EditIssueComment). - Delete(repo2.DeleteIssueComment) + Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment). + Delete(repo.DeleteIssueComment) }) - m.Get("/labels", repo2.ListIssueLabels) + m.Get("/labels", repo.ListIssueLabels) m.Group("/labels", func() { m.Combo(""). - Post(bind(api.IssueLabelsOption{}), repo2.AddIssueLabels). - Put(bind(api.IssueLabelsOption{}), repo2.ReplaceIssueLabels). - Delete(repo2.ClearIssueLabels) - m.Delete("/:id", repo2.DeleteIssueLabel) + Post(bind(api.IssueLabelsOption{}), repo.AddIssueLabels). + Put(bind(api.IssueLabelsOption{}), repo.ReplaceIssueLabels). + Delete(repo.ClearIssueLabels) + m.Delete("/:id", repo.DeleteIssueLabel) }, reqRepoWriter()) }) }, mustEnableIssues) m.Group("/labels", func() { - m.Get("", repo2.ListLabels) - m.Get("/:id", repo2.GetLabel) + m.Get("", repo.ListLabels) + m.Get("/:id", repo.GetLabel) }) m.Group("/labels", func() { - m.Post("", bind(api.CreateLabelOption{}), repo2.CreateLabel) + m.Post("", bind(api.CreateLabelOption{}), repo.CreateLabel) m.Combo("/:id"). - Patch(bind(api.EditLabelOption{}), repo2.EditLabel). - Delete(repo2.DeleteLabel) + Patch(bind(api.EditLabelOption{}), repo.EditLabel). + Delete(repo.DeleteLabel) }, reqRepoWriter()) m.Group("/milestones", func() { - m.Get("", repo2.ListMilestones) - m.Get("/:id", repo2.GetMilestone) + m.Get("", repo.ListMilestones) + m.Get("/:id", repo.GetMilestone) }) m.Group("/milestones", func() { - m.Post("", bind(api.CreateMilestoneOption{}), repo2.CreateMilestone) + m.Post("", bind(api.CreateMilestoneOption{}), repo.CreateMilestone) m.Combo("/:id"). - Patch(bind(api.EditMilestoneOption{}), repo2.EditMilestone). - Delete(repo2.DeleteMilestone) + Patch(bind(api.EditMilestoneOption{}), repo.EditMilestone). + Delete(repo.DeleteMilestone) }, reqRepoWriter()) - m.Patch("/issue-tracker", reqRepoWriter(), bind(api.EditIssueTrackerOption{}), repo2.IssueTracker) - m.Post("/mirror-sync", reqRepoWriter(), repo2.MirrorSync) - m.Get("/editorconfig/:filename", context.RepoRef(), repo2.GetEditorconfig) + m.Patch("/issue-tracker", reqRepoWriter(), bind(api.EditIssueTrackerOption{}), repo.IssueTracker) + m.Post("/mirror-sync", reqRepoWriter(), repo.MirrorSync) + m.Get("/editorconfig/:filename", context.RepoRef(), repo.GetEditorconfig) }, repoAssignment()) }, reqToken()) - m.Get("/issues", reqToken(), repo2.ListUserIssues) + m.Get("/issues", reqToken(), repo.ListUserIssues) // Organizations m.Combo("/user/orgs", reqToken()). - Get(org2.ListMyOrgs). - Post(bind(api.CreateOrgOption{}), org2.CreateMyOrg) + Get(org.ListMyOrgs). + Post(bind(api.CreateOrgOption{}), org.CreateMyOrg) - m.Get("/users/:username/orgs", org2.ListUserOrgs) + m.Get("/users/:username/orgs", org.ListUserOrgs) m.Group("/orgs/:orgname", func() { m.Combo(""). - Get(org2.Get). - Patch(bind(api.EditOrgOption{}), org2.Edit) - m.Get("/teams", org2.ListTeams) + Get(org.Get). + Patch(bind(api.EditOrgOption{}), org.Edit) + m.Get("/teams", org.ListTeams) }, orgAssignment(true)) m.Group("/admin", func() { m.Group("/users", func() { - m.Post("", bind(api.CreateUserOption{}), admin2.CreateUser) + m.Post("", bind(api.CreateUserOption{}), admin.CreateUser) m.Group("/:username", func() { m.Combo(""). - Patch(bind(api.EditUserOption{}), admin2.EditUser). - Delete(admin2.DeleteUser) - m.Post("/keys", bind(api.CreateKeyOption{}), admin2.CreatePublicKey) - m.Post("/orgs", bind(api.CreateOrgOption{}), admin2.CreateOrg) - m.Post("/repos", bind(api.CreateRepoOption{}), admin2.CreateRepo) + Patch(bind(api.EditUserOption{}), admin.EditUser). + Delete(admin.DeleteUser) + m.Post("/keys", bind(api.CreateKeyOption{}), admin.CreatePublicKey) + m.Post("/orgs", bind(api.CreateOrgOption{}), admin.CreateOrg) + m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo) }) }) m.Group("/orgs/:orgname", func() { m.Group("/teams", func() { - m.Post("", orgAssignment(true), bind(api.CreateTeamOption{}), admin2.CreateTeam) + m.Post("", orgAssignment(true), bind(api.CreateTeamOption{}), admin.CreateTeam) }) }) m.Group("/teams", func() { m.Group("/:teamid", func() { m.Combo("/members/:username"). - Put(admin2.AddTeamMember). - Delete(admin2.RemoveTeamMember) + Put(admin.AddTeamMember). + Delete(admin.RemoveTeamMember) m.Combo("/repos/:reponame"). - Put(admin2.AddTeamRepository). - Delete(admin2.RemoveTeamRepository) + Put(admin.AddTeamRepository). + Delete(admin.RemoveTeamRepository) }, orgAssignment(false, true)) }) }, reqAdmin()) diff --git a/internal/route/api/v1/repo/contents.go b/internal/route/api/v1/repo/contents.go index 40303921..e5a9277d 100644 --- a/internal/route/api/v1/repo/contents.go +++ b/internal/route/api/v1/repo/contents.go @@ -7,128 +7,141 @@ package repo import ( "encoding/base64" "fmt" + "path" + + "github.com/gogs/git-module" + "github.com/pkg/errors" "gogs.io/gogs/internal/context" "gogs.io/gogs/internal/gitutil" ) -type repoContent struct { - Type string `json:"type"` - Target string `json:"target,omitempty"` - SubmoduleGitURL string `json:"submodule_git_url,omitempty"` - Encoding string `json:"encoding,omitempty"` - Size int64 `json:"size"` - Name string `json:"name"` - Path string `json:"path"` - Content string `json:"content,omitempty"` - Sha string `json:"sha"` - URL string `json:"url"` - GitURL string `json:"git_url"` - HTMLURL string `json:"html_url"` - DownloadURL string `json:"download_url"` - Links Links `json:"_links"` -} +func GetContents(c *context.APIContext) { + gitRepo, err := git.Open(c.Repo.Repository.RepoPath()) + if err != nil { + c.ServerError("open repository", err) + return + } -type Links struct { - Git string `json:"git"` - Self string `json:"self"` - HTML string `json:"html"` -} + ref := c.Query("ref") + if ref == "" { + ref = c.Repo.Repository.DefaultBranch + } -func GetContents(c *context.APIContext) { - treeEntry, err := c.Repo.Commit.TreeEntry(c.Repo.TreePath) + commit, err := gitRepo.CatFileCommit(ref) + if err != nil { + c.NotFoundOrServerError("get commit", gitutil.IsErrRevisionNotExist, err) + return + } + + treePath := c.Params("*") + entry, err := commit.TreeEntry(treePath) if err != nil { c.NotFoundOrServerError("get tree entry", gitutil.IsErrRevisionNotExist, err) return } - username := c.Params(":username") - reponame := c.Params(":reponame") - - // TODO: figure out the best way to do this - // :base-url/:username/:project/raw/:refs/:path - templateDownloadURL := "%s/%s/%s/raw/%s" - // :base-url/repos/:username/:project/contents/:path - templateSelfLink := "%s/repos/%s/%s/contents/%s" - // :baseurl/repos/:username/:project/git/trees/:sha - templateGitURLLink := "%s/repos/%s/%s/trees/%s" - // :baseurl/repos/:username/:project/tree/:sha - templateHTMLLLink := "%s/repos/%s/%s/tree/%s" - - gitURL := fmt.Sprintf(templateGitURLLink, c.BaseURL, username, reponame, treeEntry.ID().String()) - htmlURL := fmt.Sprintf(templateHTMLLLink, c.BaseURL, username, reponame, treeEntry.ID().String()) - selfURL := fmt.Sprintf(templateSelfLink, c.BaseURL, username, reponame, c.Repo.TreePath) - - // TODO(unknwon): Make a treeEntryToRepoContent helper. - contents := &repoContent{ - Size: treeEntry.Size(), - Name: treeEntry.Name(), - Path: c.Repo.TreePath, - Sha: treeEntry.ID().String(), - URL: selfURL, - GitURL: gitURL, - HTMLURL: htmlURL, - DownloadURL: fmt.Sprintf(templateDownloadURL, c.BaseURL, username, reponame, c.Repo.TreePath), - Links: Links{ - Git: gitURL, - Self: selfURL, - HTML: htmlURL, - }, + + type links struct { + Git string `json:"git"` + Self string `json:"self"` + HTML string `json:"html"` + } + type repoContent struct { + Type string `json:"type"` + Target string `json:"target,omitempty"` + SubmoduleGitURL string `json:"submodule_git_url,omitempty"` + Encoding string `json:"encoding,omitempty"` + Size int64 `json:"size"` + Name string `json:"name"` + Path string `json:"path"` + Content string `json:"content,omitempty"` + Sha string `json:"sha"` + URL string `json:"url"` + GitURL string `json:"git_url"` + HTMLURL string `json:"html_url"` + DownloadURL string `json:"download_url"` + Links links `json:"_links"` } - // A tree entry can only be one of the following types: - // 1. Tree (directory) - // 2. SubModule - // 3. SymLink - // 4. Blob (file) - if treeEntry.IsCommit() { - // TODO(unknwon): submoduleURL is not set as current git-module doesn't handle it properly - contents.Type = "submodule" - c.JSONSuccess(contents) - return + toRepoContent := func(subpath string, entry *git.TreeEntry) (*repoContent, error) { + repoURL := fmt.Sprintf("%s/repos/%s/%s", c.BaseURL, c.Params(":username"), c.Params(":reponame")) + selfURL := fmt.Sprintf("%s/contents/%s", repoURL, subpath) + htmlURL := fmt.Sprintf("%s/src/%s/%s", c.Repo.Repository.HTMLURL(), ref, entry.Name()) + downloadURL := fmt.Sprintf("%s/raw/%s/%s", c.Repo.Repository.HTMLURL(), ref, entry.Name()) - } else if treeEntry.IsSymlink() { - contents.Type = "symlink" - blob, err := c.Repo.Commit.Blob(c.Repo.TreePath) - if err != nil { - c.ServerError("GetBlobByPath", err) - return - } - p, err := blob.Bytes() - if err != nil { - c.ServerError("Data", err) - return + content := &repoContent{ + Size: entry.Size(), + Name: entry.Name(), + Path: subpath, + Sha: entry.ID().String(), + URL: selfURL, + HTMLURL: htmlURL, + DownloadURL: downloadURL, + Links: links{ + Self: selfURL, + HTML: htmlURL, + }, } - contents.Target = string(p) - c.JSONSuccess(contents) - return - } else if treeEntry.IsBlob() { - blob, err := c.Repo.Commit.Blob(c.Repo.TreePath) - if err != nil { - c.ServerError("GetBlobByPath", err) - return + switch { + case entry.IsBlob(), entry.IsExec(): + content.Type = "file" + p, err := entry.Blob().Bytes() + if err != nil { + return nil, errors.Wrap(err, "get blob content") + } + content.Encoding = "base64" + content.Content = base64.StdEncoding.EncodeToString(p) + content.GitURL = fmt.Sprintf("%s/git/blobs/%s", repoURL, entry.ID().String()) + + case entry.IsTree(): + content.Type = "dir" + content.GitURL = fmt.Sprintf("%s/git/trees/%s", repoURL, entry.ID().String()) + + case entry.IsSymlink(): + content.Type = "symlink" + p, err := entry.Blob().Bytes() + if err != nil { + return nil, errors.Wrap(err, "get blob content") + } + content.Target = string(p) + + case entry.IsCommit(): + content.Type = "submodule" + mod, err := commit.Submodule(subpath) + if err != nil { + return nil, errors.Wrap(err, "get submodule") + } + content.SubmoduleGitURL = mod.URL + + default: + panic("unreachable") } - p, err := blob.Bytes() + + content.Links.Git = content.GitURL + + return content, nil + } + + if !entry.IsTree() { + content, err := toRepoContent(treePath, entry) if err != nil { - c.ServerError("Data", err) + c.Errorf(err, "convert %q to repoContent", treePath) return } - contents.Content = base64.StdEncoding.EncodeToString(p) - contents.Type = "file" - c.JSONSuccess(contents) + + c.JSONSuccess(content) return } - // TODO: treeEntry.IsExec() - - // treeEntry is a directory - dirTree, err := c.Repo.GitRepo.LsTree(treeEntry.ID().String()) + // The entry is a directory + dir, err := gitRepo.LsTree(entry.ID().String()) if err != nil { c.NotFoundOrServerError("get tree", gitutil.IsErrRevisionNotExist, err) return } - entries, err := dirTree.Entries() + entries, err := dir.Entries() if err != nil { c.NotFoundOrServerError("list entries", gitutil.IsErrRevisionNotExist, err) return @@ -139,50 +152,16 @@ func GetContents(c *context.APIContext) { return } - var results = make([]*repoContent, 0, len(entries)) + contents := make([]*repoContent, 0, len(entries)) for _, entry := range entries { - gitURL := fmt.Sprintf(templateGitURLLink, c.BaseURL, username, reponame, entry.ID().String()) - htmlURL := fmt.Sprintf(templateHTMLLLink, c.BaseURL, username, reponame, entry.ID().String()) - selfURL := fmt.Sprintf(templateSelfLink, c.BaseURL, username, reponame, c.Repo.TreePath) - var contentType string - if entry.IsTree() { - contentType = "dir" - } else if entry.IsCommit() { - // TODO(unknwon): submoduleURL is not set as current git-module doesn't handle it properly - contentType = "submodule" - } else if entry.IsSymlink() { - contentType = "symlink" - blob, err := c.Repo.Commit.Blob(c.Repo.TreePath) - if err != nil { - c.ServerError("GetBlobByPath", err) - return - } - p, err := blob.Bytes() - if err != nil { - c.ServerError("Data", err) - return - } - contents.Target = string(p) - } else { - contentType = "file" + subpath := path.Join(treePath, entry.Name()) + content, err := toRepoContent(subpath, entry) + if err != nil { + c.Errorf(err, "convert %q to repoContent", subpath) + return } - results = append(results, &repoContent{ - Type: contentType, - Size: entry.Size(), - Name: entry.Name(), - Path: c.Repo.TreePath, - Sha: entry.ID().String(), - URL: selfURL, - GitURL: gitURL, - HTMLURL: htmlURL, - DownloadURL: fmt.Sprintf(templateDownloadURL, c.BaseURL, username, reponame, c.Repo.TreePath), - Links: Links{ - Git: gitURL, - Self: selfURL, - HTML: htmlURL, - }, - }) + contents = append(contents, content) } - c.JSONSuccess(results) + c.JSONSuccess(contents) } |