Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[help wanted] Get basic upload-to-wiki working #12279

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions models/helper_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ func PushingEnvironment(doer *User, repo *Repository) []string {
return FullPushingEnvironment(doer, doer, repo, repo.Name, 0)
}

// WikiPushingEnvironment returns an os environment for wiki repo
func WikiPushingEnvironment(doer *User, repo *Repository) []string {
return FullPushingEnvironment(doer, doer, repo, repo.Name+".wiki", 0)
}

// FullPushingEnvironment returns an os environment to allow hooks to work on push
func FullPushingEnvironment(author, committer *User, repo *Repository, repoName string, prID int64) []string {
isWiki := "false"
Expand Down
11 changes: 11 additions & 0 deletions modules/auth/repo_form.go
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,17 @@ func (f *NewWikiForm) Validate(ctx *macaron.Context, errs binding.Errors) bindin
return validate(errs, ctx.Data, f, ctx.Locale)
}

// UploadWikiFileForm form for uploading wiki file
type UploadWikiFileForm struct {
CommitMessage string
Files []string
}

// Validate validates the fields
func (f *UploadWikiFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
return validate(errs, ctx.Data, f, ctx.Locale)
}

// ___________ .___.__ __
// \_ _____/ __| _/|__|/ |_
// | __)_ / __ | | \ __\
Expand Down
41 changes: 37 additions & 4 deletions modules/repofiles/temp_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,13 @@ func (t *TemporaryUploadRepository) Close() {
}

