forked from Gitlink/gitea-1120-rc1
fix modules/wikies/wiki.go /api/v1/repo/wiki.go
This commit is contained in:
parent
d9495f6822
commit
23f2dc9c23
|
@ -7,11 +7,19 @@
|
|||
package wikies
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
//"github.com/unknwon/com"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
wiki_service "code.gitea.io/gitea/services/wiki"
|
||||
)
|
||||
|
||||
|
@ -72,3 +80,235 @@ func wikiContentsByEntry(ctx *context.APIContext, entry *git.TreeEntry) []byte {
|
|||
}
|
||||
return content
|
||||
}
|
||||
|
||||
|
||||
func CreateWikiPage(doer *models.User, repo *models.Repository, wikiName, content, message string) error {
|
||||
return updateWikiPage(doer, repo, "", wikiName, content, message, true)
|
||||
}
|
||||
|
||||
|
||||
func EditWikiPage(doer *models.User, repo *models.Repository, oldWikiName,newWikiName, content, message string) error {
|
||||
return updateWikiPage(doer, repo, oldWikiName , newWikiName, content, message, false)
|
||||
}
|
||||
func updateWikiPage(doer *models.User, repo *models.Repository, oldWikiName, newWikiName, content, message string, isNew bool) (err error) {
|
||||
//if err = nameAllowed(newWikiName); err != nil {
|
||||
// return err
|
||||
//}
|
||||
//wikiWorkingPool.CheckIn(com.ToStr(repo.ID))
|
||||
//defer wikiWorkingPool.CheckOut(com.ToStr(repo.ID))
|
||||
//
|
||||
//if err = InitWiki(repo); err != nil {
|
||||
// return fmt.Errorf("InitWiki: %v", err)
|
||||
//}
|
||||
|
||||
hasMasterBranch := git.IsBranchExist(repo.WikiPath(), "master")
|
||||
|
||||
basePath, err := models.CreateTemporaryPath("update-wiki")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := models.RemoveTemporaryPath(basePath); err != nil {
|
||||
log.Error("Merge: RemoveTemporaryPath: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
cloneOpts := git.CloneRepoOptions{
|
||||
Bare: true,
|
||||
Shared: true,
|
||||
}
|
||||
|
||||
if hasMasterBranch {
|
||||
cloneOpts.Branch = "master"
|
||||
}
|
||||
|
||||
if err := git.Clone(repo.WikiPath(), basePath, cloneOpts); err != nil {
|
||||
log.Error("Failed to clone repository: %s (%v)", repo.FullName(), err)
|
||||
return fmt.Errorf("Failed to clone repository: %s (%v)", repo.FullName(), err)
|
||||
}
|
||||
|
||||
gitRepo, err := git.OpenRepository(basePath)
|
||||
if err != nil {
|
||||
log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
|
||||
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
|
||||
if hasMasterBranch {
|
||||
if err := gitRepo.ReadTreeToIndex("HEAD"); err != nil {
|
||||
log.Error("Unable to read HEAD tree to index in: %s %v", basePath, err)
|
||||
return fmt.Errorf("Unable to read HEAD tree to index in: %s %v", basePath, err)
|
||||
}
|
||||
}
|
||||
|
||||
newWikiPath := wiki_service.NameToFilename(newWikiName)
|
||||
if isNew {
|
||||
filesInIndex, err := gitRepo.LsFiles(newWikiPath)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
if util.IsStringInSlice(newWikiPath, filesInIndex) {
|
||||
return models.ErrWikiAlreadyExist{
|
||||
Title: newWikiPath,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
oldWikiPath := wiki_service.NameToFilename(oldWikiName)
|
||||
filesInIndex, err := gitRepo.LsFiles(oldWikiPath)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if util.IsStringInSlice(oldWikiPath, filesInIndex) {
|
||||
err := gitRepo.RemoveFilesFromIndex(oldWikiPath)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: The wiki doesn't have lfs support at present - if this changes need to check attributes here
|
||||
|
||||
objectHash, err := gitRepo.HashObject(strings.NewReader(content))
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := gitRepo.AddObjectToIndex("100644", objectHash, newWikiPath); err != nil {
|
||||
log.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
tree, err := gitRepo.WriteTree()
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
commitTreeOpts := git.CommitTreeOpts{
|
||||
Message: message,
|
||||
}
|
||||
|
||||
sign, signingKey, _ := repo.SignWikiCommit(doer)
|
||||
if sign {
|
||||
commitTreeOpts.KeyID = signingKey
|
||||
} else {
|
||||
commitTreeOpts.NoGPGSign = true
|
||||
}
|
||||
if hasMasterBranch {
|
||||
commitTreeOpts.Parents = []string{"HEAD"}
|
||||
}
|
||||
commitHash, err := gitRepo.CommitTree(doer.NewGitSig(), tree, commitTreeOpts)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := git.Push(basePath, git.PushOptions{
|
||||
Remote: "origin",
|
||||
Branch: fmt.Sprintf("%s:%s%s", commitHash.String(), git.BranchPrefix, "master"),
|
||||
Env: models.FullPushingEnvironment(
|
||||
doer,
|
||||
doer,
|
||||
repo,
|
||||
repo.Name+".wiki",
|
||||
0,
|
||||
),
|
||||
}); err != nil {
|
||||
log.Error("%v", err)
|
||||
if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("Push: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func DeleteWikiPage(doer *models.User, repo *models.Repository, pageName string) (err error) {
|
||||
|
||||
basePath, err := models.CreateTemporaryPath("update-wiki")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := git.Clone(repo.WikiPath(), basePath, git.CloneRepoOptions{
|
||||
Bare: true,
|
||||
Shared: true,
|
||||
Branch: "master",
|
||||
}); err != nil {
|
||||
log.Error("Failed to clone repository: %s (%v)", repo.FullName(), err)
|
||||
return fmt.Errorf("Failed to clone repository: %s (%v)", repo.FullName(), err)
|
||||
}
|
||||
|
||||
gitRepo, err := git.OpenRepository(basePath)
|
||||
if err != nil {
|
||||
log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
|
||||
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
|
||||
if err := gitRepo.ReadTreeToIndex("HEAD"); err != nil {
|
||||
log.Error("Unable to read HEAD tree to index in: %s %v", basePath, err)
|
||||
return fmt.Errorf("Unable to read HEAD tree to index in: %s %v", basePath, err)
|
||||
}
|
||||
|
||||
wikiPath := wiki_service.NameToFilename(pageName)
|
||||
filesInIndex, err := gitRepo.LsFiles(wikiPath)
|
||||
found := false
|
||||
for _, file := range filesInIndex {
|
||||
if file == wikiPath {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if found {
|
||||
err := gitRepo.RemoveFilesFromIndex(wikiPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return os.ErrNotExist
|
||||
}
|
||||
|
||||
// FIXME: The wiki doesn't have lfs support at present - if this changes need to check attributes here
|
||||
|
||||
tree, err := gitRepo.WriteTree()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
message := "Delete page '" + pageName + "'"
|
||||
commitTreeOpts := git.CommitTreeOpts{
|
||||
Message: message,
|
||||
Parents: []string{"HEAD"},
|
||||
}
|
||||
|
||||
sign, signingKey, _ := repo.SignWikiCommit(doer)
|
||||
if sign {
|
||||
commitTreeOpts.KeyID = signingKey
|
||||
} else {
|
||||
commitTreeOpts.NoGPGSign = true
|
||||
}
|
||||
|
||||
commitHash, err := gitRepo.CommitTree(doer.NewGitSig(), tree, commitTreeOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := git.Push(basePath, git.PushOptions{
|
||||
Remote: "origin",
|
||||
Branch: fmt.Sprintf("%s:%s%s", commitHash.String(), git.BranchPrefix, "master"),
|
||||
Env: models.PushingEnvironment(doer, repo),
|
||||
}); err != nil {
|
||||
if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("Push: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -4,10 +4,12 @@ package repo
|
|||
import (
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/markup/markdown"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/wikies"
|
||||
wiki_service "code.gitea.io/gitea/services/wiki"
|
||||
"fmt"
|
||||
|
||||
"net/http"
|
||||
)
|
||||
|
@ -35,7 +37,9 @@ func WikiList(ctx *context.APIContext) {
|
|||
|
||||
wikiRepo, commit, err := wikies.FindWikiRepoCommit(ctx)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusOK, []api.WikiesResponse{})
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -45,7 +49,7 @@ func WikiList(ctx *context.APIContext) {
|
|||
wikiRepo.Close()
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, []api.WikiesResponse{})
|
||||
//ctx.JSON(http.StatusOK, []api.WikiesResponse{})
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -125,6 +129,9 @@ func GetWiki(ctx *context.APIContext) {
|
|||
// "200":
|
||||
// "$ref": "#/responses/Wiki"
|
||||
|
||||
|
||||
|
||||
|
||||
wikiRepo, commit, _ := wikies.FindWikiRepoCommit(ctx)
|
||||
|
||||
pageName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
|
||||
|
@ -175,8 +182,8 @@ func GetWiki(ctx *context.APIContext) {
|
|||
ctx.JSON(http.StatusOK, wiki)
|
||||
}
|
||||
|
||||
func CreateWiki(ctx *context.APIContext) {
|
||||
// swagger:operation POST /repos/{owner}/{repo}/wikis repository repoCreateWiki
|
||||
func CreateWiki(ctx *context.APIContext, form api.WikiOption) {
|
||||
// swagger:operation POST /repos/{owner}/{repo}/wikies repository repoCreateWiki
|
||||
// ---
|
||||
// summary: Create a wiki in a repository
|
||||
// produces:
|
||||
|
@ -197,12 +204,58 @@ func CreateWiki(ctx *context.APIContext) {
|
|||
// schema:
|
||||
// "$ref": "#/definitions/WikiOption"
|
||||
// responses:
|
||||
// "201":
|
||||
// "200":
|
||||
// "$ref": "#/responses/Wiki"
|
||||
|
||||
err2 := wikies.CreateWikiPage(ctx.User, ctx.Repo.Repository, form.Name, form.Content, form.CommitMessage)
|
||||
if err2 != nil{
|
||||
ctx.ServerError("CreateWikiPage", err2)
|
||||
}
|
||||
|
||||
wikiRepo, commit, _ := wikies.FindWikiRepoCommit(ctx)
|
||||
|
||||
data, entry, pageFilename, _:= wikies.WikiContentsByName(ctx, commit, form.Name)
|
||||
|
||||
|
||||
metas := ctx.Repo.Repository.ComposeDocumentMetas()
|
||||
|
||||
PageContent := markdown.RenderWiki(data, ctx.Repo.RepoLink, metas)
|
||||
|
||||
commitsCount, _ := wikiRepo.FileCommitsCount("master", pageFilename)
|
||||
|
||||
c, err := wikiRepo.GetCommitByPath(entry.Name())
|
||||
if err != nil {
|
||||
if models.IsErrWikiInvalidFileName(err) {
|
||||
return
|
||||
}
|
||||
}
|
||||
fmt.Println(form)
|
||||
wiki := api.WikiResponse{
|
||||
WikiMeta: api.WikiMeta{
|
||||
Name: form.Name,
|
||||
Commit: api.WikiCommit{
|
||||
Author: api.WikiUser{
|
||||
Name: c.Author.Name,
|
||||
Email: c.Author.Email,
|
||||
When: c.Author.When.Unix(),
|
||||
},
|
||||
Commiter: api.WikiUser{
|
||||
Name: c.Committer.Name,
|
||||
Email: c.Committer.Email,
|
||||
When: c.Author.When.Unix(),
|
||||
},
|
||||
ID: c.ID.String(),
|
||||
Message: c.Message(),
|
||||
},
|
||||
},
|
||||
CommitCounts: commitsCount,
|
||||
Content: PageContent,
|
||||
}
|
||||
ctx.JSON(http.StatusOK, wiki)
|
||||
|
||||
}
|
||||
|
||||
func EditWiki(ctx *context.Context) {
|
||||
func EditWiki(ctx *context.APIContext, form api.WikiOption) {
|
||||
// swagger:operation PATCH /repos/{owner}/{repo}/wikies/{pagename} repository repoEditWiki
|
||||
// ---
|
||||
// summary: Edit a wiki in a repository
|
||||
|
@ -231,10 +284,61 @@ func EditWiki(ctx *context.Context) {
|
|||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/Wiki"
|
||||
fmt.Println(form)
|
||||
|
||||
//OldPageName := ctx.Params(":page")
|
||||
|
||||
oldWikiName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
|
||||
newWikiName := wiki_service.NormalizeWikiName(form.Name)
|
||||
|
||||
err2 := wikies.EditWikiPage(ctx.User, ctx.Repo.Repository, oldWikiName,newWikiName, form.Content, form.CommitMessage)
|
||||
if err2 != nil{
|
||||
ctx.ServerError("EditWikiPage", err2)
|
||||
}
|
||||
wikiRepo, commit, _ := wikies.FindWikiRepoCommit(ctx)
|
||||
|
||||
data, entry, pageFilename, _:= wikies.WikiContentsByName(ctx, commit, form.Name) //
|
||||
|
||||
|
||||
metas := ctx.Repo.Repository.ComposeDocumentMetas()
|
||||
|
||||
PageContent := markdown.RenderWiki(data, ctx.Repo.RepoLink, metas)
|
||||
|
||||
commitsCount, _ := wikiRepo.FileCommitsCount("master", pageFilename)
|
||||
|
||||
c, err := wikiRepo.GetCommitByPath(entry.Name())
|
||||
if err != nil {
|
||||
if models.IsErrWikiInvalidFileName(err) {
|
||||
return
|
||||
}
|
||||
}
|
||||
fmt.Println(form)
|
||||
wiki := api.WikiResponse{
|
||||
WikiMeta: api.WikiMeta{
|
||||
Name: form.Name,
|
||||
Commit: api.WikiCommit{
|
||||
Author: api.WikiUser{
|
||||
Name: c.Author.Name,
|
||||
Email: c.Author.Email,
|
||||
When: c.Author.When.Unix(),
|
||||
},
|
||||
Commiter: api.WikiUser{
|
||||
Name: c.Committer.Name,
|
||||
Email: c.Committer.Email,
|
||||
When: c.Author.When.Unix(),
|
||||
},
|
||||
ID: c.ID.String(),
|
||||
Message: c.Message(),
|
||||
},
|
||||
},
|
||||
CommitCounts: commitsCount,
|
||||
Content: PageContent,
|
||||
}
|
||||
ctx.JSON(http.StatusOK, wiki)
|
||||
|
||||
}
|
||||
|
||||
func DeleteWiki(ctx *context.Context) {
|
||||
func DeleteWiki(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /repos/{owner}/{repo}/wikies/{pagename} repository repoDeleteWiki
|
||||
// ---
|
||||
// summary: Delete a wiki in a repository
|
||||
|
@ -259,6 +363,15 @@ func DeleteWiki(ctx *context.Context) {
|
|||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "404":
|
||||
// "500":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
WikiPageName := ctx.Params(":page")
|
||||
err := wikies.DeleteWikiPage(ctx.User, ctx.Repo.Repository, WikiPageName)
|
||||
if err != nil{
|
||||
ctx.Error(http.StatusInternalServerError,"DeleteWikiPage", err)
|
||||
return
|
||||
}
|
||||
log.Trace("WikiPage deleted : %s%s", ctx.Repo.Repository.Name, WikiPageName)
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -8931,6 +8931,44 @@
|
|||
"$ref": "#/responses/WikiList"
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "Create a wiki in a repository",
|
||||
"operationId": "repoCreateWiki",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/WikiOption"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"$ref": "#/responses/Wiki"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/wikies/{pagename}": {
|
||||
|
@ -9059,46 +9097,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/wikis": {
|
||||
"post": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "Create a wiki in a repository",
|
||||
"operationId": "repoCreateWiki",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/WikiOption"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"$ref": "#/responses/Wiki"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repositories/{id}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
|
@ -16373,4 +16371,4 @@
|
|||
"TOTPHeader": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue