Skip to content

Commit 4bb1e41

Browse files
authored
Merge branch 'main' into fix-markdown-url
2 parents d71fed9 + 1831752 commit 4bb1e41

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+343
-153
lines changed

models/issue.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,8 @@ func sortIssuesSession(sess *xorm.Session, sortType string, priorityRepoID int64
12191219
"ELSE issue.deadline_unix END DESC")
12201220
case "priorityrepo":
12211221
sess.OrderBy("CASE WHEN issue.repo_id = " + strconv.FormatInt(priorityRepoID, 10) + " THEN 1 ELSE 2 END, issue.created_unix DESC")
1222+
case "project-column-sorting":
1223+
sess.Asc("project_issue.sorting")
12221224
default:
12231225
sess.Desc("issue.created_unix")
12241226
}

models/migrations/migrations.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,8 @@ var migrations = []Migration{
359359
NewMigration("Drop table remote_version (if exists)", dropTableRemoteVersion),
360360
// v202 -> v203
361361
NewMigration("Create key/value table for user settings", createUserSettingsTable),
362+
// v203 -> v204
363+
NewMigration("Add Sorting to ProjectIssue table", addProjectIssueSorting),
362364
}
363365

364366
// GetCurrentDBVersion returns the current db version

models/migrations/v203.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2021 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"xorm.io/xorm"
9+
)
10+
11+
func addProjectIssueSorting(x *xorm.Engine) error {
12+
// ProjectIssue saves relation from issue to a project
13+
type ProjectIssue struct {
14+
Sorting int64 `xorm:"NOT NULL DEFAULT 0"`
15+
}
16+
17+
return x.Sync2(new(ProjectIssue))
18+
}