// Clone the base repository to our path and set branch as the HEAD
func (t *TemporaryUploadRepository) Clone(branch string) error {
if _, err := git.NewCommand("clone", "-s", "--bare", "-b", branch, t.repo.RepoPath(), t.basePath).Run(); err != nil {
func (t *TemporaryUploadRepository) clone(branch string, isWiki bool) error {
repoPath := t.repo.RepoPath()
if isWiki {
repoPath = t.repo.WikiPath()
}

if _, err := git.NewCommand("clone", "-s", "--bare", "-b", branch, repoPath, t.basePath).Run(); err != nil {
stderr := err.Error()
if matched, _ := regexp.MatchString(".*Remote branch .* not found in upstream origin.*", stderr); matched {
return git.ErrBranchNotExist{
Expand All @@ -65,6 +70,7 @@ func (t *TemporaryUploadRepository) Clone(branch string) error {
return fmt.Errorf("Clone: %v %s", err, stderr)
}
}

gitRepo, err := git.OpenRepository(t.basePath)
if err != nil {
return err
Expand All @@ -73,6 +79,16 @@ func (t *TemporaryUploadRepository) Clone(branch string) error {
return nil
}

// CloneWiki the base repository to our path and set branch as the HEAD
func (t *TemporaryUploadRepository) CloneWiki(branch string) error {
return t.clone(branch, true)
}

// Clone the base repository to our path and set branch as the HEAD
func (t *TemporaryUploadRepository) Clone(branch string) error {
return t.clone(branch, false)
}

// SetDefaultIndex sets the git index to our HEAD
func (t *TemporaryUploadRepository) SetDefaultIndex() error {
if _, err := git.NewCommand("read-tree", "HEAD").RunInDir(t.basePath); err != nil {
Expand Down Expand Up @@ -253,11 +269,18 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(author, committer *models
}

// Push the provided commitHash to the repository branch by the provided user
func (t *TemporaryUploadRepository) Push(doer *models.User, commitHash string, branch string) error {
func (t *TemporaryUploadRepository) push(doer *models.User, commitHash string, branch string, isWiki bool) error {
// Because calls hooks we need to pass in the environment
env := models.PushingEnvironment(doer, t.repo)
repoPath := t.repo.RepoPath()

if isWiki {
repoPath = t.repo.WikiPath()
env = models.WikiPushingEnvironment(doer, t.repo)
}

if err := git.Push(t.basePath, git.PushOptions{
Remote: t.repo.RepoPath(),
Remote: repoPath,
Branch: strings.TrimSpace(commitHash) + ":refs/heads/" + strings.TrimSpace(branch),
Env: env,
}); err != nil {
Expand All @@ -277,6 +300,16 @@ func (t *TemporaryUploadRepository) Push(doer *models.User, commitHash string, b
return nil
}

// PushWiki push the provided commitHash to the wiki repository branch by the provided user
func (t *TemporaryUploadRepository) PushWiki(doer *models.User, commitHash string, branch string) error {
return t.push(doer, commitHash, branch, true)
}

// Push the provided commitHash to the repository branch by the provided user
func (t *TemporaryUploadRepository) Push(doer *models.User, commitHash string, branch string) error {
return t.push(doer, commitHash, branch, false)
}

// DiffIndex returns a Diff of the current index to the head
func (t *TemporaryUploadRepository) DiffIndex() (*gitdiff.Diff, error) {
stdoutReader, stdoutWriter, err := os.Pipe()
Expand Down
35 changes: 29 additions & 6 deletions modules/repofiles/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ func cleanUpAfterFailure(infos *[]uploadInfo, t *TemporaryUploadRepository, orig
return original
}

// UploadRepoFiles uploads files to the given repository
func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRepoFileOptions) error {
func uploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRepoFileOptions, isWiki bool) error {
if len(opts.Files) == 0 {
return nil
}
Expand Down Expand Up @@ -78,9 +77,17 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
return err
}
defer t.Close()
if err := t.Clone(opts.OldBranch); err != nil {
return err

if isWiki {
if err := t.CloneWiki(opts.OldBranch); err != nil {
return err
}
} else {
if err := t.Clone(opts.OldBranch); err != nil {
return err
}
}

if err := t.SetDefaultIndex(); err != nil {
return err
}
Expand Down Expand Up @@ -190,9 +197,25 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
}

// Then push this tree to NewBranch
if err := t.Push(doer, commitHash, opts.NewBranch); err != nil {
return err
if isWiki {
if err := t.PushWiki(doer, commitHash, opts.NewBranch); err != nil {
return err
}
} else {
if err := t.Push(doer, commitHash, opts.NewBranch); err != nil {
return err
}
}

return models.DeleteUploads(uploads...)
}

// UploadRepoWikiFiles uploads files to the given repository's wiki repo
func UploadRepoWikiFiles(repo *models.Repository, doer *models.User, opts *UploadRepoFileOptions) error {
return uploadRepoFiles(repo, doer, opts, true)
}

// UploadRepoFiles uploads files to the given repository
func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRepoFileOptions) error {
return uploadRepoFiles(repo, doer, opts, false)
}
1 change: 1 addition & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1370,6 +1370,7 @@ wiki.file_revision = Page Revision
wiki.wiki_page_revisions = Wiki Page Revisions
wiki.back_to_wiki = Back to wiki page
wiki.delete_page_button = Delete Page
wiki.upload_files_button = Upload Files
wiki.delete_page_notice_1 = Deleting the wiki page '%s' cannot be undone. Continue?
wiki.page_already_exists = A wiki page with the same name already exists.
wiki.reserved_page = The wiki page name '%s' is reserved.
Expand Down
7 changes: 7 additions & 0 deletions routers/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ func MustBeNotEmpty(ctx *context.Context) {
}
}

// MustHaveWiki render when a repo have wiki
func MustHaveWiki(ctx *context.Context) {
if !ctx.Repo.Repository.HasWiki() {
ctx.NotFound("MustHaveWiki", nil)
}
}

// MustBeEditable check that repo can be edited
func MustBeEditable(ctx *context.Context) {
if !ctx.Repo.Repository.CanEnableEditor() || ctx.Repo.IsViewCommit {
Expand Down
69 changes: 69 additions & 0 deletions routers/repo/wiki.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/repofiles"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/upload"
"code.gitea.io/gitea/modules/util"
wiki_service "code.gitea.io/gitea/services/wiki"
)
Expand All @@ -31,6 +33,7 @@ const (
tplWikiRevision base.TplName = "repo/wiki/revision"
tplWikiNew base.TplName = "repo/wiki/new"
tplWikiPages base.TplName = "repo/wiki/pages"
tplWikiUpload base.TplName = "repo/wiki/upload"
)

// MustEnableWiki check if wiki is enabled, if external then redirect
Expand Down Expand Up @@ -654,3 +657,69 @@ func DeleteWikiPagePost(ctx *context.Context) {
"redirect": ctx.Repo.RepoLink + "/wiki/",
})
}

// UploadWikiFile render wiki upload page
func UploadWikiFile(ctx *context.Context) {
ctx.Data["PageIsWiki"] = true
ctx.Data["PageIsUpload"] = true
ctx.Data["RequireTribute"] = true
ctx.Data["RequireSimpleMDE"] = true
upload.AddUploadContext(ctx, "repo")

if !ctx.Repo.Repository.HasWiki() {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki")
return
}

renderEditPage(ctx)
if ctx.Written() {
return
}

ctx.HTML(200, tplWikiUpload)
}

// UploadWikiFilePost response for wiki upload request
func UploadWikiFilePost(ctx *context.Context, form auth.UploadWikiFileForm) {
fmt.Println("UploadWikiFilePost")

ctx.Data["PageIsWiki"] = true
ctx.Data["PageIsUpload"] = true
ctx.Data["RequireTribute"] = true
ctx.Data["RequireSimpleMDE"] = true
upload.AddUploadContext(ctx, "repo")

if ctx.HasError() {
ctx.HTML(200, tplWikiUpload)
return
}

message := strings.TrimSpace(form.CommitMessage)
if len(message) == 0 {
message = ctx.Tr("repo.editor.upload_files_to_dir", "_media")
}

form.CommitMessage = strings.TrimSpace(form.CommitMessage)
if len(form.CommitMessage) > 0 {
message += "\n\n" + form.CommitMessage
}

if err := repofiles.UploadRepoWikiFiles(ctx.Repo.Repository, ctx.User, &repofiles.UploadRepoFileOptions{
LastCommitID: ctx.Repo.CommitID,
OldBranch: "master",
NewBranch: "master",
TreePath: "_media",
Message: message,
Files: form.Files,
}); err != nil {
// FIXME: it will get a "The process cannot access the file because it is being used by another process." error when try to remove
// the uploaded cache file. Upload is successed anyway, but still need to fix this one.
log.Error("Error during upload to repo %-v : %v", ctx.Repo.Repository, err)
ctx.RenderWithErr(ctx.Tr("repo.editor.unable_to_upload_files", "_media", err), tplWikiUpload, &form)
return
}

ctx.JSON(200, map[string]interface{}{
"redirect": ctx.Repo.RepoLink + "/wiki/",
})
}
9 changes: 9 additions & 0 deletions routers/routes/macaron.go
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,13 @@ func RegisterMacaronRoutes(m *macaron.Macaron) {
}, context.RepoRef(), repo.MustBeEditable, repo.MustBeAbleToUpload)
}, context.RepoMustNotBeArchived(), reqRepoCodeWriter, repo.MustBeNotEmpty)

m.Group("", func() {
m.Group("", func() {
m.Post("/upload-wiki-file", repo.UploadFileToServer)
m.Post("/upload-wiki-remove", bindIgnErr(auth.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer)
}, context.RepoRef(), repo.MustBeEditable, repo.MustBeAbleToUpload)
}, context.RepoMustNotBeArchived(), reqRepoCodeWriter, repo.MustHaveWiki)

m.Group("/branches", func() {
m.Group("/_new/", func() {
m.Post("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.CreateBranch)
Expand Down Expand Up @@ -811,6 +818,8 @@ func RegisterMacaronRoutes(m *macaron.Macaron) {
Post(bindIgnErr(auth.NewWikiForm{}), repo.NewWikiPost)
m.Combo("/:page/_edit").Get(repo.EditWiki).
Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost)
m.Combo("/_upload").Get(repo.UploadWikiFile).
Post(bindIgnErr(auth.UploadWikiFileForm{}), repo.UploadWikiFilePost)
m.Post("/:page/delete", repo.DeleteWikiPagePost)
}, context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter)
}, repo.MustEnableWiki, context.RepoRef(), func(ctx *context.Context) {
Expand Down
10 changes: 2 additions & 8 deletions services/wiki/wiki.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
)

var (
reservedWikiNames = []string{"_pages", "_new", "_edit", "raw"}
reservedWikiNames = []string{"_pages", "_new", "_edit", "_upload", "raw"}
wikiWorkingPool = sync.NewExclusivePool()
)

Expand Down Expand Up @@ -209,13 +209,7 @@ func updateWikiPage(doer *models.User, repo *models.Repository, oldWikiName, new
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,
),
Env: models.WikiPushingEnvironment(doer, repo),
}); err != nil {
log.Error("%v", err)
if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) {
Expand Down
23 changes: 23 additions & 0 deletions templates/repo/wiki/upload.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{{template "base/head" .}}
<div class="repository file editor upload">
{{template "repo/header" .}}
<div class="ui container">
{{template "base/alert" .}}
<form class="ui comment form" method="post">
{{.CsrfTokenHtml}}
<div class="field">
<div class="files"></div>
<div class="ui dropzone" id="dropzone" data-upload-url="{{.RepoLink}}/upload-wiki-file" data-remove-url="{{.RepoLink}}/upload-wiki-remove" data-csrf="{{.CsrfToken}}" data-accepts="{{.UploadAllowedTypes}}" data-max-file="{{.UploadMaxFiles}}" data-max-size="{{.UploadMaxSize}}" data-default-message="{{.i18n.Tr "dropzone.default_message"}}" data-invalid-input-type="{{.i18n.Tr "dropzone.invalid_input_type"}}" data-file-too-big="{{.i18n.Tr "dropzone.file_too_big"}}" data-remove-file="{{.i18n.Tr "dropzone.remove_file"}}"></div>
</div>
<div class="field">
<input name="message" placeholder="{{.i18n.Tr "repo.wiki.default_commit_message"}}">
</div>
<div class="text right">
<button class="ui green button">
{{.i18n.Tr "repo.wiki.upload_files_button"}}
</button>
</div>
</form>
</div>
</div>
{{template "base/footer" .}}
9 changes: 8 additions & 1 deletion templates/repo/wiki/view.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@
</div>
</div>
</div>
<div class="right fitted item">
<div class="right fitted item" id="file-buttons">
<div class="ui tiny blue buttons">
<a href="{{.RepoLink}}/wiki/_upload" class="ui button">
{{.i18n.Tr "repo.wiki.upload_files_button"}}
</a>
</div>
</div>
<div class="fitted item">
<div class="ui action small input" id="clone-panel">
{{if not $.DisableHTTP}}
<button class="ui basic clone button" id="repo-clone-https" data-link="{{.WikiCloneLink.HTTPS}}">
Expand Down