Changes
2 changed files (+156/-110)
-
-
@@ -217,6 +217,57 @@ func DeleteUnadoptedRepository(doer, u *user_model.User, repoName string) errorreturn 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, inif !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, inif 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 }
-
-
-
@@ -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]) }
-