aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--services/repository/adopt.go180
-rw-r--r--services/repository/adopt_test.go86
2 files changed, 156 insertions, 110 deletions
diff --git a/services/repository/adopt.go b/services/repository/adopt.go
index 2f87b0d7bd..fc3fdc608f 100644
--- a/services/repository/adopt.go
+++ b/services/repository/adopt.go
@@ -217,6 +217,57 @@ func DeleteUnadoptedRepository(doer, u *user_model.User, repoName string) error
return util.RemoveAll(repoPath)
}
+type unadoptedRrepositories struct {
+ repositories []string
+ index int
+ start int
+ end int
+}
+
+func (unadopted *unadoptedRrepositories) add(repository string) {
+ if unadopted.index >= unadopted.start && unadopted.index < unadopted.end {
+ unadopted.repositories = append(unadopted.repositories, repository)
+ }
+ unadopted.index++
+}
+
+func checkUnadoptedRepositories(userName string, repoNamesToCheck []string, unadopted *unadoptedRrepositories) error {
+ if len(repoNamesToCheck) == 0 {
+ return nil
+ }
+ ctxUser, err := user_model.GetUserByName(userName)
+ if err != nil {
+ if user_model.IsErrUserNotExist(err) {
+ log.Debug("Missing user: %s", userName)
+ return nil
+ }
+ return err
+ }
+ repos, _, err := models.GetUserRepositories(&models.SearchRepoOptions{
+ Actor: ctxUser,
+ Private: true,
+ ListOptions: db.ListOptions{
+ Page: 1,
+ PageSize: len(repoNamesToCheck),
+ }, LowerNames: repoNamesToCheck})
+ if err != nil {
+ return err
+ }
+ if len(repos) == len(repoNamesToCheck) {
+ return nil
+ }
+ repoNames := make(map[string]bool, len(repos))
+ for _, repo := range repos {
+ repoNames[repo.LowerName] = true
+ }
+ for _, repoName := range repoNamesToCheck {
+ if _, ok := repoNames[repoName]; !ok {
+ unadopted.add(filepath.Join(userName, repoName))
+ }
+ }
+ return nil
+}
+
// ListUnadoptedRepositories lists all the unadopted repositories that match the provided query
func ListUnadoptedRepositories(query string, opts *db.ListOptions) ([]string, int, error) {
globUser, _ := glob.Compile("*")
@@ -236,15 +287,17 @@ func ListUnadoptedRepositories(query string, opts *db.ListOptions) ([]string, in
}
}
}
- start := (opts.Page - 1) * opts.PageSize
- end := start + opts.PageSize
-
- repoNamesToCheck := make([]string, 0, opts.PageSize)
+ var repoNamesToCheck []string
- repoNames := make([]string, 0, opts.PageSize)
- var ctxUser *user_model.User
+ start := (opts.Page - 1) * opts.PageSize
+ unadopted := &unadoptedRrepositories{
+ repositories: make([]string, 0, opts.PageSize),
+ start: start,
+ end: start + opts.PageSize,
+ index: 0,
+ }
- count := 0
+ var userName string
// We're going to iterate by pagesize.
root := filepath.Clean(setting.RepoRootPath)
@@ -258,51 +311,16 @@ func ListUnadoptedRepositories(query string, opts *db.ListOptions) ([]string, in
if !strings.ContainsRune(path[len(root)+1:], filepath.Separator) {
// Got a new user
-
- // Clean up old repoNamesToCheck
- if len(repoNamesToCheck) > 0 {
- repos, _, err := models.GetUserRepositories(&models.SearchRepoOptions{
- Actor: ctxUser,
- Private: true,
- ListOptions: db.ListOptions{
- Page: 1,
- PageSize: opts.PageSize,
- }, LowerNames: repoNamesToCheck})
- if err != nil {
- return err
- }
- for _, name := range repoNamesToCheck {
- found := false
- repoLoopCatchup:
- for i, repo := range repos {
- if repo.LowerName == name {
- found = true
- repos = append(repos[:i], repos[i+1:]...)
- break repoLoopCatchup
- }
- }
- if !found {
- if count >= start && count < end {
- repoNames = append(repoNames, fmt.Sprintf("%s/%s", ctxUser.Name, name))
- }
- count++
- }
- }
- repoNamesToCheck = repoNamesToCheck[:0]
+ if err = checkUnadoptedRepositories(userName, repoNamesToCheck, unadopted); err != nil {
+ return err
}
+ repoNamesToCheck = repoNamesToCheck[:0]
if !globUser.Match(info.Name()) {
return filepath.SkipDir
}
- ctxUser, err = user_model.GetUserByName(info.Name())
- if err != nil {
- if user_model.IsErrUserNotExist(err) {
- log.Debug("Missing user: %s", info.Name())
- return filepath.SkipDir
- }
- return err
- }
+ userName = info.Name()
return nil
}
@@ -315,74 +333,16 @@ func ListUnadoptedRepositories(query string, opts *db.ListOptions) ([]string, in
if repo_model.IsUsableRepoName(name) != nil || strings.ToLower(name) != name || !globRepo.Match(name) {
return filepath.SkipDir
}
- if count < end {
- repoNamesToCheck = append(repoNamesToCheck, name)
- if len(repoNamesToCheck) >= opts.PageSize {
- repos, _, err := models.GetUserRepositories(&models.SearchRepoOptions{
- Actor: ctxUser,
- Private: true,
- ListOptions: db.ListOptions{
- Page: 1,
- PageSize: opts.PageSize,
- }, LowerNames: repoNamesToCheck})
- if err != nil {
- return err
- }
- for _, name := range repoNamesToCheck {
- found := false
- repoLoop:
- for i, repo := range repos {
- if repo.LowerName == name {
- found = true
- repos = append(repos[:i], repos[i+1:]...)
- break repoLoop
- }
- }
- if !found {
- if count >= start && count < end {
- repoNames = append(repoNames, fmt.Sprintf("%s/%s", ctxUser.Name, name))
- }
- count++
- }
- }
- repoNamesToCheck = repoNamesToCheck[:0]
- }
- return filepath.SkipDir
- }
- count++
+
+ repoNamesToCheck = append(repoNamesToCheck, name)
return filepath.SkipDir
}); err != nil {
return nil, 0, err
}
- if len(repoNamesToCheck) > 0 {
- repos, _, err := models.GetUserRepositories(&models.SearchRepoOptions{
- Actor: ctxUser,
- Private: true,
- ListOptions: db.ListOptions{
- Page: 1,
- PageSize: opts.PageSize,
- }, LowerNames: repoNamesToCheck})
- if err != nil {
- return nil, 0, err
- }
- for _, name := range repoNamesToCheck {
- found := false
- repoLoop:
- for i, repo := range repos {
- if repo.LowerName == name {
- found = true
- repos = append(repos[:i], repos[i+1:]...)
- break repoLoop
- }
- }
- if !found {
- if count >= start && count < end {
- repoNames = append(repoNames, fmt.Sprintf("%s/%s", ctxUser.Name, name))
- }
- count++
- }
- }
+ if err := checkUnadoptedRepositories(userName, repoNamesToCheck, unadopted); err != nil {
+ return nil, 0, err
}
- return repoNames, count, nil
+
+ return unadopted.repositories, unadopted.index, nil
}
diff --git a/services/repository/adopt_test.go b/services/repository/adopt_test.go
new file mode 100644
index 0000000000..2053151106
--- /dev/null
+++ b/services/repository/adopt_test.go
@@ -0,0 +1,86 @@
+// 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 repository
+
+import (
+ "os"
+ "path"
+ "testing"
+
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/setting"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestCheckUnadoptedRepositories_Add(t *testing.T) {
+ start := 10
+ end := 20
+ unadopted := &unadoptedRrepositories{
+ start: start,
+ end: end,
+ index: 0,
+ }
+
+ total := 30
+ for i := 0; i < total; i++ {
+ unadopted.add("something")
+ }
+
+ assert.Equal(t, total, unadopted.index)
+ assert.Equal(t, end-start, len(unadopted.repositories))
+}
+
+func TestCheckUnadoptedRepositories(t *testing.T) {
+ assert.NoError(t, unittest.PrepareTestDatabase())
+ //
+ // Non existent user
+ //
+ unadopted := &unadoptedRrepositories{start: 0, end: 100}
+ err := checkUnadoptedRepositories("notauser", []string{"repo"}, unadopted)
+ assert.NoError(t, err)
+ assert.Equal(t, 0, len(unadopted.repositories))
+ //
+ // Unadopted repository is returned
+ // Existing (adopted) repository is not returned
+ //
+ userName := "user2"
+ repoName := "repo2"
+ unadoptedRepoName := "unadopted"
+ unadopted = &unadoptedRrepositories{start: 0, end: 100}
+ err = checkUnadoptedRepositories(userName, []string{repoName, unadoptedRepoName}, unadopted)
+ assert.NoError(t, err)
+ assert.Equal(t, []string{path.Join(userName, unadoptedRepoName)}, unadopted.repositories)
+ //
+ // Existing (adopted) repository is not returned
+ //
+ unadopted = &unadoptedRrepositories{start: 0, end: 100}
+ err = checkUnadoptedRepositories(userName, []string{repoName}, unadopted)
+ assert.NoError(t, err)
+ assert.Equal(t, 0, len(unadopted.repositories))
+ assert.Equal(t, 0, unadopted.index)
+}
+
+func TestListUnadoptedRepositories_ListOptions(t *testing.T) {
+ assert.NoError(t, unittest.PrepareTestDatabase())
+ username := "user2"
+ unadoptedList := []string{path.Join(username, "unadopted1"), path.Join(username, "unadopted2")}
+ for _, unadopted := range unadoptedList {
+ _ = os.Mkdir(path.Join(setting.RepoRootPath, unadopted+".git"), 0755)
+ }
+
+ opts := db.ListOptions{Page: 1, PageSize: 1}
+ repoNames, count, err := ListUnadoptedRepositories("", &opts)
+ assert.NoError(t, err)
+ assert.Equal(t, 2, count)
+ assert.Equal(t, unadoptedList[0], repoNames[0])
+
+ opts = db.ListOptions{Page: 2, PageSize: 1}
+ repoNames, count, err = ListUnadoptedRepositories("", &opts)
+ assert.NoError(t, err)
+ assert.Equal(t, 2, count)
+ assert.Equal(t, unadoptedList[1], repoNames[0])
+}