mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-03 08:02:36 +09:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ce938b6c7 | ||
|
|
6139834e76 | ||
|
|
b673a24ee6 | ||
|
|
fd35f56e87 | ||
|
|
1f8df5dd89 | ||
|
|
6a025d8b4a | ||
|
|
270c7f36db | ||
|
|
0e448fb96d | ||
|
|
659b946eda | ||
|
|
56ab5ec9ea | ||
|
|
3b13c5d41a | ||
|
|
d27f061863 | ||
|
|
07489d0405 | ||
|
|
30708d9ffe | ||
|
|
1b08dfeacf | ||
|
|
e5ded0ee19 | ||
|
|
a384109244 |
21
CHANGELOG.md
21
CHANGELOG.md
@@ -4,6 +4,27 @@ This changelog goes through all the changes that have been made in each release
|
||||
without substantial changes to our git log; to see the highlights of what has
|
||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
|
||||
## [1.15.3](https://github.com/go-gitea/gitea/releases/tag/v1.15.3) - 2021-09-19
|
||||
|
||||
* ENHANCEMENTS
|
||||
* Add fluid to ui container class to remove margin (#16396) (#16976)
|
||||
* Add caller to cat-file batch calls (#17082) (#17089)
|
||||
* BUGFIXES
|
||||
* Render full plain readme. (#17083) (#17090)
|
||||
* Upgrade xorm to v1.2.4 (#17059)
|
||||
* Fix bug of migrate comments which only fetch one page (#17055) (#17058)
|
||||
* Do not show issue context popup on external issues (#17050) (#17054)
|
||||
* Decrement Fork Num when converting from Fork (#17035) (#17046)
|
||||
* Correctly rollback in ForkRepository (#17034) (#17045)
|
||||
* Fix missing close in WalkGitLog (#17008) (#17009)
|
||||
* Add prefix to SVG id/class attributes (#16997) (#17000)
|
||||
* Fix bug of migrated repository not index (#16991) (#16996)
|
||||
* Skip AllowedUserVisibilityModes validation on update user if it is an organisation (#16988) (#16990)
|
||||
* Fix storage Iterate bug and Add storage doctor to delete garbage attachments (#16971) (#16977)
|
||||
* Fix issue with issue default mail template (#16956) (#16975)
|
||||
* Ensure that rebase conflicts are handled in updates (#16952) (#16960)
|
||||
* Prevent panic on diff generation (#16950) (#16951)
|
||||
|
||||
## [1.15.2](https://github.com/go-gitea/gitea/releases/tag/v1.15.2) - 2021-09-03
|
||||
|
||||
* BUGFIXES
|
||||
|
||||
@@ -29,6 +29,7 @@ async function processFile(file, {prefix, fullName} = {}) {
|
||||
plugins: extendDefaultPlugins([
|
||||
'removeXMLNS',
|
||||
'removeDimensions',
|
||||
{name: 'prefixIds', params: {prefix: () => name}},
|
||||
{
|
||||
name: 'addClassesToSVGElement',
|
||||
params: {classNames: ['svg', name]},
|
||||
|
||||
@@ -124,7 +124,6 @@ func runRecreateTable(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
func runDoctor(ctx *cli.Context) error {
|
||||
|
||||
// Silence the default loggers
|
||||
log.DelNamedLogger("console")
|
||||
log.DelNamedLogger(log.DEFAULT)
|
||||
|
||||
2
go.mod
2
go.mod
@@ -139,7 +139,7 @@ require (
|
||||
mvdan.cc/xurls/v2 v2.2.0
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
|
||||
xorm.io/builder v0.3.9
|
||||
xorm.io/xorm v1.2.2
|
||||
xorm.io/xorm v1.2.4
|
||||
)
|
||||
|
||||
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
|
||||
|
||||
4
go.sum
4
go.sum
@@ -1765,5 +1765,5 @@ xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/builder v0.3.9 h1:Sd65/LdWyO7LR8+Cbd+e7mm3sK/7U9k0jS3999IDHMc=
|
||||
xorm.io/builder v0.3.9/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/xorm v1.0.6/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4=
|
||||
xorm.io/xorm v1.2.2 h1:FFBOEvJ++8fYBA9cywf2sxDVmFktl1SpJzTAG1ab06Y=
|
||||
xorm.io/xorm v1.2.2/go.mod h1:fTG8tSjk6O1BYxwuohZUK+S1glnRycsCF05L1qQyEU0=
|
||||
xorm.io/xorm v1.2.4 h1:2MQV4wJt4kY6CYJsLxjCLzBen7+aqVxqDTIwfnR59g4=
|
||||
xorm.io/xorm v1.2.4/go.mod h1:fTG8tSjk6O1BYxwuohZUK+S1glnRycsCF05L1qQyEU0=
|
||||
|
||||
@@ -144,6 +144,11 @@ func GetAttachmentByUUID(uuid string) (*Attachment, error) {
|
||||
return getAttachmentByUUID(x, uuid)
|
||||
}
|
||||
|
||||
// ExistAttachmentsByUUID returns true if attachment is exist by given UUID
|
||||
func ExistAttachmentsByUUID(uuid string) (bool, error) {
|
||||
return x.Where("`uuid`=?", uuid).Exist(new(Attachment))
|
||||
}
|
||||
|
||||
// GetAttachmentByReleaseIDFileName returns attachment by given releaseId and fileName.
|
||||
func GetAttachmentByReleaseIDFileName(releaseID int64, fileName string) (*Attachment, error) {
|
||||
return getAttachmentByReleaseIDFileName(x, releaseID, fileName)
|
||||
|
||||
@@ -45,19 +45,16 @@ func WithContext(f func(ctx DBContext) error) error {
|
||||
// WithTx represents executing database operations on a transaction
|
||||
func WithTx(f func(ctx DBContext) error) error {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
sess.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
if err := f(DBContext{sess}); err != nil {
|
||||
sess.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
err := sess.Commit()
|
||||
sess.Close()
|
||||
return err
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// Iterate iterates the databases and doing something
|
||||
|
||||
@@ -1217,6 +1217,12 @@ func IncrementRepoForkNum(ctx DBContext, repoID int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// DecrementRepoForkNum decrement repository fork number
|
||||
func DecrementRepoForkNum(ctx DBContext, repoID int64) error {
|
||||
_, err := ctx.e.Exec("UPDATE `repository` SET num_forks=num_forks-1 WHERE id=?", repoID)
|
||||
return err
|
||||
}
|
||||
|
||||
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
|
||||
func ChangeRepositoryName(doer *User, repo *Repository, newRepoName string) (err error) {
|
||||
oldRepoName := repo.Name
|
||||
|
||||
@@ -1062,9 +1062,9 @@ func checkDupEmail(e Engine, u *User) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateUser check if user is valide to insert / update into database
|
||||
// validateUser check if user is valid to insert / update into database
|
||||
func validateUser(u *User) error {
|
||||
if !setting.Service.AllowedUserVisibilityModesSlice.IsAllowedVisibility(u.Visibility) {
|
||||
if !setting.Service.AllowedUserVisibilityModesSlice.IsAllowedVisibility(u.Visibility) && !u.IsOrganization() {
|
||||
return fmt.Errorf("visibility Mode not allowed: %s", u.Visibility.String())
|
||||
}
|
||||
|
||||
|
||||
76
modules/doctor/storage.go
Normal file
76
modules/doctor/storage.go
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package doctor
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
)
|
||||
|
||||
func checkAttachmentStorageFiles(logger log.Logger, autofix bool) error {
|
||||
var total, garbageNum int
|
||||
var deletePaths []string
|
||||
if err := storage.Attachments.IterateObjects(func(p string, obj storage.Object) error {
|
||||
defer obj.Close()
|
||||
|
||||
total++
|
||||
stat, err := obj.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
exist, err := models.ExistAttachmentsByUUID(stat.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exist {
|
||||
garbageNum++
|
||||
if autofix {
|
||||
deletePaths = append(deletePaths, p)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
logger.Error("storage.Attachments.IterateObjects failed: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if garbageNum > 0 {
|
||||
if autofix {
|
||||
var deletedNum int
|
||||
for _, p := range deletePaths {
|
||||
if err := storage.Attachments.Delete(p); err != nil {
|
||||
log.Error("Delete attachment %s failed: %v", p, err)
|
||||
} else {
|
||||
deletedNum++
|
||||
}
|
||||
}
|
||||
logger.Info("%d missed information attachment detected, %d deleted.", garbageNum, deletedNum)
|
||||
} else {
|
||||
logger.Warn("Checked %d attachment, %d missed information.", total, garbageNum)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkStorageFiles(logger log.Logger, autofix bool) error {
|
||||
if err := storage.Init(); err != nil {
|
||||
logger.Error("storage.Init failed: %v", err)
|
||||
return err
|
||||
}
|
||||
return checkAttachmentStorageFiles(logger, autofix)
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(&Check{
|
||||
Title: "Check if there is garbage storage files",
|
||||
Name: "storages",
|
||||
IsDefault: false,
|
||||
Run: checkStorageFiles,
|
||||
AbortIfFailed: false,
|
||||
SkipDatabaseInitialization: false,
|
||||
Priority: 1,
|
||||
})
|
||||
}
|
||||
@@ -8,8 +8,10 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -40,9 +42,14 @@ func CatFileBatchCheck(repoPath string) (WriteCloserError, *bufio.Reader, func()
|
||||
<-closed
|
||||
}
|
||||
|
||||
_, filename, line, _ := runtime.Caller(2)
|
||||
filename = strings.TrimPrefix(filename, callerPrefix)
|
||||
|
||||
go func() {
|
||||
stderr := strings.Builder{}
|
||||
err := NewCommandContext(ctx, "cat-file", "--batch-check").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
|
||||
err := NewCommandContext(ctx, "cat-file", "--batch-check").
|
||||
SetDescription(fmt.Sprintf("%s cat-file --batch-check [repo_path: %s] (%s:%d)", GitExecutable, repoPath, filename, line)).
|
||||
RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
|
||||
if err != nil {
|
||||
_ = batchStdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
|
||||
_ = batchStdinReader.CloseWithError(ConcatenateError(err, (&stderr).String()))
|
||||
@@ -76,9 +83,14 @@ func CatFileBatch(repoPath string) (WriteCloserError, *bufio.Reader, func()) {
|
||||
<-closed
|
||||
}
|
||||
|
||||
_, filename, line, _ := runtime.Caller(2)
|
||||
filename = strings.TrimPrefix(filename, callerPrefix)
|
||||
|
||||
go func() {
|
||||
stderr := strings.Builder{}
|
||||
err := NewCommandContext(ctx, "cat-file", "--batch").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
|
||||
err := NewCommandContext(ctx, "cat-file", "--batch").
|
||||
SetDescription(fmt.Sprintf("%s cat-file --batch [repo_path: %s] (%s:%d)", GitExecutable, repoPath, filename, line)).
|
||||
RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
|
||||
if err != nil {
|
||||
_ = batchStdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
|
||||
_ = batchStdinReader.CloseWithError(ConcatenateError(err, (&stderr).String()))
|
||||
@@ -292,3 +304,10 @@ func ParseTreeLine(rd *bufio.Reader, modeBuf, fnameBuf, shaBuf []byte) (mode, fn
|
||||
sha = shaBuf
|
||||
return
|
||||
}
|
||||
|
||||
var callerPrefix string
|
||||
|
||||
func init() {
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
callerPrefix = strings.TrimSuffix(filename, "modules/git/batch_reader.go")
|
||||
}
|
||||
|
||||
@@ -18,11 +18,16 @@ import (
|
||||
)
|
||||
|
||||
// LogNameStatusRepo opens git log --raw in the provided repo and returns a stdin pipe, a stdout reader and cancel function
|
||||
func LogNameStatusRepo(repository, head, treepath string, paths ...string) (*bufio.Reader, func()) {
|
||||
func LogNameStatusRepo(ctx context.Context, repository, head, treepath string, paths ...string) (*bufio.Reader, func()) {
|
||||
// We often want to feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary.
|
||||
// so let's create a batch stdin and stdout
|
||||
stdoutReader, stdoutWriter := nio.Pipe(buffer.New(32 * 1024))
|
||||
|
||||
// Lets also create a context so that we can absolutely ensure that the command should die when we're done
|
||||
ctx, ctxCancel := context.WithCancel(ctx)
|
||||
|
||||
cancel := func() {
|
||||
ctxCancel()
|
||||
_ = stdoutReader.Close()
|
||||
_ = stdoutWriter.Close()
|
||||
}
|
||||
@@ -50,7 +55,7 @@ func LogNameStatusRepo(repository, head, treepath string, paths ...string) (*buf
|
||||
|
||||
go func() {
|
||||
stderr := strings.Builder{}
|
||||
err := NewCommand(args...).RunInDirFullPipeline(repository, stdoutWriter, &stderr, nil)
|
||||
err := NewCommandContext(ctx, args...).RunInDirFullPipeline(repository, stdoutWriter, &stderr, nil)
|
||||
if err != nil {
|
||||
_ = stdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
|
||||
} else {
|
||||
@@ -75,8 +80,8 @@ type LogNameStatusRepoParser struct {
|
||||
}
|
||||
|
||||
// NewLogNameStatusRepoParser returns a new parser for a git log raw output
|
||||
func NewLogNameStatusRepoParser(repository, head, treepath string, paths ...string) *LogNameStatusRepoParser {
|
||||
rd, cancel := LogNameStatusRepo(repository, head, treepath, paths...)
|
||||
func NewLogNameStatusRepoParser(ctx context.Context, repository, head, treepath string, paths ...string) *LogNameStatusRepoParser {
|
||||
rd, cancel := LogNameStatusRepo(ctx, repository, head, treepath, paths...)
|
||||
return &LogNameStatusRepoParser{
|
||||
treepath: treepath,
|
||||
paths: paths,
|
||||
@@ -311,8 +316,11 @@ func WalkGitLog(ctx context.Context, repo *Repository, head *Commit, treepath st
|
||||
}
|
||||
}
|
||||
|
||||
g := NewLogNameStatusRepoParser(repo.Path, head.ID.String(), treepath, paths...)
|
||||
defer g.Close()
|
||||
g := NewLogNameStatusRepoParser(ctx, repo.Path, head.ID.String(), treepath, paths...)
|
||||
// don't use defer g.Close() here as g may change its value - instead wrap in a func
|
||||
defer func() {
|
||||
g.Close()
|
||||
}()
|
||||
|
||||
results := make([]string, len(paths))
|
||||
remaining := len(paths)
|
||||
@@ -331,6 +339,7 @@ heaploop:
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
g.Close()
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
@@ -380,7 +389,7 @@ heaploop:
|
||||
remainingPaths = append(remainingPaths, pth)
|
||||
}
|
||||
}
|
||||
g = NewLogNameStatusRepoParser(repo.Path, lastEmptyParent, treepath, remainingPaths...)
|
||||
g = NewLogNameStatusRepoParser(ctx, repo.Path, lastEmptyParent, treepath, remainingPaths...)
|
||||
parentRemaining = map[string]bool{}
|
||||
nextRestart = (remaining * 3) / 4
|
||||
continue heaploop
|
||||
|
||||
@@ -827,7 +827,7 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
|
||||
reftext := node.Data[ref.RefLocation.Start:ref.RefLocation.End]
|
||||
if exttrack && !ref.IsPull {
|
||||
ctx.Metas["index"] = ref.Issue
|
||||
link = createLink(com.Expand(ctx.Metas["format"], ctx.Metas), reftext, "ref-issue")
|
||||
link = createLink(com.Expand(ctx.Metas["format"], ctx.Metas), reftext, "ref-issue ref-external-issue")
|
||||
} else {
|
||||
// Path determines the type of link that will be rendered. It's unknown at this point whether
|
||||
// the linked item is actually a PR or an issue. Luckily it's of no real consequence because
|
||||
|
||||
@@ -96,12 +96,14 @@ func TestRender_IssueIndexPattern2(t *testing.T) {
|
||||
// numeric: render inputs with valid mentions
|
||||
test := func(s, expectedFmt, marker string, indices ...int) {
|
||||
var path, prefix string
|
||||
isExternal := false
|
||||
if marker == "!" {
|
||||
path = "pulls"
|
||||
prefix = "http://localhost:3000/someUser/someRepo/pulls/"
|
||||
} else {
|
||||
path = "issues"
|
||||
prefix = "https://someurl.com/someUser/someRepo/"
|
||||
isExternal = true
|
||||
}
|
||||
|
||||
links := make([]interface{}, len(indices))
|
||||
@@ -111,8 +113,13 @@ func TestRender_IssueIndexPattern2(t *testing.T) {
|
||||
expectedNil := fmt.Sprintf(expectedFmt, links...)
|
||||
testRenderIssueIndexPattern(t, s, expectedNil, &RenderContext{Metas: localMetas})
|
||||
|
||||
class := "ref-issue"
|
||||
if isExternal {
|
||||
class += " ref-external-issue"
|
||||
}
|
||||
|
||||
for i, index := range indices {
|
||||
links[i] = numericIssueLink(prefix, "ref-issue", index, marker)
|
||||
links[i] = numericIssueLink(prefix, class, index, marker)
|
||||
}
|
||||
expectedNum := fmt.Sprintf(expectedFmt, links...)
|
||||
testRenderIssueIndexPattern(t, s, expectedNum, &RenderContext{Metas: numericMetas})
|
||||
@@ -178,7 +185,7 @@ func TestRender_IssueIndexPattern4(t *testing.T) {
|
||||
test := func(s, expectedFmt string, names ...string) {
|
||||
links := make([]interface{}, len(names))
|
||||
for i, name := range names {
|
||||
links[i] = alphanumIssueLink("https://someurl.com/someUser/someRepo/", "ref-issue", name)
|
||||
links[i] = alphanumIssueLink("https://someurl.com/someUser/someRepo/", "ref-issue ref-external-issue", name)
|
||||
}
|
||||
expected := fmt.Sprintf(expectedFmt, links...)
|
||||
testRenderIssueIndexPattern(t, s, expected, &RenderContext{Metas: alphanumericMetas})
|
||||
|
||||
@@ -66,7 +66,7 @@ func createDefaultPolicy() *bluemonday.Policy {
|
||||
}
|
||||
|
||||
// Allow classes for anchors
|
||||
policy.AllowAttrs("class").Matching(regexp.MustCompile(`ref-issue`)).OnElements("a")
|
||||
policy.AllowAttrs("class").Matching(regexp.MustCompile(`ref-issue( ref-external-issue)?`)).OnElements("a")
|
||||
|
||||
// Allow classes for task lists
|
||||
policy.AllowAttrs("class").Matching(regexp.MustCompile(`task-list-item`)).OnElements("li")
|
||||
|
||||
@@ -541,6 +541,9 @@ func (g *GithubDownloaderV3) GetAllComments(page, perPage int) ([]*base.Comment,
|
||||
created = "created"
|
||||
asc = "asc"
|
||||
)
|
||||
if perPage > g.maxPerPage {
|
||||
perPage = g.maxPerPage
|
||||
}
|
||||
opt := &github.IssueListCommentsOptions{
|
||||
Sort: &created,
|
||||
Direction: &asc,
|
||||
@@ -555,7 +558,9 @@ func (g *GithubDownloaderV3) GetAllComments(page, perPage int) ([]*base.Comment,
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error while listing repos: %v", err)
|
||||
}
|
||||
log.Trace("Request get comments %d/%d, but in fact get %d", perPage, page, len(comments))
|
||||
var isEnd = resp.NextPage == 0
|
||||
|
||||
log.Trace("Request get comments %d/%d, but in fact get %d, next page is %d", perPage, page, len(comments), resp.NextPage)
|
||||
g.rate = &resp.Rate
|
||||
for _, comment := range comments {
|
||||
var email string
|
||||
@@ -600,7 +605,7 @@ func (g *GithubDownloaderV3) GetAllComments(page, perPage int) ([]*base.Comment,
|
||||
})
|
||||
}
|
||||
|
||||
return allComments, len(allComments) < perPage, nil
|
||||
return allComments, isEnd, nil
|
||||
}
|
||||
|
||||
// GetPullRequests returns pull requests according page and perPage
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// ForkRepository forks a repository
|
||||
@@ -45,38 +46,60 @@ func ForkRepository(doer, owner *models.User, oldRepo *models.Repository, name,
|
||||
|
||||
oldRepoPath := oldRepo.RepoPath()
|
||||
|
||||
needsRollback := false
|
||||
rollbackFn := func() {
|
||||
if !needsRollback {
|
||||
return
|
||||
}
|
||||
|
||||
repoPath := models.RepoPath(owner.Name, repo.Name)
|
||||
|
||||
if exists, _ := util.IsExist(repoPath); !exists {
|
||||
return
|
||||
}
|
||||
|
||||
// As the transaction will be failed and hence database changes will be destroyed we only need
|
||||
// to delete the related repository on the filesystem
|
||||
if errDelete := util.RemoveAll(repoPath); errDelete != nil {
|
||||
log.Error("Failed to remove fork repo")
|
||||
}
|
||||
}
|
||||
|
||||
needsRollbackInPanic := true
|
||||
defer func() {
|
||||
panicErr := recover()
|
||||
if panicErr == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if needsRollbackInPanic {
|
||||
rollbackFn()
|
||||
}
|
||||
panic(panicErr)
|
||||
}()
|
||||
|
||||
err = models.WithTx(func(ctx models.DBContext) error {
|
||||
if err = models.CreateRepository(ctx, doer, owner, repo, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rollbackRemoveFn := func() {
|
||||
if repo.ID == 0 {
|
||||
return
|
||||
}
|
||||
if errDelete := models.DeleteRepository(doer, owner.ID, repo.ID); errDelete != nil {
|
||||
log.Error("Rollback deleteRepository: %v", errDelete)
|
||||
}
|
||||
}
|
||||
|
||||
if err = models.IncrementRepoForkNum(ctx, oldRepo.ID); err != nil {
|
||||
rollbackRemoveFn()
|
||||
return err
|
||||
}
|
||||
|
||||
// copy lfs files failure should not be ignored
|
||||
if err := models.CopyLFS(ctx, repo, oldRepo); err != nil {
|
||||
rollbackRemoveFn()
|
||||
if err = models.CopyLFS(ctx, repo, oldRepo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
needsRollback = true
|
||||
|
||||
repoPath := models.RepoPath(owner.Name, repo.Name)
|
||||
if stdout, err := git.NewCommand(
|
||||
"clone", "--bare", oldRepoPath, repoPath).
|
||||
SetDescription(fmt.Sprintf("ForkRepository(git clone): %s to %s", oldRepo.FullName(), repo.FullName())).
|
||||
RunInDirTimeout(10*time.Minute, ""); err != nil {
|
||||
log.Error("Fork Repository (git clone) Failed for %v (from %v):\nStdout: %s\nError: %v", repo, oldRepo, stdout, err)
|
||||
rollbackRemoveFn()
|
||||
return fmt.Errorf("git clone: %v", err)
|
||||
}
|
||||
|
||||
@@ -84,23 +107,23 @@ func ForkRepository(doer, owner *models.User, oldRepo *models.Repository, name,
|
||||
SetDescription(fmt.Sprintf("ForkRepository(git update-server-info): %s", repo.FullName())).
|
||||
RunInDir(repoPath); err != nil {
|
||||
log.Error("Fork Repository (git update-server-info) failed for %v:\nStdout: %s\nError: %v", repo, stdout, err)
|
||||
rollbackRemoveFn()
|
||||
return fmt.Errorf("git update-server-info: %v", err)
|
||||
}
|
||||
|
||||
if err = createDelegateHooks(repoPath); err != nil {
|
||||
rollbackRemoveFn()
|
||||
return fmt.Errorf("createDelegateHooks: %v", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
needsRollbackInPanic = false
|
||||
if err != nil {
|
||||
rollbackFn()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// even if below operations failed, it could be ignored. And they will be retried
|
||||
ctx := models.DefaultDBContext()
|
||||
if err = repo.UpdateSize(ctx); err != nil {
|
||||
if err := repo.UpdateSize(ctx); err != nil {
|
||||
log.Error("Failed to update size for repository: %v", err)
|
||||
}
|
||||
if err := models.CopyLanguageStat(oldRepo, repo); err != nil {
|
||||
@@ -109,3 +132,34 @@ func ForkRepository(doer, owner *models.User, oldRepo *models.Repository, name,
|
||||
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
// ConvertForkToNormalRepository convert the provided repo from a forked repo to normal repo
|
||||
func ConvertForkToNormalRepository(repo *models.Repository) error {
|
||||
err := models.WithTx(func(ctx models.DBContext) error {
|
||||
repo, err := models.GetRepositoryByIDCtx(ctx, repo.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !repo.IsFork {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := models.DecrementRepoForkNum(ctx, repo.ForkID); err != nil {
|
||||
log.Error("Unable to decrement repo fork num for old root repo %d of repository %-v whilst converting from fork. Error: %v", repo.ForkID, repo, err)
|
||||
return err
|
||||
}
|
||||
|
||||
repo.IsFork = false
|
||||
repo.ForkID = 0
|
||||
|
||||
if err := models.UpdateRepositoryCtx(ctx, repo, false); err != nil {
|
||||
log.Error("Unable to update repository %-v whilst converting from fork. Error: %v", repo, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ type minioFileInfo struct {
|
||||
}
|
||||
|
||||
func (m minioFileInfo) Name() string {
|
||||
return m.ObjectInfo.Key
|
||||
return path.Base(m.ObjectInfo.Key)
|
||||
}
|
||||
|
||||
func (m minioFileInfo) Size() int64 {
|
||||
@@ -219,7 +219,7 @@ func (m *MinioStorage) IterateObjects(fn func(path string, obj Object) error) er
|
||||
}
|
||||
if err := func(object *minio.Object, fn func(path string, obj Object) error) error {
|
||||
defer object.Close()
|
||||
return fn(strings.TrimPrefix(m.basePath, mObjInfo.Key), &minioObject{object})
|
||||
return fn(strings.TrimPrefix(mObjInfo.Key, m.basePath), &minioObject{object})
|
||||
}(object, fn); err != nil {
|
||||
return convertMinioErr(err)
|
||||
}
|
||||
|
||||
@@ -93,7 +93,6 @@ func runMigrateTask(t *models.Task) (err error) {
|
||||
}
|
||||
|
||||
opts.MigrateToRepoID = t.RepoID
|
||||
var repo *models.Repository
|
||||
|
||||
ctx, cancel := context.WithCancel(graceful.GetManager().ShutdownContext())
|
||||
defer cancel()
|
||||
@@ -107,7 +106,7 @@ func runMigrateTask(t *models.Task) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
repo, err = migrations.MigrateRepository(ctx, t.Doer, t.Owner.Name, *opts, func(format string, args ...interface{}) {
|
||||
t.Repo, err = migrations.MigrateRepository(ctx, t.Doer, t.Owner.Name, *opts, func(format string, args ...interface{}) {
|
||||
message := models.TranslatableMessage{
|
||||
Format: format,
|
||||
Args: args,
|
||||
@@ -118,7 +117,7 @@ func runMigrateTask(t *models.Task) (err error) {
|
||||
_ = t.UpdateCols("message")
|
||||
})
|
||||
if err == nil {
|
||||
log.Trace("Repository migrated [%d]: %s/%s", repo.ID, t.Owner.Name, repo.Name)
|
||||
log.Trace("Repository migrated [%d]: %s/%s", t.Repo.ID, t.Owner.Name, t.Repo.Name)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
<svg viewBox="0 0 64 64" class="svg gitea-github" width="16" height="16" aria-hidden="true"><linearGradient id="a" x1="30.999" x2="30.999" y1="16" y2="55.342" gradientUnits="userSpaceOnUse" spreadMethod="reflect"><stop offset="0" stop-color="#6dc7ff"/><stop offset="1" stop-color="#e6abff"/></linearGradient><path fill="url(#a)" d="M25.008 56.007c-.003-.368-.006-1.962-.009-3.454l-.003-1.55c-6.729.915-8.358-3.78-8.376-3.83-.934-2.368-2.211-3.045-2.266-3.073l-.124-.072c-.463-.316-1.691-1.157-1.342-2.263.315-.997 1.536-1.1 2.091-1.082 3.074.215 4.63 2.978 4.694 3.095 1.569 2.689 3.964 2.411 5.509 1.844.144-.688.367-1.32.659-1.878-4.956-.879-10.571-3.515-10.571-13.104 0-2.633.82-4.96 2.441-6.929-.362-1.206-.774-3.666.446-6.765l.174-.442.452-.144c.416-.137 2.688-.624 7.359 2.433a24.959 24.959 0 0 1 6.074-.759c2.115.01 4.158.265 6.09.759 4.667-3.058 6.934-2.565 7.351-2.433l.451.145.174.44c1.225 3.098.813 5.559.451 6.766 1.618 1.963 2.438 4.291 2.438 6.929 0 9.591-5.621 12.219-10.588 13.087.563 1.065.868 2.402.868 3.878 0 1.683-.007 7.204-.015 8.402l-2-.014c.008-1.196.015-6.708.015-8.389 0-2.442-.943-3.522-1.35-3.874l-1.73-1.497 2.274-.253c5.205-.578 10.525-2.379 10.525-11.341 0-2.33-.777-4.361-2.31-6.036l-.43-.469.242-.587c.166-.401.894-2.442-.043-5.291-.758.045-2.568.402-5.584 2.447l-.384.259-.445-.123c-1.863-.518-3.938-.796-6.001-.806-2.052.01-4.124.288-5.984.806l-.445.123-.383-.259c-3.019-2.044-4.833-2.404-5.594-2.449-.935 2.851-.206 4.892-.04 5.293l.242.587-.429.469c-1.536 1.681-2.314 3.712-2.314 6.036 0 8.958 5.31 10.77 10.504 11.361l2.252.256-1.708 1.49c-.372.325-1.03 1.112-1.254 2.727l-.075.549-.506.227c-1.321.592-5.839 2.162-8.548-2.485-.015-.025-.544-.945-1.502-1.557.646.639 1.433 1.673 2.068 3.287.066.19 1.357 3.622 7.28 2.339l1.206-.262.012 3.978c.003 1.487.006 3.076.009 3.444l-1.998.014z"/><linearGradient id="b" x1="32" x2="32" y1="5" y2="59.167" gradientUnits="userSpaceOnUse" spreadMethod="reflect"><stop offset="0" stop-color="#1a6dff"/><stop offset="1" stop-color="#c822ff"/></linearGradient><path fill="url(#b)" d="M32 58C17.663 58 6 46.337 6 32S17.663 6 32 6s26 11.663 26 26-11.663 26-26 26zm0-50C18.767 8 8 18.767 8 32s10.767 24 24 24 24-10.767 24-24S45.233 8 32 8z"/></svg>
|
||||
<svg viewBox="0 0 64 64" class="svg gitea-github" width="16" height="16" aria-hidden="true"><linearGradient id="gitea-github__a" x1="30.999" x2="30.999" y1="16" y2="55.342" gradientUnits="userSpaceOnUse" spreadMethod="reflect"><stop offset="0" stop-color="#6dc7ff"/><stop offset="1" stop-color="#e6abff"/></linearGradient><path fill="url(#gitea-github__a)" d="M25.008 56.007c-.003-.368-.006-1.962-.009-3.454l-.003-1.55c-6.729.915-8.358-3.78-8.376-3.83-.934-2.368-2.211-3.045-2.266-3.073l-.124-.072c-.463-.316-1.691-1.157-1.342-2.263.315-.997 1.536-1.1 2.091-1.082 3.074.215 4.63 2.978 4.694 3.095 1.569 2.689 3.964 2.411 5.509 1.844.144-.688.367-1.32.659-1.878-4.956-.879-10.571-3.515-10.571-13.104 0-2.633.82-4.96 2.441-6.929-.362-1.206-.774-3.666.446-6.765l.174-.442.452-.144c.416-.137 2.688-.624 7.359 2.433a24.959 24.959 0 0 1 6.074-.759c2.115.01 4.158.265 6.09.759 4.667-3.058 6.934-2.565 7.351-2.433l.451.145.174.44c1.225 3.098.813 5.559.451 6.766 1.618 1.963 2.438 4.291 2.438 6.929 0 9.591-5.621 12.219-10.588 13.087.563 1.065.868 2.402.868 3.878 0 1.683-.007 7.204-.015 8.402l-2-.014c.008-1.196.015-6.708.015-8.389 0-2.442-.943-3.522-1.35-3.874l-1.73-1.497 2.274-.253c5.205-.578 10.525-2.379 10.525-11.341 0-2.33-.777-4.361-2.31-6.036l-.43-.469.242-.587c.166-.401.894-2.442-.043-5.291-.758.045-2.568.402-5.584 2.447l-.384.259-.445-.123c-1.863-.518-3.938-.796-6.001-.806-2.052.01-4.124.288-5.984.806l-.445.123-.383-.259c-3.019-2.044-4.833-2.404-5.594-2.449-.935 2.851-.206 4.892-.04 5.293l.242.587-.429.469c-1.536 1.681-2.314 3.712-2.314 6.036 0 8.958 5.31 10.77 10.504 11.361l2.252.256-1.708 1.49c-.372.325-1.03 1.112-1.254 2.727l-.075.549-.506.227c-1.321.592-5.839 2.162-8.548-2.485-.015-.025-.544-.945-1.502-1.557.646.639 1.433 1.673 2.068 3.287.066.19 1.357 3.622 7.28 2.339l1.206-.262.012 3.978c.003 1.487.006 3.076.009 3.444l-1.998.014z"/><linearGradient id="gitea-github__b" x1="32" x2="32" y1="5" y2="59.167" gradientUnits="userSpaceOnUse" spreadMethod="reflect"><stop offset="0" stop-color="#1a6dff"/><stop offset="1" stop-color="#c822ff"/></linearGradient><path fill="url(#gitea-github__b)" d="M32 58C17.663 58 6 46.337 6 32S17.663 6 32 6s26 11.663 26 26-11.663 26-26 26zm0-50C18.767 8 8 18.767 8 32s10.767 24 24 24 24-10.767 24-24S45.233 8 32 8z"/></svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
@@ -119,13 +119,15 @@ func GetArchive(ctx *context.APIContext) {
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
repoPath := models.RepoPath(ctx.Params(":username"), ctx.Params(":reponame"))
|
||||
gitRepo, err := git.OpenRepository(repoPath)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
|
||||
return
|
||||
if ctx.Repo.GitRepo == nil {
|
||||
gitRepo, err := git.OpenRepository(repoPath)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.GitRepo = gitRepo
|
||||
defer gitRepo.Close()
|
||||
}
|
||||
ctx.Repo.GitRepo = gitRepo
|
||||
defer gitRepo.Close()
|
||||
|
||||
repo.Download(ctx.Context)
|
||||
}
|
||||
|
||||
@@ -1130,6 +1130,9 @@ func UpdatePullRequest(ctx *context.APIContext) {
|
||||
if models.IsErrMergeConflicts(err) {
|
||||
ctx.Error(http.StatusConflict, "Update", "merge failed because of conflict")
|
||||
return
|
||||
} else if models.IsErrRebaseConflicts(err) {
|
||||
ctx.Error(http.StatusConflict, "Update", "rebase failed because of conflict")
|
||||
return
|
||||
}
|
||||
ctx.Error(http.StatusInternalServerError, "pull_service.Update", err)
|
||||
return
|
||||
|
||||
@@ -752,6 +752,21 @@ func UpdatePullRequest(ctx *context.Context) {
|
||||
ctx.Flash.Error(flashError)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
|
||||
return
|
||||
} else if models.IsErrRebaseConflicts(err) {
|
||||
conflictError := err.(models.ErrRebaseConflicts)
|
||||
flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{
|
||||
"Message": ctx.Tr("repo.pulls.rebase_conflict", utils.SanitizeFlashErrorString(conflictError.CommitSHA)),
|
||||
"Summary": ctx.Tr("repo.pulls.rebase_conflict_summary"),
|
||||
"Details": utils.SanitizeFlashErrorString(conflictError.StdErr) + "<br>" + utils.SanitizeFlashErrorString(conflictError.StdOut),
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("UpdatePullRequest.HTMLString", err)
|
||||
return
|
||||
}
|
||||
ctx.Flash.Error(flashError)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
|
||||
return
|
||||
|
||||
}
|
||||
ctx.Flash.Error(err.Error())
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
|
||||
|
||||
@@ -538,10 +538,8 @@ func SettingsPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
repo.IsFork = false
|
||||
repo.ForkID = 0
|
||||
if err := models.UpdateRepository(repo, false); err != nil {
|
||||
log.Error("Unable to update repository %-v whilst converting from fork", repo)
|
||||
if err := repository.ConvertForkToNormalRepository(repo); err != nil {
|
||||
log.Error("Unable to convert repository %-v from fork. Error: %v", repo, err)
|
||||
ctx.ServerError("Convert Fork", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -353,6 +353,10 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
||||
}
|
||||
} else {
|
||||
ctx.Data["IsRenderedHTML"] = true
|
||||
buf, err = ioutil.ReadAll(rd)
|
||||
if err != nil {
|
||||
log.Error("ReadAll failed: %v", err)
|
||||
}
|
||||
ctx.Data["FileContent"] = strings.ReplaceAll(
|
||||
gotemplate.HTMLEscapeString(string(buf)), "\n", `<br>`,
|
||||
)
|
||||
|
||||
@@ -996,6 +996,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
|
||||
|
||||
// Create a new section to represent this hunk
|
||||
curSection = &DiffSection{}
|
||||
lastLeftIdx = -1
|
||||
curFile.Sections = append(curFile.Sections, curSection)
|
||||
|
||||
lineSectionInfo := getDiffLineSectionInfo(curFile.Name, line, leftLine-1, rightLine-1)
|
||||
@@ -1036,6 +1037,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
|
||||
// Create a new section to represent this hunk
|
||||
curSection = &DiffSection{}
|
||||
curFile.Sections = append(curFile.Sections, curSection)
|
||||
lastLeftIdx = -1
|
||||
}
|
||||
if lastLeftIdx > -1 {
|
||||
diffLine.Match = lastLeftIdx
|
||||
@@ -1061,6 +1063,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
|
||||
// Create a new section to represent this hunk
|
||||
curSection = &DiffSection{}
|
||||
curFile.Sections = append(curFile.Sections, curSection)
|
||||
lastLeftIdx = -1
|
||||
}
|
||||
if len(curSection.Lines) == 0 || curSection.Lines[len(curSection.Lines)-1].Type != DiffLineDel {
|
||||
lastLeftIdx = len(curSection.Lines)
|
||||
@@ -1121,6 +1124,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
|
||||
curFile.IsBin = true
|
||||
curFile.IsLFSFile = true
|
||||
curSection.Lines = nil
|
||||
lastLeftIdx = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
{{end -}}
|
||||
{{- range .ReviewComments}}
|
||||
<hr>
|
||||
{{.i18n.Tr "mail.issue.in_tree_path" .TreePath}}
|
||||
{{$.i18n.Tr "mail.issue.in_tree_path" .TreePath}}
|
||||
<div class="review">
|
||||
<pre>{{.Patch}}</pre>
|
||||
<div>{{.RenderedContent | Safe}}</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="page-content user signin{{if .LinkAccountMode}} icon{{end}}">
|
||||
{{template "user/auth/signin_navbar" .}}
|
||||
<div class="ui middle very relaxed page grid">
|
||||
<div class="ui container column">
|
||||
<div class="ui container column fluid">
|
||||
{{template "user/auth/signin_inner" .}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="ui container column{{if .LinkAccountMode}} icon{{end}}">
|
||||
<div class="ui container column fluid{{if .LinkAccountMode}} icon{{end}}">
|
||||
<h4 class="ui top attached header center">
|
||||
{{if .LinkAccountMode}}
|
||||
{{.i18n.Tr "auth.oauth_signup_title"}}
|
||||
|
||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -1047,7 +1047,7 @@ strk.kbt.io/projects/go/libravatar
|
||||
# xorm.io/builder v0.3.9
|
||||
## explicit
|
||||
xorm.io/builder
|
||||
# xorm.io/xorm v1.2.2
|
||||
# xorm.io/xorm v1.2.4
|
||||
## explicit
|
||||
xorm.io/xorm
|
||||
xorm.io/xorm/caches
|
||||
|
||||
3
vendor/xorm.io/xorm/convert/conversion.go
generated
vendored
3
vendor/xorm.io/xorm/convert/conversion.go
generated
vendored
@@ -325,6 +325,9 @@ func AssignValue(dv reflect.Value, src interface{}) error {
|
||||
if src == nil {
|
||||
return nil
|
||||
}
|
||||
if v, ok := src.(*interface{}); ok {
|
||||
return AssignValue(dv, *v)
|
||||
}
|
||||
|
||||
if dv.Type().Implements(scannerType) {
|
||||
return dv.Interface().(sql.Scanner).Scan(src)
|
||||
|
||||
33
vendor/xorm.io/xorm/dialects/dialect.go
generated
vendored
33
vendor/xorm.io/xorm/dialects/dialect.go
generated
vendored
@@ -103,6 +103,39 @@ func (db *Base) URI() *URI {
|
||||
return db.uri
|
||||
}
|
||||
|
||||
// CreateTableSQL implements Dialect
|
||||
func (db *Base) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) {
|
||||
if tableName == "" {
|
||||
tableName = table.Name
|
||||
}
|
||||
|
||||
quoter := db.dialect.Quoter()
|
||||
var b strings.Builder
|
||||
b.WriteString("CREATE TABLE IF NOT EXISTS ")
|
||||
quoter.QuoteTo(&b, tableName)
|
||||
b.WriteString(" (")
|
||||
|
||||
for i, colName := range table.ColumnsSeq() {
|
||||
col := table.GetColumn(colName)
|
||||
s, _ := ColumnString(db.dialect, col, col.IsPrimaryKey && len(table.PrimaryKeys) == 1)
|
||||
b.WriteString(s)
|
||||
|
||||
if i != len(table.ColumnsSeq())-1 {
|
||||
b.WriteString(", ")
|
||||
}
|
||||
}
|
||||
|
||||
if len(table.PrimaryKeys) > 1 {
|
||||
b.WriteString(", PRIMARY KEY (")
|
||||
b.WriteString(quoter.Join(table.PrimaryKeys, ","))
|
||||
b.WriteString(")")
|
||||
}
|
||||
|
||||
b.WriteString(")")
|
||||
|
||||
return []string{b.String()}, false
|
||||
}
|
||||
|
||||
// DropTableSQL returns drop table SQL
|
||||
func (db *Base) DropTableSQL(tableName string) (string, bool) {
|
||||
quote := db.dialect.Quoter().Quote
|
||||
|
||||
39
vendor/xorm.io/xorm/dialects/mssql.go
generated
vendored
39
vendor/xorm.io/xorm/dialects/mssql.go
generated
vendored
@@ -626,34 +626,37 @@ WHERE IXS.TYPE_DESC='NONCLUSTERED' and OBJECT_NAME(IXS.OBJECT_ID) =?
|
||||
}
|
||||
|
||||
func (db *mssql) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) {
|
||||
var sql string
|
||||
if tableName == "" {
|
||||
tableName = table.Name
|
||||
}
|
||||
|
||||
sql = "IF NOT EXISTS (SELECT [name] FROM sys.tables WHERE [name] = '" + tableName + "' ) CREATE TABLE "
|
||||
quoter := db.dialect.Quoter()
|
||||
var b strings.Builder
|
||||
b.WriteString("IF NOT EXISTS (SELECT [name] FROM sys.tables WHERE [name] = '")
|
||||
quoter.QuoteTo(&b, tableName)
|
||||
b.WriteString("' ) CREATE TABLE ")
|
||||
quoter.QuoteTo(&b, tableName)
|
||||
b.WriteString(" (")
|
||||
|
||||
sql += db.Quoter().Quote(tableName) + " ("
|
||||
|
||||
pkList := table.PrimaryKeys
|
||||
|
||||
for _, colName := range table.ColumnsSeq() {
|
||||
for i, colName := range table.ColumnsSeq() {
|
||||
col := table.GetColumn(colName)
|
||||
s, _ := ColumnString(db, col, col.IsPrimaryKey && len(pkList) == 1)
|
||||
sql += s
|
||||
sql = strings.TrimSpace(sql)
|
||||
sql += ", "
|
||||
s, _ := ColumnString(db.dialect, col, col.IsPrimaryKey && len(table.PrimaryKeys) == 1)
|
||||
b.WriteString(s)
|
||||
|
||||
if i != len(table.ColumnsSeq())-1 {
|
||||
b.WriteString(", ")
|
||||
}
|
||||
}
|
||||
|
||||
if len(pkList) > 1 {
|
||||
sql += "PRIMARY KEY ( "
|
||||
sql += strings.Join(pkList, ",")
|
||||
sql += " ), "
|
||||
if len(table.PrimaryKeys) > 1 {
|
||||
b.WriteString(", PRIMARY KEY (")
|
||||
b.WriteString(quoter.Join(table.PrimaryKeys, ","))
|
||||
b.WriteString(")")
|
||||
}
|
||||
|
||||
sql = sql[:len(sql)-2] + ")"
|
||||
sql += ";"
|
||||
return []string{sql}, true
|
||||
b.WriteString(")")
|
||||
|
||||
return []string{b.String()}, true
|
||||
}
|
||||
|
||||
func (db *mssql) ForUpdateSQL(query string) string {
|
||||
|
||||
57
vendor/xorm.io/xorm/dialects/mysql.go
generated
vendored
57
vendor/xorm.io/xorm/dialects/mysql.go
generated
vendored
@@ -626,42 +626,43 @@ func (db *mysql) GetIndexes(queryer core.Queryer, ctx context.Context, tableName
|
||||
}
|
||||
|
||||
func (db *mysql) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) {
|
||||
var sql = "CREATE TABLE IF NOT EXISTS "
|
||||
if tableName == "" {
|
||||
tableName = table.Name
|
||||
}
|
||||
|
||||
quoter := db.Quoter()
|
||||
quoter := db.dialect.Quoter()
|
||||
var b strings.Builder
|
||||
b.WriteString("CREATE TABLE IF NOT EXISTS ")
|
||||
quoter.QuoteTo(&b, tableName)
|
||||
b.WriteString(" (")
|
||||
|
||||
sql += quoter.Quote(tableName)
|
||||
sql += " ("
|
||||
for i, colName := range table.ColumnsSeq() {
|
||||
col := table.GetColumn(colName)
|
||||
s, _ := ColumnString(db.dialect, col, col.IsPrimaryKey && len(table.PrimaryKeys) == 1)
|
||||
b.WriteString(s)
|
||||
|
||||
if len(table.ColumnsSeq()) > 0 {
|
||||
pkList := table.PrimaryKeys
|
||||
|
||||
for _, colName := range table.ColumnsSeq() {
|
||||
col := table.GetColumn(colName)
|
||||
s, _ := ColumnString(db, col, col.IsPrimaryKey && len(pkList) == 1)
|
||||
sql += s
|
||||
sql = strings.TrimSpace(sql)
|
||||
if len(col.Comment) > 0 {
|
||||
sql += " COMMENT '" + col.Comment + "'"
|
||||
}
|
||||
sql += ", "
|
||||
if len(col.Comment) > 0 {
|
||||
b.WriteString(" COMMENT '")
|
||||
b.WriteString(col.Comment)
|
||||
b.WriteString("'")
|
||||
}
|
||||
|
||||
if len(pkList) > 1 {
|
||||
sql += "PRIMARY KEY ( "
|
||||
sql += quoter.Join(pkList, ",")
|
||||
sql += " ), "
|
||||
if i != len(table.ColumnsSeq())-1 {
|
||||
b.WriteString(", ")
|
||||
}
|
||||
|
||||
sql = sql[:len(sql)-2]
|
||||
}
|
||||
sql += ")"
|
||||
|
||||
if len(table.PrimaryKeys) > 1 {
|
||||
b.WriteString(", PRIMARY KEY (")
|
||||
b.WriteString(quoter.Join(table.PrimaryKeys, ","))
|
||||
b.WriteString(")")
|
||||
}
|
||||
|
||||
b.WriteString(")")
|
||||
|
||||
if table.StoreEngine != "" {
|
||||
sql += " ENGINE=" + table.StoreEngine
|
||||
b.WriteString(" ENGINE=")
|
||||
b.WriteString(table.StoreEngine)
|
||||
}
|
||||
|
||||
var charset = table.Charset
|
||||
@@ -669,13 +670,15 @@ func (db *mysql) CreateTableSQL(table *schemas.Table, tableName string) ([]strin
|
||||
charset = db.URI().Charset
|
||||
}
|
||||
if len(charset) != 0 {
|
||||
sql += " DEFAULT CHARSET " + charset
|
||||
b.WriteString(" DEFAULT CHARSET ")
|
||||
b.WriteString(charset)
|
||||
}
|
||||
|
||||
if db.rowFormat != "" {
|
||||
sql += " ROW_FORMAT=" + db.rowFormat
|
||||
b.WriteString(" ROW_FORMAT=")
|
||||
b.WriteString(db.rowFormat)
|
||||
}
|
||||
return []string{sql}, true
|
||||
return []string{b.String()}, true
|
||||
}
|
||||
|
||||
func (db *mysql) Filters() []Filter {
|
||||
|
||||
35
vendor/xorm.io/xorm/dialects/postgres.go
generated
vendored
35
vendor/xorm.io/xorm/dialects/postgres.go
generated
vendored
@@ -965,41 +965,6 @@ func (db *postgres) AutoIncrStr() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (db *postgres) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) {
|
||||
var sql string
|
||||
sql = "CREATE TABLE IF NOT EXISTS "
|
||||
if tableName == "" {
|
||||
tableName = table.Name
|
||||
}
|
||||
|
||||
quoter := db.Quoter()
|
||||
sql += quoter.Quote(tableName)
|
||||
sql += " ("
|
||||
|
||||
if len(table.ColumnsSeq()) > 0 {
|
||||
pkList := table.PrimaryKeys
|
||||
|
||||
for _, colName := range table.ColumnsSeq() {
|
||||
col := table.GetColumn(colName)
|
||||
s, _ := ColumnString(db, col, col.IsPrimaryKey && len(pkList) == 1)
|
||||
sql += s
|
||||
sql = strings.TrimSpace(sql)
|
||||
sql += ", "
|
||||
}
|
||||
|
||||
if len(pkList) > 1 {
|
||||
sql += "PRIMARY KEY ( "
|
||||
sql += quoter.Join(pkList, ",")
|
||||
sql += " ), "
|
||||
}
|
||||
|
||||
sql = sql[:len(sql)-2]
|
||||
}
|
||||
sql += ")"
|
||||
|
||||
return []string{sql}, true
|
||||
}
|
||||
|
||||
func (db *postgres) IndexCheckSQL(tableName, idxName string) (string, []interface{}) {
|
||||
if len(db.getSchema()) == 0 {
|
||||
args := []interface{}{tableName, idxName}
|
||||
|
||||
35
vendor/xorm.io/xorm/dialects/sqlite3.go
generated
vendored
35
vendor/xorm.io/xorm/dialects/sqlite3.go
generated
vendored
@@ -285,41 +285,6 @@ func (db *sqlite3) DropIndexSQL(tableName string, index *schemas.Index) string {
|
||||
return fmt.Sprintf("DROP INDEX %v", db.Quoter().Quote(idxName))
|
||||
}
|
||||
|
||||
func (db *sqlite3) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) {
|
||||
var sql string
|
||||
sql = "CREATE TABLE IF NOT EXISTS "
|
||||
if tableName == "" {
|
||||
tableName = table.Name
|
||||
}
|
||||
|
||||
quoter := db.Quoter()
|
||||
sql += quoter.Quote(tableName)
|
||||
sql += " ("
|
||||
|
||||
if len(table.ColumnsSeq()) > 0 {
|
||||
pkList := table.PrimaryKeys
|
||||
|
||||
for _, colName := range table.ColumnsSeq() {
|
||||
col := table.GetColumn(colName)
|
||||
s, _ := ColumnString(db, col, col.IsPrimaryKey && len(pkList) == 1)
|
||||
sql += s
|
||||
sql = strings.TrimSpace(sql)
|
||||
sql += ", "
|
||||
}
|
||||
|
||||
if len(pkList) > 1 {
|
||||
sql += "PRIMARY KEY ( "
|
||||
sql += quoter.Join(pkList, ",")
|
||||
sql += " ), "
|
||||
}
|
||||
|
||||
sql = sql[:len(sql)-2]
|
||||
}
|
||||
sql += ")"
|
||||
|
||||
return []string{sql}, true
|
||||
}
|
||||
|
||||
func (db *sqlite3) ForUpdateSQL(query string) string {
|
||||
return query
|
||||
}
|
||||
|
||||
25
vendor/xorm.io/xorm/internal/utils/new.go
generated
vendored
Normal file
25
vendor/xorm.io/xorm/internal/utils/new.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2021 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package utils
|
||||
|
||||
import "reflect"
|
||||
|
||||
// New creates a value according type
|
||||
func New(tp reflect.Type, length, cap int) reflect.Value {
|
||||
switch tp.Kind() {
|
||||
case reflect.Slice:
|
||||
slice := reflect.MakeSlice(tp, length, cap)
|
||||
x := reflect.New(slice.Type())
|
||||
x.Elem().Set(slice)
|
||||
return x
|
||||
case reflect.Map:
|
||||
mp := reflect.MakeMapWithSize(tp, cap)
|
||||
x := reflect.New(mp.Type())
|
||||
x.Elem().Set(mp)
|
||||
return x
|
||||
default:
|
||||
return reflect.New(tp)
|
||||
}
|
||||
}
|
||||
10
vendor/xorm.io/xorm/rows.go
generated
vendored
10
vendor/xorm.io/xorm/rows.go
generated
vendored
@@ -84,12 +84,18 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
|
||||
|
||||
// Next move cursor to next record, return false if end has reached
|
||||
func (rows *Rows) Next() bool {
|
||||
return rows.rows.Next()
|
||||
if rows.rows != nil {
|
||||
return rows.rows.Next()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Err returns the error, if any, that was encountered during iteration. Err may be called after an explicit or implicit Close.
|
||||
func (rows *Rows) Err() error {
|
||||
return rows.rows.Err()
|
||||
if rows.rows != nil {
|
||||
return rows.rows.Err()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Scan row record to bean properties
|
||||
|
||||
5
vendor/xorm.io/xorm/session.go
generated
vendored
5
vendor/xorm.io/xorm/session.go
generated
vendored
@@ -174,6 +174,11 @@ func (session *Session) Engine() *Engine {
|
||||
return session.engine
|
||||
}
|
||||
|
||||
// Tx returns session tx
|
||||
func (session *Session) Tx() *core.Tx {
|
||||
return session.tx
|
||||
}
|
||||
|
||||
func (session *Session) getQueryer() core.Queryer {
|
||||
if session.tx != nil {
|
||||
return session.tx
|
||||
|
||||
62
vendor/xorm.io/xorm/session_find.go
generated
vendored
62
vendor/xorm.io/xorm/session_find.go
generated
vendored
@@ -161,6 +161,16 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||
}
|
||||
|
||||
func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect.Value, sqlStr string, args ...interface{}) error {
|
||||
elemType := containerValue.Type().Elem()
|
||||
var isPointer bool
|
||||
if elemType.Kind() == reflect.Ptr {
|
||||
isPointer = true
|
||||
elemType = elemType.Elem()
|
||||
}
|
||||
if elemType.Kind() == reflect.Ptr {
|
||||
return errors.New("pointer to pointer is not supported")
|
||||
}
|
||||
|
||||
rows, err := session.queryRows(sqlStr, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -177,31 +187,8 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
|
||||
return err
|
||||
}
|
||||
|
||||
var newElemFunc func(fields []string) reflect.Value
|
||||
elemType := containerValue.Type().Elem()
|
||||
var isPointer bool
|
||||
if elemType.Kind() == reflect.Ptr {
|
||||
isPointer = true
|
||||
elemType = elemType.Elem()
|
||||
}
|
||||
if elemType.Kind() == reflect.Ptr {
|
||||
return errors.New("pointer to pointer is not supported")
|
||||
}
|
||||
|
||||
newElemFunc = func(fields []string) reflect.Value {
|
||||
switch elemType.Kind() {
|
||||
case reflect.Slice:
|
||||
slice := reflect.MakeSlice(elemType, len(fields), len(fields))
|
||||
x := reflect.New(slice.Type())
|
||||
x.Elem().Set(slice)
|
||||
return x
|
||||
case reflect.Map:
|
||||
mp := reflect.MakeMap(elemType)
|
||||
x := reflect.New(mp.Type())
|
||||
x.Elem().Set(mp)
|
||||
return x
|
||||
}
|
||||
return reflect.New(elemType)
|
||||
var newElemFunc = func(fields []string) reflect.Value {
|
||||
return utils.New(elemType, len(fields), len(fields))
|
||||
}
|
||||
|
||||
var containerValueSetFunc func(*reflect.Value, schemas.PK) error
|
||||
@@ -226,10 +213,15 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
|
||||
|
||||
containerValueSetFunc = func(newValue *reflect.Value, pk schemas.PK) error {
|
||||
keyValue := reflect.New(keyType)
|
||||
err := convertPKToValue(table, keyValue.Interface(), pk)
|
||||
if err != nil {
|
||||
return err
|
||||
cols := table.PKColumns()
|
||||
if len(cols) == 1 {
|
||||
if err := convert.AssignValue(keyValue, pk[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
keyValue.Set(reflect.ValueOf(&pk))
|
||||
}
|
||||
|
||||
if isPointer {
|
||||
containerValue.SetMapIndex(keyValue.Elem(), newValue.Elem().Addr())
|
||||
} else {
|
||||
@@ -241,8 +233,7 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
|
||||
|
||||
if elemType.Kind() == reflect.Struct {
|
||||
var newValue = newElemFunc(fields)
|
||||
dataStruct := utils.ReflectValue(newValue.Interface())
|
||||
tb, err := session.engine.tagParser.ParseWithCache(dataStruct)
|
||||
tb, err := session.engine.tagParser.ParseWithCache(newValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -266,7 +257,6 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
|
||||
default:
|
||||
err = rows.Scan(bean)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -278,16 +268,6 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
|
||||
return rows.Err()
|
||||
}
|
||||
|
||||
func convertPKToValue(table *schemas.Table, dst interface{}, pk schemas.PK) error {
|
||||
cols := table.PKColumns()
|
||||
if len(cols) == 1 {
|
||||
return convert.Assign(dst, pk[0], nil, nil)
|
||||
}
|
||||
|
||||
dst = pk
|
||||
return nil
|
||||
}
|
||||
|
||||
func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr interface{}, args ...interface{}) (err error) {
|
||||
if !session.canCache() ||
|
||||
utils.IndexNoCase(sqlStr, "having") != -1 ||
|
||||
|
||||
@@ -7,6 +7,9 @@ export default function initContextPopups() {
|
||||
if (!refIssues.length) return;
|
||||
|
||||
refIssues.each(function () {
|
||||
if ($(this).hasClass('ref-external-issue')) {
|
||||
return;
|
||||
}
|
||||
const [index, _issues, repo, owner] = $(this).attr('href').replace(/[#?].*$/, '').split('/').reverse();
|
||||
|
||||
const el = document.createElement('div');
|
||||
|
||||
Reference in New Issue
Block a user