models/project_board.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ func (b *ProjectBoard) LoadIssues() (IssueList, error) {
265265
issues, err := Issues(&IssuesOptions{
266266
ProjectBoardID: b.ID,
267267
ProjectID: b.ProjectID,
268+
SortType: "project-column-sorting",
268269
})
269270
if err != nil {
270271
return nil, err
@@ -276,6 +277,7 @@ func (b *ProjectBoard) LoadIssues() (IssueList, error) {
276277
issues, err := Issues(&IssuesOptions{
277278
ProjectBoardID: -1, // Issues without ProjectBoardID
278279
ProjectID: b.ProjectID,
280+
SortType: "project-column-sorting",
279281
})
280282
if err != nil {
281283
return nil, err

models/project_issue.go

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type ProjectIssue struct {
2020

2121
// If 0, then it has not been added to a specific board in the project
2222
ProjectBoardID int64 `xorm:"INDEX"`
23+
Sorting int64 `xorm:"NOT NULL DEFAULT 0"`
2324
}
2425

2526
func init() {
@@ -184,34 +185,34 @@ func addUpdateIssueProject(ctx context.Context, issue *Issue, doer *user_model.U
184185
// |_| |_| \___// |\___|\___|\__|____/ \___/ \__,_|_| \__,_|
185186
// |__/
186187

187-
// MoveIssueAcrossProjectBoards move a card from one board to another
188-
func MoveIssueAcrossProjectBoards(issue *Issue, board *ProjectBoard) error {
189-
ctx, committer, err := db.TxContext()
190-
if err != nil {
191-
return err
192-
}
193-
defer committer.Close()
194-
sess := db.GetEngine(ctx)
195-
196-
var pis ProjectIssue
197-
has, err := sess.Where("issue_id=?", issue.ID).Get(&pis)
198-
if err != nil {
199-
return err
200-
}
201-
202-
if !has {
203-
return fmt.Errorf("issue has to be added to a project first")
204-
}
188+
// MoveIssuesOnProjectBoard moves or keeps issues in a column and sorts them inside that column
189+
func MoveIssuesOnProjectBoard(board *ProjectBoard, sortedIssueIDs map[int64]int64) error {
190+
return db.WithTx(func(ctx context.Context) error {
191+
sess := db.GetEngine(ctx)
205192

206-
pis.ProjectBoardID = board.ID
207-
if _, err := sess.ID(pis.ID).Cols("project_board_id").Update(&pis); err != nil {
208-
return err
209-
}
193+
issueIDs := make([]int64, 0, len(sortedIssueIDs))
194+
for _, issueID := range sortedIssueIDs {
195+
issueIDs = append(issueIDs, issueID)
196+
}
197+
count, err := sess.Table(new(ProjectIssue)).Where("project_id=?", board.ProjectID).In("issue_id", issueIDs).Count()
198+
if err != nil {
199+
return err
200+
}
201+
if int(count) != len(sortedIssueIDs) {
202+
return fmt.Errorf("all issues have to be added to a project first")
203+
}
210204

211-
return committer.Commit()
205+
for sorting, issueID := range sortedIssueIDs {
206+
_, err = sess.Exec("UPDATE `project_issue` SET project_board_id=?, sorting=? WHERE issue_id=?", board.ID, sorting, issueID)
207+
if err != nil {
208+
return err
209+
}
210+
}
211+
return nil
212+
})
212213
}
213214

214215
func (pb *ProjectBoard) removeIssues(e db.Engine) error {
215-
_, err := e.Exec("UPDATE `project_issue` SET project_board_id = 0 WHERE project_board_id = ? ", pb.ID)
216+
_, err := e.Exec("UPDATE `project_issue` SET project_board_id = 0, sorting = 0 WHERE project_board_id = ? ", pb.ID)
216217
return err
217218
}

modules/context/repo.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
584584
}
585585
ctx.Data["Tags"] = tags
586586

587-
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
587+
brs, _, err := ctx.Repo.GitRepo.GetBranchNames(0, 0)
588588
if err != nil {
589589
ctx.ServerError("GetBranches", err)
590590
return
@@ -810,7 +810,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
810810
if len(ctx.Params("*")) == 0 {
811811
refName = ctx.Repo.Repository.DefaultBranch
812812
if !ctx.Repo.GitRepo.IsBranchExist(refName) {
813-
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
813+
brs, _, err := ctx.Repo.GitRepo.GetBranchNames(0, 0)
814814
if err != nil {
815815
ctx.ServerError("GetBranches", err)
816816
return

modules/git/repo_branch.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,22 @@ func GetBranchesByPath(path string, skip, limit int) ([]*Branch, int, error) {
9595
}
9696
defer gitRepo.Close()
9797

98-
brs, countAll, err := gitRepo.GetBranches(skip, limit)
98+
return gitRepo.GetBranches(skip, limit)
99+
}
100+
101+
// GetBranches returns a slice of *git.Branch
102+
func (repo *Repository) GetBranches(skip, limit int) ([]*Branch, int, error) {
103+
brs, countAll, err := repo.GetBranchNames(skip, limit)
99104
if err != nil {
100105
return nil, 0, err
101106
}
102107

103108
branches := make([]*Branch, len(brs))
104109
for i := range brs {
105110
branches[i] = &Branch{
106-
Path: path,
111+
Path: repo.Path,
107112
Name: brs[i],
108-
gitRepo: gitRepo,
113+
gitRepo: repo,
109114
}
110115
}
111116

modules/git/repo_branch_gogit.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
package git
1010

1111
import (
12+
"context"
1213
"strings"
1314

1415
"github.com/go-git/go-git/v5/plumbing"
@@ -52,7 +53,7 @@ func (repo *Repository) IsBranchExist(name string) bool {
5253

5354
// GetBranches returns branches from the repository, skipping skip initial branches and
5455
// returning at most limit branches, or all branches if limit is 0.
55-
func (repo *Repository) GetBranches(skip, limit int) ([]string, int, error) {
56+
func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
5657
var branchNames []string
5758

5859
branches, err := repo.gogitRepo.Branches()
@@ -79,3 +80,26 @@ func (repo *Repository) GetBranches(skip, limit int) ([]string, int, error) {
7980

8081
return branchNames, count, nil
8182
}
83+
84+
// WalkReferences walks all the references from the repository
85+
func WalkReferences(ctx context.Context, repoPath string, walkfn func(string) error) (int, error) {
86+
repo, err := OpenRepositoryCtx(ctx, repoPath)
87+
if err != nil {
88+
return 0, err
89+
}
90+
defer repo.Close()
91+
92+
i := 0
93+
iter, err := repo.gogitRepo.References()
94+
if err != nil {
95+
return i, err
96+
}
97+
defer iter.Close()
98+
99+
err = iter.ForEach(func(ref *plumbing.Reference) error {
100+
err := walkfn(string(ref.Name()))
101+
i++
102+
return err
103+
})
104+
return i, err
105+
}

modules/git/repo_branch_nogogit.go

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,29 @@ func (repo *Repository) IsBranchExist(name string) bool {
6161
return repo.IsReferenceExist(BranchPrefix + name)
6262
}
6363

64-
// GetBranches returns branches from the repository, skipping skip initial branches and
64+
// GetBranchNames returns branches from the repository, skipping skip initial branches and
6565
// returning at most limit branches, or all branches if limit is 0.
66-
func (repo *Repository) GetBranches(skip, limit int) ([]string, int, error) {
66+
func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
6767
return callShowRef(repo.Ctx, repo.Path, BranchPrefix, "--heads", skip, limit)
6868
}
6969

70+
// WalkReferences walks all the references from the repository
71+
func WalkReferences(ctx context.Context, repoPath string, walkfn func(string) error) (int, error) {
72+
return walkShowRef(ctx, repoPath, "", 0, 0, walkfn)
73+
}
74+
7075
// callShowRef return refs, if limit = 0 it will not limit
7176
func callShowRef(ctx context.Context, repoPath, prefix, arg string, skip, limit int) (branchNames []string, countAll int, err error) {
77+
countAll, err = walkShowRef(ctx, repoPath, arg, skip, limit, func(branchName string) error {
78+
branchName = strings.TrimPrefix(branchName, prefix)
79+
branchNames = append(branchNames, branchName)
80+
81+
return nil
82+
})
83+
return
84+
}
85+
86+
func walkShowRef(ctx context.Context, repoPath, arg string, skip, limit int, walkfn func(string) error) (countAll int, err error) {
7287
stdoutReader, stdoutWriter := io.Pipe()
7388
defer func() {
7489
_ = stdoutReader.Close()
@@ -77,7 +92,11 @@ func callShowRef(ctx context.Context, repoPath, prefix, arg string, skip, limit
7792

7893
go func() {
7994
stderrBuilder := &strings.Builder{}
80-
err := NewCommandContext(ctx, "show-ref", arg).RunInDirPipeline(repoPath, stdoutWriter, stderrBuilder)
95+
args := []string{"show-ref"}
96+
if arg != "" {
97+
args = append(args, arg)
98+
}
99+
err := NewCommandContext(ctx, args...).RunInDirPipeline(repoPath, stdoutWriter, stderrBuilder)
81100
if err != nil {
82101
if stderrBuilder.Len() == 0 {
83102
_ = stdoutWriter.Close()
@@ -94,10 +113,10 @@ func callShowRef(ctx context.Context, repoPath, prefix, arg string, skip, limit
94113
for i < skip {
95114
_, isPrefix, err := bufReader.ReadLine()
96115
if err == io.EOF {
97-
return branchNames, i, nil
116+
return i, nil
98117
}
99118
if err != nil {
100-
return nil, 0, err
119+
return 0, err
101120
}
102121
if !isPrefix {
103122
i++
@@ -112,39 +131,42 @@ func callShowRef(ctx context.Context, repoPath, prefix, arg string, skip, limit
112131
_, err = bufReader.ReadSlice(' ')
113132
}
114133
if err == io.EOF {
115-
return branchNames, i, nil
134+
return i, nil
116135
}
117136
if err != nil {
118-
return nil, 0, err
137+
return 0, err
119138
}
120139

121140
branchName, err := bufReader.ReadString('\n')
122141
if err == io.EOF {
123142
// This shouldn't happen... but we'll tolerate it for the sake of peace
124-
return branchNames, i, nil
143+
return i, nil
125144
}
126145
if err != nil {
127-
return nil, i, err
146+
return i, err
128147
}
129-
branchName = strings.TrimPrefix(branchName, prefix)
148+
130149
if len(branchName) > 0 {
131150
branchName = branchName[:len(branchName)-1]
132151
}
133-
branchNames = append(branchNames, branchName)
152+
err = walkfn(branchName)
153+
if err != nil {
154+
return i, err
155+
}
134156
i++
135157
}
136158
// count all refs
137159
for limit != 0 {
138160
_, isPrefix, err := bufReader.ReadLine()
139161
if err == io.EOF {
140-
return branchNames, i, nil
162+
return i, nil
141163
}
142164
if err != nil {
143-
return nil, 0, err
165+
return 0, err
144166
}
145167
if !isPrefix {
146168
i++
147169
}
148170
}
149-
return branchNames, i, nil
171+
return i, nil
150172
}

modules/git/repo_branch_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,21 @@ func TestRepository_GetBranches(t *testing.T) {
1717
assert.NoError(t, err)
1818
defer bareRepo1.Close()
1919

20-
branches, countAll, err := bareRepo1.GetBranches(0, 2)
20+
branches, countAll, err := bareRepo1.GetBranchNames(0, 2)
2121

2222
assert.NoError(t, err)
2323
assert.Len(t, branches, 2)
2424
assert.EqualValues(t, 3, countAll)
2525
assert.ElementsMatch(t, []string{"branch1", "branch2"}, branches)
2626

27-
branches, countAll, err = bareRepo1.GetBranches(0, 0)
27+
branches, countAll, err = bareRepo1.GetBranchNames(0, 0)
2828

2929
assert.NoError(t, err)
3030
assert.Len(t, branches, 3)
3131
assert.EqualValues(t, 3, countAll)
3232
assert.ElementsMatch(t, []string{"branch1", "branch2", "master"}, branches)
3333

34-
branches, countAll, err = bareRepo1.GetBranches(5, 1)
34+
branches, countAll, err = bareRepo1.GetBranchNames(5, 1)
3535

3636
assert.NoError(t, err)
3737
assert.Len(t, branches, 0)
@@ -48,7 +48,7 @@ func BenchmarkRepository_GetBranches(b *testing.B) {
4848
defer bareRepo1.Close()
4949

5050
for i := 0; i < b.N; i++ {
51-
_, _, err := bareRepo1.GetBranches(0, 0)
51+
_, _, err := bareRepo1.GetBranchNames(0, 0)
5252
if err != nil {
5353
b.Fatal(err)
5454
}

modules/setting/setting.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -548,25 +548,25 @@ func SetCustomPathAndConf(providedCustom, providedConf, providedWorkPath string)
548548

549549
// LoadFromExisting initializes setting options from an existing config file (app.ini)
550550
func LoadFromExisting() {
551-
loadFromConf(false)
551+
loadFromConf(false, "")
552552
}
553553

554554
// LoadAllowEmpty initializes setting options, it's also fine that if the config file (app.ini) doesn't exist
555555
func LoadAllowEmpty() {
556-
loadFromConf(true)
556+
loadFromConf(true, "")
557557
}
558558

559559
// LoadForTest initializes setting options for tests
560-
func LoadForTest() {
561-
loadFromConf(true)
560+
func LoadForTest(extraConfigs ...string) {
561+
loadFromConf(true, strings.Join(extraConfigs, "\n"))
562562
if err := PrepareAppDataPath(); err != nil {
563563
log.Fatal("Can not prepare APP_DATA_PATH: %v", err)
564564
}
565565
}
566566

567567
// loadFromConf initializes configuration context.
568568
// NOTE: do not print any log except error.
569-
func loadFromConf(allowEmpty bool) {
569+
func loadFromConf(allowEmpty bool, extraConfig string) {
570570
Cfg = ini.Empty()
571571

572572
if WritePIDFile && len(PIDFile) > 0 {
@@ -585,6 +585,12 @@ func loadFromConf(allowEmpty bool) {
585585
log.Fatal("Unable to find configuration file: %q.\nEnsure you are running in the correct environment or set the correct configuration file with -c.", CustomConf)
586586
} // else: no config file, a config file might be created at CustomConf later (might not)
587587

588+
if extraConfig != "" {
589+
if err = Cfg.Append([]byte(extraConfig)); err != nil {
590+
log.Fatal("Unable to append more config: %v", err)
591+
}
592+
}
593+
588594
Cfg.NameMapper = ini.SnackCase
589595

590596
homeDir, err := com.HomeDir()

0 commit comments

Comments
 (0)