1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo.git synced 2025-01-20 16:50:28 -05:00

refactor: cleanup wiki path

This commit is contained in:
Snoweuph 2025-01-19 14:39:45 +01:00
parent 6b2f67ea01
commit 33470c35c3
No known key found for this signature in database
GPG key ID: BEFC41DA223CEC55
8 changed files with 113 additions and 87 deletions

View file

@ -301,3 +301,6 @@ code.gitea.io/gitea/services/repository/files
code.gitea.io/gitea/services/webhook code.gitea.io/gitea/services/webhook
NewNotifier NewNotifier
code.gitea.io/gitea/services/wiki
WebPathToPath

View file

@ -92,7 +92,7 @@ func NewWikiPage(ctx *context.APIContext) {
wikiPage := getWikiPage(ctx, wikiName) wikiPage := getWikiPage(ctx, wikiName)
if !ctx.Written() { if !ctx.Written() {
notify_service.NewWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, string(wikiName.WebPath()), form.Message) notify_service.NewWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName.GitPath(), form.Message)
ctx.JSON(http.StatusCreated, wikiPage) ctx.JSON(http.StatusCreated, wikiPage)
} }
} }
@ -143,7 +143,7 @@ func EditWikiPage(ctx *context.APIContext) {
oldWikiName := wiki_service.RequestToPath(ctx.PathParamRaw(":pageName")) oldWikiName := wiki_service.RequestToPath(ctx.PathParamRaw(":pageName"))
newWikiName := wiki_service.TitleToPath(form.Title) newWikiName := wiki_service.TitleToPath(form.Title)
if len(newWikiName.WebPath()) == 0 { if newWikiName.IsEmpty() {
newWikiName = oldWikiName newWikiName = oldWikiName
} }
@ -166,7 +166,7 @@ func EditWikiPage(ctx *context.APIContext) {
wikiPage := getWikiPage(ctx, newWikiName) wikiPage := getWikiPage(ctx, newWikiName)
if !ctx.Written() { if !ctx.Written() {
notify_service.EditWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, string(newWikiName.WebPath()), form.Message) notify_service.EditWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, newWikiName.GitPath(), form.Message)
ctx.JSON(http.StatusOK, wikiPage) ctx.JSON(http.StatusOK, wikiPage)
} }
} }
@ -186,12 +186,12 @@ func getWikiPage(ctx *context.APIContext, wikiName wiki_service.Path) *api.WikiP
return nil return nil
} }
sidebarContent, _ := wikiContentsByName(ctx, commit, wiki_service.TitleToPath("_Sidebar"), true) sidebarContent, _ := wikiContentsByName(ctx, commit, wiki_service.SidebarPath(), true)
if ctx.Written() { if ctx.Written() {
return nil return nil
} }
footerContent, _ := wikiContentsByName(ctx, commit, wiki_service.TitleToPath("_Footer"), true) footerContent, _ := wikiContentsByName(ctx, commit, wiki_service.FooterPath(), true)
if ctx.Written() { if ctx.Written() {
return nil return nil
} }
@ -257,7 +257,7 @@ func DeleteWikiPage(ctx *context.APIContext) {
return return
} }
notify_service.DeleteWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, string(wikiName.WebPath())) notify_service.DeleteWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName.GitPath())
ctx.Status(http.StatusNoContent) ctx.Status(http.StatusNoContent)
} }
@ -329,7 +329,7 @@ func ListWikiPages(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "GetCommit", err) ctx.Error(http.StatusInternalServerError, "GetCommit", err)
return return
} }
wikiName, err := wiki_service.GitPathToPath(wiki_service.GitPath(entry.Name())) wikiName, err := wiki_service.GitPathToPath(entry.Name())
if err != nil { if err != nil {
if repo_model.IsErrWikiInvalidFileName(err) { if repo_model.IsErrWikiInvalidFileName(err) {
continue continue
@ -425,8 +425,8 @@ func ListPageRevisions(ctx *context.APIContext) {
// get requested pagename // get requested pagename
pageName := wiki_service.RequestToPath(ctx.PathParamRaw(":pageName")) pageName := wiki_service.RequestToPath(ctx.PathParamRaw(":pageName"))
if len(pageName.WebPath()) == 0 { if pageName.IsEmpty() {
pageName = wiki_service.WebPathToPath("Home") pageName = wiki_service.HomePath()
} }
// lookup filename in wiki - get filecontent, gitTree entry , real filename // lookup filename in wiki - get filecontent, gitTree entry , real filename
@ -521,7 +521,7 @@ func wikiContentsByEntry(ctx *context.APIContext, entry *git.TreeEntry) string {
// indicating whether the page exists. Writes to ctx if an error occurs. // indicating whether the page exists. Writes to ctx if an error occurs.
func wikiContentsByName(ctx *context.APIContext, commit *git.Commit, wikiName wiki_service.Path, isSidebarOrFooter bool) (string, string) { func wikiContentsByName(ctx *context.APIContext, commit *git.Commit, wikiName wiki_service.Path, isSidebarOrFooter bool) (string, string) {
gitFilename := wikiName.GitPath() gitFilename := wikiName.GitPath()
entry, err := findEntryForFile(commit, string(gitFilename)) entry, err := findEntryForFile(commit, gitFilename)
if err != nil { if err != nil {
if git.IsErrNotExist(err) { if git.IsErrNotExist(err) {
if !isSidebarOrFooter { if !isSidebarOrFooter {
@ -532,5 +532,5 @@ func wikiContentsByName(ctx *context.APIContext, commit *git.Commit, wikiName wi
} }
return "", "" return "", ""
} }
return wikiContentsByEntry(ctx, entry), string(gitFilename) return wikiContentsByEntry(ctx, entry), gitFilename
} }

View file

@ -129,14 +129,14 @@ func wikiContentsByEntry(ctx *context.Context, entry *git.TreeEntry) []byte {
// indicating whether the page exists. Writes to ctx if an error occurs. // indicating whether the page exists. Writes to ctx if an error occurs.
func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.Path) ([]byte, *git.TreeEntry, string, bool) { func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.Path) ([]byte, *git.TreeEntry, string, bool) {
gitFilename := wikiName.GitPath() gitFilename := wikiName.GitPath()
entry, err := findEntryForFile(commit, string(gitFilename)) entry, err := findEntryForFile(commit, gitFilename)
if err != nil && !git.IsErrNotExist(err) { if err != nil && !git.IsErrNotExist(err) {
ctx.ServerError("findEntryForFile", err) ctx.ServerError("findEntryForFile", err)
return nil, nil, "", false return nil, nil, "", false
} else if entry == nil { } else if entry == nil {
return nil, nil, "", true return nil, nil, "", true
} }
return wikiContentsByEntry(ctx, entry), entry, string(gitFilename), false return wikiContentsByEntry(ctx, entry), entry, gitFilename, false
} }
func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
@ -165,7 +165,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
if !entry.IsRegular() { if !entry.IsRegular() {
continue continue
} }
wikiName, err := wiki_service.GitPathToPath(wiki_service.GitPath(entry.Name())) wikiName, err := wiki_service.GitPathToPath(entry.Name())
if err != nil { if err != nil {
if repo_model.IsErrWikiInvalidFileName(err) { if repo_model.IsErrWikiInvalidFileName(err) {
continue continue
@ -175,13 +175,13 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
} }
ctx.ServerError("WikiFilenameToName", err) ctx.ServerError("WikiFilenameToName", err)
return nil, nil return nil, nil
} else if wikiName.WebPath() == "_Sidebar" || wikiName.WebPath() == "_Footer" { } else if wikiName.IsSidebar() || wikiName.IsFooter() {
continue continue
} }
_, displayName := wikiName.DisplayName() _, displayName := wikiName.DisplayName()
pages = append(pages, PageMeta{ pages = append(pages, PageMeta{
Name: displayName, Name: displayName,
SubURL: string(wikiName.URLPath()), SubURL: wikiName.URLPath(),
GitEntryName: entry.Name(), GitEntryName: entry.Name(),
}) })
} }
@ -189,8 +189,8 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
// get requested page name // get requested page name
pageName := wiki_service.RequestToPath(ctx.PathParamRaw("*")) pageName := wiki_service.RequestToPath(ctx.PathParamRaw("*"))
if len(pageName.WebPath()) == 0 { if pageName.IsEmpty() {
pageName = wiki_service.WebPathToPath("Home") pageName = wiki_service.HomePath()
} }
_, displayName := pageName.DisplayName() _, displayName := pageName.DisplayName()
@ -199,8 +199,8 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
ctx.Data["Title"] = displayName ctx.Data["Title"] = displayName
ctx.Data["title"] = displayName ctx.Data["title"] = displayName
isSideBar := pageName.WebPath() == "_Sidebar" isSideBar := pageName.IsSidebar()
isFooter := pageName.WebPath() == "_Footer" isFooter := pageName.IsFooter()
// lookup filename in wiki - get filecontent, gitTree entry , real filename // lookup filename in wiki - get filecontent, gitTree entry , real filename
data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName) data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
@ -216,7 +216,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
var sidebarContent []byte var sidebarContent []byte
if !isSideBar { if !isSideBar {
sidebarContent, _, _, _ = wikiContentsByName(ctx, commit, wiki_service.WebPathToPath("_Sidebar")) sidebarContent, _, _, _ = wikiContentsByName(ctx, commit, wiki_service.SidebarPath())
if ctx.Written() { if ctx.Written() {
if wikiRepo != nil { if wikiRepo != nil {
wikiRepo.Close() wikiRepo.Close()
@ -229,7 +229,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
var footerContent []byte var footerContent []byte
if !isFooter { if !isFooter {
footerContent, _, _, _ = wikiContentsByName(ctx, commit, wiki_service.WebPathToPath("_Footer")) footerContent, _, _, _ = wikiContentsByName(ctx, commit, wiki_service.FooterPath())
if ctx.Written() { if ctx.Written() {
if wikiRepo != nil { if wikiRepo != nil {
wikiRepo.Close() wikiRepo.Close()
@ -338,8 +338,8 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
// get requested pagename // get requested pagename
pageName := wiki_service.RequestToPath(ctx.PathParamRaw("*")) pageName := wiki_service.RequestToPath(ctx.PathParamRaw("*"))
if len(pageName.WebPath()) == 0 { if pageName.IsEmpty() {
pageName = wiki_service.WebPathToPath("Home") pageName = wiki_service.HomePath()
} }
_, displayName := pageName.DisplayName() _, displayName := pageName.DisplayName()
@ -422,8 +422,8 @@ func renderEditPage(ctx *context.Context) {
// get requested pagename // get requested pagename
pageName := wiki_service.RequestToPath(ctx.PathParamRaw("*")) pageName := wiki_service.RequestToPath(ctx.PathParamRaw("*"))
if len(pageName.WebPath()) == 0 { if pageName.IsEmpty() {
pageName = wiki_service.WebPathToPath("Home") pageName = wiki_service.HomePath()
} }
_, displayName := pageName.DisplayName() _, displayName := pageName.DisplayName()
@ -627,7 +627,7 @@ func WikiPages(ctx *context.Context) {
if !entry.Entry.IsRegular() { if !entry.Entry.IsRegular() {
continue continue
} }
wikiName, err := wiki_service.GitPathToPath(wiki_service.GitPath(entry.Entry.Name())) wikiName, err := wiki_service.GitPathToPath(entry.Entry.Name())
if err != nil { if err != nil {
if repo_model.IsErrWikiInvalidFileName(err) { if repo_model.IsErrWikiInvalidFileName(err) {
continue continue
@ -638,7 +638,7 @@ func WikiPages(ctx *context.Context) {
_, displayName := wikiName.DisplayName() _, displayName := wikiName.DisplayName()
pages = append(pages, PageMeta{ pages = append(pages, PageMeta{
Name: displayName, Name: displayName,
SubURL: string(wikiName.URLPath()), SubURL: wikiName.URLPath(),
GitEntryName: entry.Entry.Name(), GitEntryName: entry.Entry.Name(),
UpdatedUnix: timeutil.TimeStamp(entry.Commit.Author.When.Unix()), UpdatedUnix: timeutil.TimeStamp(entry.Commit.Author.When.Unix()),
}) })
@ -671,7 +671,7 @@ func WikiRaw(ctx *context.Context) {
var entry *git.TreeEntry var entry *git.TreeEntry
if commit != nil { if commit != nil {
// Try to find a file with that name // Try to find a file with that name
entry, err = findEntryForFile(commit, string(providedGitPath)) entry, err = findEntryForFile(commit, providedGitPath)
if err != nil && !git.IsErrNotExist(err) { if err != nil && !git.IsErrNotExist(err) {
ctx.ServerError("findFile", err) ctx.ServerError("findFile", err)
return return
@ -679,8 +679,8 @@ func WikiRaw(ctx *context.Context) {
if entry == nil { if entry == nil {
// Try to find a wiki page with that name // Try to find a wiki page with that name
providedGitPath = wiki_service.GitPath(strings.TrimSuffix(string(providedGitPath), ".md")) providedGitPath = strings.TrimSuffix(providedGitPath, ".md")
entry, err = findEntryForFile(commit, string(providedGitPath)) entry, err = findEntryForFile(commit, providedGitPath)
if err != nil && !git.IsErrNotExist(err) { if err != nil && !git.IsErrNotExist(err) {
ctx.ServerError("findFile", err) ctx.ServerError("findFile", err)
return return
@ -746,9 +746,9 @@ func NewWikiPost(ctx *context.Context) {
return return
} }
notify_service.NewWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, string(wikiName.WebPath()), form.Message) notify_service.NewWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName.GitPath(), form.Message)
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + string(wikiName.URLPath())) ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + wikiName.URLPath())
} }
// EditWiki render wiki modify page // EditWiki render wiki modify page
@ -790,16 +790,16 @@ func EditWikiPost(ctx *context.Context) {
return return
} }
notify_service.EditWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, string(newWikiName.WebPath()), form.Message) notify_service.EditWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, newWikiName.GitPath(), form.Message)
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + string(newWikiName.URLPath())) ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + newWikiName.URLPath())
} }
// DeleteWikiPagePost delete wiki page // DeleteWikiPagePost delete wiki page
func DeleteWikiPagePost(ctx *context.Context) { func DeleteWikiPagePost(ctx *context.Context) {
wikiName := wiki_service.RequestToPath(ctx.PathParamRaw("*")) wikiName := wiki_service.RequestToPath(ctx.PathParamRaw("*"))
if len(wikiName.WebPath()) == 0 { if wikiName.IsEmpty() {
wikiName = wiki_service.WebPathToPath("Home") wikiName = wiki_service.HomePath()
} }
if err := wiki_service.DeleteWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName); err != nil { if err := wiki_service.DeleteWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName); err != nil {
@ -807,7 +807,7 @@ func DeleteWikiPagePost(ctx *context.Context) {
return return
} }
notify_service.DeleteWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, string(wikiName.WebPath())) notify_service.DeleteWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName.GitPath())
ctx.JSONRedirect(ctx.Repo.RepoLink + "/wiki/") ctx.JSONRedirect(ctx.Repo.RepoLink + "/wiki/")
} }

View file

@ -36,7 +36,7 @@ func wikiEntry(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.
entries, err := commit.ListEntries() entries, err := commit.ListEntries()
require.NoError(t, err) require.NoError(t, err)
for _, entry := range entries { for _, entry := range entries {
if entry.Name() == string(wikiName.GitPath()) { if entry.Name() == wikiName.GitPath() {
return entry return entry
} }
} }
@ -159,7 +159,7 @@ func TestEditWiki(t *testing.T) {
EditWiki(ctx) EditWiki(ctx)
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.EqualValues(t, "Home", ctx.Data["Title"]) assert.EqualValues(t, "Home", ctx.Data["Title"])
assert.Equal(t, wikiContent(t, ctx.Repo.Repository, wiki_service.WebPathToPath("Home")), ctx.Data["content"]) assert.Equal(t, wikiContent(t, ctx.Repo.Repository, wiki_service.HomePath()), ctx.Data["content"])
} }
func TestEditWikiPost(t *testing.T) { func TestEditWikiPost(t *testing.T) {
@ -182,7 +182,7 @@ func TestEditWikiPost(t *testing.T) {
assertWikiExists(t, ctx.Repo.Repository, wiki_service.TitleToPath(title)) assertWikiExists(t, ctx.Repo.Repository, wiki_service.TitleToPath(title))
assert.Equal(t, content, wikiContent(t, ctx.Repo.Repository, wiki_service.TitleToPath(title))) assert.Equal(t, content, wikiContent(t, ctx.Repo.Repository, wiki_service.TitleToPath(title)))
if title != "Home" { if title != "Home" {
assertWikiNotExists(t, ctx.Repo.Repository, wiki_service.WebPathToPath("Home")) assertWikiNotExists(t, ctx.Repo.Repository, wiki_service.HomePath())
} }
} }
} }
@ -195,7 +195,7 @@ func TestDeleteWikiPagePost(t *testing.T) {
contexttest.LoadRepo(t, ctx, 1) contexttest.LoadRepo(t, ctx, 1)
DeleteWikiPagePost(ctx) DeleteWikiPagePost(ctx)
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assertWikiNotExists(t, ctx.Repo.Repository, wiki_service.WebPathToPath("Home")) assertWikiNotExists(t, ctx.Repo.Repository, wiki_service.HomePath())
} }
func TestWikiRaw(t *testing.T) { func TestWikiRaw(t *testing.T) {

View file

@ -98,12 +98,12 @@ func NormalizeWikiBranch(ctx context.Context, repo *repo_model.Repository, to st
// prepareGitPath try to find a suitable file path with file name by the given raw wiki name. // prepareGitPath try to find a suitable file path with file name by the given raw wiki name.
// return: existence, prepared file path with name, error // return: existence, prepared file path with name, error
func prepareGitPath(gitRepo *git.Repository, branch string, wikiPath Path) (bool, GitPath, error) { func prepareGitPath(gitRepo *git.Repository, branch string, wikiPath Path) (bool, string, error) {
unescaped := string(wikiPath.WebPath()) + ".md" unescaped := string(wikiPath.WebPath()) + ".md"
gitPath := wikiPath.GitPath() gitPath := wikiPath.GitPath()
// Look for both files // Look for both files
filesInIndex, err := gitRepo.LsTree(branch, unescaped, string(gitPath)) filesInIndex, err := gitRepo.LsTree(branch, unescaped, gitPath)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "Not a valid object name "+branch) { if strings.Contains(err.Error(), "Not a valid object name "+branch) {
return false, gitPath, nil return false, gitPath, nil
@ -117,8 +117,8 @@ func prepareGitPath(gitRepo *git.Repository, branch string, wikiPath Path) (bool
switch filename { switch filename {
case unescaped: case unescaped:
// if we find the unescaped file return it // if we find the unescaped file return it
return true, GitPath(unescaped), nil return true, unescaped, nil
case string(gitPath): case gitPath:
foundEscaped = true foundEscaped = true
} }
} }
@ -128,7 +128,7 @@ func prepareGitPath(gitRepo *git.Repository, branch string, wikiPath Path) (bool
} }
// updateWikiPage adds a new page or edits an existing page in repository wiki. // updateWikiPage adds a new page or edits an existing page in repository wiki.
func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldWikiName, newWikiName Path, content, message string, isNew bool) (err error) { func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldWikiName *Path, newWikiName Path, content, message string, isNew bool) (err error) {
err = repo.MustNotBeArchived() err = repo.MustNotBeArchived()
if err != nil { if err != nil {
return err return err
@ -192,22 +192,22 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
if isNew { if isNew {
if isWikiExist { if isWikiExist {
return repo_model.ErrWikiAlreadyExist{ return repo_model.ErrWikiAlreadyExist{
Title: string(newWikiPath), Title: newWikiPath,
} }
} }
} else { } else {
// avoid check existence again if wiki name is not changed since gitRepo.LsFiles(...) is not free. // avoid check existence again if wiki name is not changed since gitRepo.LsFiles(...) is not free.
isOldWikiExist := true isOldWikiExist := true
oldWikiPath := newWikiPath oldWikiPath := newWikiPath
if oldWikiName != newWikiName { if *oldWikiName != newWikiName {
isOldWikiExist, oldWikiPath, err = prepareGitPath(gitRepo, repo.GetWikiBranchName(), oldWikiName) isOldWikiExist, oldWikiPath, err = prepareGitPath(gitRepo, repo.GetWikiBranchName(), *oldWikiName)
if err != nil { if err != nil {
return err return err
} }
} }
if isOldWikiExist { if isOldWikiExist {
err := gitRepo.RemoveFilesFromIndex(string(oldWikiPath)) err := gitRepo.RemoveFilesFromIndex(oldWikiPath)
if err != nil { if err != nil {
log.Error("RemoveFilesFromIndex failed: %v", err) log.Error("RemoveFilesFromIndex failed: %v", err)
return err return err
@ -223,7 +223,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
return err return err
} }
if err := gitRepo.AddObjectToIndex("100644", objectHash, string(newWikiPath)); err != nil { if err := gitRepo.AddObjectToIndex("100644", objectHash, newWikiPath); err != nil {
log.Error("AddObjectToIndex failed: %v", err) log.Error("AddObjectToIndex failed: %v", err)
return err return err
} }
@ -282,13 +282,13 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
// AddWikiPage adds a new wiki page with a given wikiPath. // AddWikiPage adds a new wiki page with a given wikiPath.
func AddWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, wikiName Path, content, message string) error { func AddWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, wikiName Path, content, message string) error {
return updateWikiPage(ctx, doer, repo, WebPathToPath(""), wikiName, content, message, true) return updateWikiPage(ctx, doer, repo, nil, wikiName, content, message, true)
} }
// EditWikiPage updates a wiki page identified by its wikiPath, // EditWikiPage updates a wiki page identified by its wikiPath,
// optionally also changing wikiPath. // optionally also changing wikiPath.
func EditWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldWikiName, newWikiName Path, content, message string) error { func EditWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldWikiName, newWikiName Path, content, message string) error {
return updateWikiPage(ctx, doer, repo, oldWikiName, newWikiName, content, message, false) return updateWikiPage(ctx, doer, repo, &oldWikiName, newWikiName, content, message, false)
} }
// DeleteWikiPage deletes a wiki page identified by its path. // DeleteWikiPage deletes a wiki page identified by its path.
@ -341,7 +341,7 @@ func DeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
return err return err
} }
if found { if found {
err := gitRepo.RemoveFilesFromIndex(string(wikiPath)) err := gitRepo.RemoveFilesFromIndex(wikiPath)
if err != nil { if err != nil {
return err return err
} }
@ -433,7 +433,7 @@ func SearchWikiContents(ctx context.Context, repo *repo_model.Repository, keywor
res := make([]SearchContentsResult, 0, len(grepRes)) res := make([]SearchContentsResult, 0, len(grepRes))
for _, entry := range grepRes { for _, entry := range grepRes {
wp, err := GitPathToPath(GitPath(entry.Filename)) wp, err := GitPathToPath(entry.Filename)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -37,16 +37,26 @@ import (
// * This problem should have been 99% fixed, but it needs more tests. // * This problem should have been 99% fixed, but it needs more tests.
// * The old wiki code's behavior is always using %2F, instead of subdirectory, so there are a lot of legacy "%2F" files in user wikis. // * The old wiki code's behavior is always using %2F, instead of subdirectory, so there are a lot of legacy "%2F" files in user wikis.
type ( type WebPath string
WebPath string
GitPath string
URLPath string
)
type Path struct { type Path struct {
file WebPath file WebPath
} }
var reservedWikiPaths = []string{"_pages", "_new", "_edit", "raw"}
func HomePath() Path {
return Path{file: "Home"}
}
func SidebarPath() Path {
return Path{file: "_Sidebar"}
}
func FooterPath() Path {
return Path{file: "_Footer"}
}
func WebPathToPath(web WebPath) Path { func WebPathToPath(web WebPath) Path {
return Path{ return Path{
file: web, file: web,
@ -75,8 +85,7 @@ func TitleToPath(title string) Path {
} }
} }
func GitPathToPath(g GitPath) (*Path, error) { func GitPathToPath(gitPath string) (*Path, error) {
gitPath := string(g)
if !strings.HasSuffix(gitPath, ".md") { if !strings.HasSuffix(gitPath, ".md") {
return nil, repo_model.ErrWikiInvalidFileName{FileName: gitPath} return nil, repo_model.ErrWikiInvalidFileName{FileName: gitPath}
} }
@ -96,6 +105,22 @@ func GitPathToPath(g GitPath) (*Path, error) {
}, nil }, nil
} }
func (w Path) IsEmpty() bool {
return len(w.file) == 0
}
func (w Path) IsHome() bool {
return w.file == "Home"
}
func (w Path) IsSidebar() bool {
return w.file == "_Sidebar"
}
func (w Path) IsFooter() bool {
return w.file == "_Footer"
}
func (w Path) DisplayName() (dir, display string) { func (w Path) DisplayName() (dir, display string) {
dir = path.Dir(string(w.file)) dir = path.Dir(string(w.file))
display = path.Base(string(w.file)) display = path.Base(string(w.file))
@ -111,10 +136,10 @@ func (w Path) WebPath() WebPath {
return w.file return w.file
} }
func (w Path) GitPath() GitPath { func (w Path) GitPath() string {
if strings.HasSuffix(string(w.file), ".md") { if strings.HasSuffix(string(w.file), ".md") {
ret, _ := url.PathUnescape(string(w.file)) ret, _ := url.PathUnescape(string(w.file))
return GitPath(util.PathJoinRelX(ret)) return util.PathJoinRelX(ret)
} }
a := strings.Split(string(w.file), "/") a := strings.Split(string(w.file), "/")
@ -125,11 +150,11 @@ func (w Path) GitPath() GitPath {
a[i] = strings.ReplaceAll(a[i], "%20", " ") // space is safe to be kept in git path a[i] = strings.ReplaceAll(a[i], "%20", " ") // space is safe to be kept in git path
a[i] = strings.ReplaceAll(a[i], "+", " ") a[i] = strings.ReplaceAll(a[i], "+", " ")
} }
return GitPath(strings.Join(a, "/") + ".md") return strings.Join(a, "/") + ".md"
} }
func (w Path) URLPath() URLPath { func (w Path) URLPath() string {
return URLPath(w.file) return string(w.file)
} }
func WebPathSegments(s WebPath) []string { func WebPathSegments(s WebPath) []string {
@ -152,11 +177,9 @@ func ToWikiPageMetaData(wikiPath Path, lastCommit *git.Commit, repo *repo_model.
} }
} }
var reservedWikiNames = []string{"_pages", "_new", "_edit", "raw"}
func validateWebPath(name Path) error { func validateWebPath(name Path) error {
for _, s := range WebPathSegments(name.WebPath()) { for _, s := range WebPathSegments(name.WebPath()) {
if util.SliceContainsString(reservedWikiNames, s) { if util.SliceContainsString(reservedWikiPaths, s) {
return repo_model.ErrWikiReservedName{Title: s} return repo_model.ErrWikiReservedName{Title: s}
} }
} }

View file

@ -69,7 +69,7 @@ func TestWebPathToDisplayName(t *testing.T) {
func TestWebPathToGitPath(t *testing.T) { func TestWebPathToGitPath(t *testing.T) {
type test struct { type test struct {
Expected GitPath Expected string
WebPath WebPath WebPath WebPath
} }
for _, test := range []test{ for _, test := range []test{
@ -87,7 +87,7 @@ func TestWebPathToGitPath(t *testing.T) {
func TestGitPathToWebPath(t *testing.T) { func TestGitPathToWebPath(t *testing.T) {
type test struct { type test struct {
Expected WebPath Expected WebPath
Filename GitPath Filename string
} }
for _, test := range []test{ for _, test := range []test{
{"hello-world", "hello-world.md"}, // this shouldn't happen, because it should always have a ".-" suffix {"hello-world", "hello-world.md"}, // this shouldn't happen, because it should always have a ".-" suffix
@ -100,7 +100,7 @@ func TestGitPathToWebPath(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
assert.EqualValues(t, test.Expected, wikiPath.WebPath()) assert.EqualValues(t, test.Expected, wikiPath.WebPath())
} }
for _, badFilename := range []GitPath{ for _, badFilename := range []string{
"nofileextension", "nofileextension",
"wrongfileextension.txt", "wrongfileextension.txt",
} { } {
@ -176,7 +176,7 @@ func TestRepository_AddWikiPage(t *testing.T) {
masterTree, err := gitRepo.GetTree("master") masterTree, err := gitRepo.GetTree("master")
require.NoError(t, err) require.NoError(t, err)
gitPath := wikiPath.GitPath() gitPath := wikiPath.GitPath()
entry, err := masterTree.GetTreeEntryByPath(string(gitPath)) entry, err := masterTree.GetTreeEntryByPath(gitPath)
require.NoError(t, err) require.NoError(t, err)
assert.EqualValues(t, gitPath, entry.Name(), "%s not added correctly", userTitle) assert.EqualValues(t, gitPath, entry.Name(), "%s not added correctly", userTitle)
}) })
@ -185,7 +185,7 @@ func TestRepository_AddWikiPage(t *testing.T) {
t.Run("check wiki already exist", func(t *testing.T) { t.Run("check wiki already exist", func(t *testing.T) {
t.Parallel() t.Parallel()
// test for already-existing wiki name // test for already-existing wiki name
err := AddWikiPage(git.DefaultContext, doer, repo, TitleToPath("Home"), wikiContent, commitMsg) err := AddWikiPage(git.DefaultContext, doer, repo, HomePath(), wikiContent, commitMsg)
require.Error(t, err) require.Error(t, err)
assert.True(t, repo_model.IsErrWikiAlreadyExist(err)) assert.True(t, repo_model.IsErrWikiAlreadyExist(err))
}) })
@ -213,7 +213,7 @@ func TestRepository_EditWikiPage(t *testing.T) {
} { } {
wikiPath := TitleToPath(newWikiName) wikiPath := TitleToPath(newWikiName)
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
require.NoError(t, EditWikiPage(git.DefaultContext, doer, repo, TitleToPath("Home"), wikiPath, newWikiContent, commitMsg)) require.NoError(t, EditWikiPage(git.DefaultContext, doer, repo, HomePath(), wikiPath, newWikiContent, commitMsg))
// Now need to show that the page has been added: // Now need to show that the page has been added:
gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo) gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo)
@ -221,11 +221,11 @@ func TestRepository_EditWikiPage(t *testing.T) {
masterTree, err := gitRepo.GetTree("master") masterTree, err := gitRepo.GetTree("master")
require.NoError(t, err) require.NoError(t, err)
gitPath := wikiPath.GitPath() gitPath := wikiPath.GitPath()
entry, err := masterTree.GetTreeEntryByPath(string(gitPath)) entry, err := masterTree.GetTreeEntryByPath(gitPath)
require.NoError(t, err) require.NoError(t, err)
assert.EqualValues(t, gitPath, entry.Name(), "%s not edited correctly", newWikiName) assert.EqualValues(t, gitPath, entry.Name(), "%s not edited correctly", newWikiName)
if newWikiName != "Home" { if !wikiPath.IsHome() {
_, err := masterTree.GetTreeEntryByPath("Home.md") _, err := masterTree.GetTreeEntryByPath("Home.md")
require.Error(t, err) require.Error(t, err)
} }
@ -237,7 +237,7 @@ func TestRepository_DeleteWikiPage(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
require.NoError(t, DeleteWikiPage(git.DefaultContext, doer, repo, TitleToPath("Home"))) require.NoError(t, DeleteWikiPage(git.DefaultContext, doer, repo, HomePath()))
// Now need to show that the page has been added: // Now need to show that the page has been added:
gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo) gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo)
@ -245,8 +245,8 @@ func TestRepository_DeleteWikiPage(t *testing.T) {
defer gitRepo.Close() defer gitRepo.Close()
masterTree, err := gitRepo.GetTree("master") masterTree, err := gitRepo.GetTree("master")
require.NoError(t, err) require.NoError(t, err)
gitPath := WebPathToPath("Home").GitPath() gitPath := HomePath().GitPath()
_, err = masterTree.GetTreeEntryByPath(string(gitPath)) _, err = masterTree.GetTreeEntryByPath(gitPath)
require.Error(t, err) require.Error(t, err)
} }
@ -311,16 +311,16 @@ func TestPrepareWikiFileName_FirstPage(t *testing.T) {
defer gitRepo.Close() defer gitRepo.Close()
existence, newWikiPath, err := prepareGitPath(gitRepo, "master", TitleToPath("Home")) existence, newWikiPath, err := prepareGitPath(gitRepo, "master", HomePath())
assert.False(t, existence) assert.False(t, existence)
require.NoError(t, err) require.NoError(t, err)
assert.EqualValues(t, "Home.md", newWikiPath) assert.EqualValues(t, "Home.md", newWikiPath)
} }
func TestWebPathConversion(t *testing.T) { func TestWebPathConversion(t *testing.T) {
assert.Equal(t, "path/wiki", string(WebPathToPath("path/wiki").URLPath())) assert.Equal(t, "path/wiki", WebPathToPath("path/wiki").URLPath())
assert.Equal(t, "wiki", string(WebPathToPath("wiki").URLPath())) assert.Equal(t, "wiki", WebPathToPath("wiki").URLPath())
assert.Equal(t, "", string(WebPathToPath("").URLPath())) assert.Equal(t, "", WebPathToPath("").URLPath())
} }
func TestWebPathFromRequest(t *testing.T) { func TestWebPathFromRequest(t *testing.T) {

View file

@ -457,7 +457,7 @@ func CreateDeclarativeRepoWithOptions(t *testing.T, owner *user_model.User, opts
require.NoError(t, err) require.NoError(t, err)
// Add a new wiki page // Add a new wiki page
err = wiki_service.AddWikiPage(db.DefaultContext, owner, repo, wiki_service.WebPathToPath("Home"), "Welcome to the wiki!", "Add a Home page") err = wiki_service.AddWikiPage(db.DefaultContext, owner, repo, wiki_service.HomePath(), "Welcome to the wiki!", "Add a Home page")
require.NoError(t, err) require.NoError(t, err)
} }