Changes
88 changed files (+1363/-1388)
-
-
@@ -102,7 +102,7 @@ func migrateAvatars(dstStorage storage.ObjectStorage) error {} func migrateRepoAvatars(dstStorage storage.ObjectStorage) error { return models.IterateRepository(func(repo *repo_model.Repository) error { return repo_model.IterateRepository(func(repo *repo_model.Repository) error { _, err := storage.Copy(dstStorage, repo.CustomAvatarRelativePath(), storage.RepoAvatars, repo.CustomAvatarRelativePath()) return err })
-
-
-
@@ -24,7 +24,7 @@ func assertUserDeleted(t *testing.T, userID int64) {unittest.AssertNotExistsBean(t, &models.OrgUser{UID: userID}) unittest.AssertNotExistsBean(t, &models.IssueUser{UID: userID}) unittest.AssertNotExistsBean(t, &models.TeamUser{UID: userID}) unittest.AssertNotExistsBean(t, &models.Star{UID: userID}) unittest.AssertNotExistsBean(t, &repo_model.Star{UID: userID}) } func TestUserDeleteAccount(t *testing.T) {
-
-
-
@@ -89,7 +89,7 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *models.Pulassert.NoError(t, err) assert.NotEmpty(t, baseRepo) headRepo, err := repo_service.ForkRepository(actor, forkOrg, models.ForkRepoOptions{ headRepo, err := repo_service.ForkRepository(actor, forkOrg, repo_service.ForkRepoOptions{ BaseRepo: baseRepo, Name: "repo-pr-update", Description: "desc",
-
-
-
@@ -8,7 +8,7 @@ import ("net/url" "testing" "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" )
-
@@ -18,8 +18,8 @@ func TestRepoWatch(t *testing.T) {// Test round-trip auto-watch setting.Service.AutoWatchOnChanges = true session := loginUser(t, "user2") unittest.AssertNotExistsBean(t, &models.Watch{UserID: 2, RepoID: 3}) unittest.AssertNotExistsBean(t, &repo_model.Watch{UserID: 2, RepoID: 3}) testEditFile(t, session, "user3", "repo3", "master", "README.md", "Hello, World (Edited for watch)\n") unittest.AssertExistsAndLoadBean(t, &models.Watch{UserID: 2, RepoID: 3, Mode: models.RepoWatchModeAuto}) unittest.AssertExistsAndLoadBean(t, &repo_model.Watch{UserID: 2, RepoID: 3, Mode: repo_model.WatchModeAuto}) }) }
-
-
-
@@ -16,6 +16,7 @@ import ("code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/git"
-
@@ -414,3 +415,127 @@ func DeleteOldActions(olderThan time.Duration) (err error) {_, err = db.GetEngine(db.DefaultContext).Where("created_unix < ?", time.Now().Add(-olderThan).Unix()).Delete(&Action{}) return } func notifyWatchers(ctx context.Context, actions ...*Action) error { var watchers []*repo_model.Watch var repo *repo_model.Repository var err error var permCode []bool var permIssue []bool var permPR []bool e := db.GetEngine(ctx) for _, act := range actions { repoChanged := repo == nil || repo.ID != act.RepoID if repoChanged { // Add feeds for user self and all watchers. watchers, err = repo_model.GetWatchers(ctx, act.RepoID) if err != nil { return fmt.Errorf("get watchers: %v", err) } } // Add feed for actioner. act.UserID = act.ActUserID if _, err = e.Insert(act); err != nil { return fmt.Errorf("insert new actioner: %v", err) } if repoChanged { act.loadRepo() repo = act.Repo // check repo owner exist. if err := act.Repo.GetOwner(ctx); err != nil { return fmt.Errorf("can't get repo owner: %v", err) } } else if act.Repo == nil { act.Repo = repo } // Add feed for organization if act.Repo.Owner.IsOrganization() && act.ActUserID != act.Repo.Owner.ID { act.ID = 0 act.UserID = act.Repo.Owner.ID if _, err = e.InsertOne(act); err != nil { return fmt.Errorf("insert new actioner: %v", err) } } if repoChanged { permCode = make([]bool, len(watchers)) permIssue = make([]bool, len(watchers)) permPR = make([]bool, len(watchers)) for i, watcher := range watchers { user, err := user_model.GetUserByIDEngine(e, watcher.UserID) if err != nil { permCode[i] = false permIssue[i] = false permPR[i] = false continue } perm, err := getUserRepoPermission(ctx, repo, user) if err != nil { permCode[i] = false permIssue[i] = false permPR[i] = false continue } permCode[i] = perm.CanRead(unit.TypeCode) permIssue[i] = perm.CanRead(unit.TypeIssues) permPR[i] = perm.CanRead(unit.TypePullRequests) } } for i, watcher := range watchers { if act.ActUserID == watcher.UserID { continue } act.ID = 0 act.UserID = watcher.UserID act.Repo.Units = nil switch act.OpType { case ActionCommitRepo, ActionPushTag, ActionDeleteTag, ActionPublishRelease, ActionDeleteBranch: if !permCode[i] { continue } case ActionCreateIssue, ActionCommentIssue, ActionCloseIssue, ActionReopenIssue: if !permIssue[i] { continue } case ActionCreatePullRequest, ActionCommentPull, ActionMergePullRequest, ActionClosePullRequest, ActionReopenPullRequest: if !permPR[i] { continue } } if _, err = e.InsertOne(act); err != nil { return fmt.Errorf("insert new action: %v", err) } } } return nil } // NotifyWatchers creates batch of actions for every watcher. func NotifyWatchers(actions ...*Action) error { return notifyWatchers(db.DefaultContext, actions...) } // NotifyWatchersActions creates batch of actions for every watcher. func NotifyWatchersActions(acts []*Action) error { ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() for _, act := range acts { if err := notifyWatchers(ctx, act); err != nil { return err } } return committer.Commit() }
-
-
-
@@ -92,3 +92,40 @@ func TestGetFeeds2(t *testing.T) {assert.NoError(t, err) assert.Len(t, actions, 0) } func TestNotifyWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) action := &Action{ ActUserID: 8, RepoID: 1, OpType: ActionStarRepo, } assert.NoError(t, NotifyWatchers(action)) // One watchers are inactive, thus action is only created for user 8, 1, 4, 11 unittest.AssertExistsAndLoadBean(t, &Action{ ActUserID: action.ActUserID, UserID: 8, RepoID: action.RepoID, OpType: action.OpType, }) unittest.AssertExistsAndLoadBean(t, &Action{ ActUserID: action.ActUserID, UserID: 1, RepoID: action.RepoID, OpType: action.OpType, }) unittest.AssertExistsAndLoadBean(t, &Action{ ActUserID: action.ActUserID, UserID: 4, RepoID: action.RepoID, OpType: action.OpType, }) unittest.AssertExistsAndLoadBean(t, &Action{ ActUserID: action.ActUserID, UserID: 11, RepoID: action.RepoID, OpType: action.OpType, }) }
-
-
-
@@ -71,21 +71,6 @@ func (err ErrUserNotAllowedCreateOrg) Error() string {return "user is not allowed to create organizations" } // ErrReachLimitOfRepo represents a "ReachLimitOfRepo" kind of error. type ErrReachLimitOfRepo struct { Limit int } // IsErrReachLimitOfRepo checks if an error is a ErrReachLimitOfRepo. func IsErrReachLimitOfRepo(err error) bool { _, ok := err.(ErrReachLimitOfRepo) return ok } func (err ErrReachLimitOfRepo) Error() string { return fmt.Sprintf("user has reached maximum limit of repositories [limit: %d]", err.Limit) } // __ __.__ __ .__ // / \ / \__| | _|__| // \ \/\/ / | |/ / |
-
@@ -322,38 +307,6 @@ func (err ErrRepoTransferInProgress) Error() string {return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name) } // ErrRepoAlreadyExist represents a "RepoAlreadyExist" kind of error. type ErrRepoAlreadyExist struct { Uname string Name string } // IsErrRepoAlreadyExist checks if an error is a ErrRepoAlreadyExist. func IsErrRepoAlreadyExist(err error) bool { _, ok := err.(ErrRepoAlreadyExist) return ok } func (err ErrRepoAlreadyExist) Error() string { return fmt.Sprintf("repository already exists [uname: %s, name: %s]", err.Uname, err.Name) } // ErrRepoFilesAlreadyExist represents a "RepoFilesAlreadyExist" kind of error. type ErrRepoFilesAlreadyExist struct { Uname string Name string } // IsErrRepoFilesAlreadyExist checks if an error is a ErrRepoAlreadyExist. func IsErrRepoFilesAlreadyExist(err error) bool { _, ok := err.(ErrRepoFilesAlreadyExist) return ok } func (err ErrRepoFilesAlreadyExist) Error() string { return fmt.Sprintf("repository files already exist [uname: %s, name: %s]", err.Uname, err.Name) } // ErrForkAlreadyExist represents a "ForkAlreadyExist" kind of error. type ErrForkAlreadyExist struct { Uname string
-
@@ -371,22 +324,6 @@ func (err ErrForkAlreadyExist) Error() string {return fmt.Sprintf("repository is already forked by user [uname: %s, repo path: %s, fork path: %s]", err.Uname, err.RepoName, err.ForkName) } // ErrRepoRedirectNotExist represents a "RepoRedirectNotExist" kind of error. type ErrRepoRedirectNotExist struct { OwnerID int64 RepoName string } // IsErrRepoRedirectNotExist check if an error is an ErrRepoRedirectNotExist. func IsErrRepoRedirectNotExist(err error) bool { _, ok := err.(ErrRepoRedirectNotExist) return ok } func (err ErrRepoRedirectNotExist) Error() string { return fmt.Sprintf("repository redirect does not exist [uid: %d, name: %s]", err.OwnerID, err.RepoName) } // ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error. type ErrInvalidCloneAddr struct { Host string
-
-
-
@@ -6,6 +6,7 @@ package modelsimport ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/timeutil" )
-
@@ -80,11 +81,11 @@ func CheckIssueWatch(user *user_model.User, issue *Issue) (bool, error) {if exist { return iw.IsWatching, nil } w, err := getWatch(db.GetEngine(db.DefaultContext), user.ID, issue.RepoID) w, err := repo_model.GetWatch(db.DefaultContext, user.ID, issue.RepoID) if err != nil { return false, err } return isWatchMode(w.Mode) || IsUserParticipantsOfIssue(user, issue), nil return repo_model.IsWatchMode(w.Mode) || IsUserParticipantsOfIssue(user, issue), nil } // GetIssueWatchersIDs returns IDs of subscribers or explicit unsubscribers to a given issue id
-
-
-
@@ -225,7 +225,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, ntoNotify[id] = struct{}{} } if !(issue.IsPull && HasWorkInProgressPrefix(issue.Title)) { repoWatches, err := getRepoWatchersIDs(e, issue.RepoID) repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID) if err != nil { return err }
-
-
-
@@ -794,7 +794,7 @@ func removeOrgUser(ctx context.Context, orgID, userID int64) error {return fmt.Errorf("GetUserRepositories [%d]: %v", userID, err) } for _, repoID := range repoIDs { if err = watchRepo(sess, userID, repoID, false); err != nil { if err = repo_model.WatchRepoCtx(ctx, userID, repoID, false); err != nil { return err } }
-
-
-
@@ -238,7 +238,7 @@ func (t *Team) addRepository(ctx context.Context, repo *repo_model.Repository) (return fmt.Errorf("getMembers: %v", err) } for _, u := range t.Members { if err = watchRepo(e, u.ID, repo.ID, true); err != nil { if err = repo_model.WatchRepoCtx(ctx, u.ID, repo.ID, true); err != nil { return fmt.Errorf("watchRepo: %v", err) } }
-
@@ -341,7 +341,7 @@ func (t *Team) removeAllRepositories(ctx context.Context) (err error) {continue } if err = watchRepo(e, user.ID, repo.ID, false); err != nil { if err = repo_model.WatchRepoCtx(ctx, user.ID, repo.ID, false); err != nil { return err }
-
@@ -399,7 +399,7 @@ func (t *Team) removeRepository(ctx context.Context, repo *repo_model.Repositorycontinue } if err = watchRepo(e, teamUser.UID, repo.ID, false); err != nil { if err = repo_model.WatchRepoCtx(ctx, teamUser.UID, repo.ID, false); err != nil { return err }
-
@@ -857,7 +857,7 @@ func AddTeamMember(team *Team, userID int64) error {return err } if setting.Service.AutoWatchNewRepos { if err = watchRepo(sess, userID, repo.ID, true); err != nil { if err = repo_model.WatchRepoCtx(ctx, userID, repo.ID, true); err != nil { return err } }
-
-
-
@@ -370,3 +370,89 @@ func UpdateReleasesMigrationsByType(gitServiceType structs.GitServiceType, origi}) return err } // PushUpdateDeleteTagsContext updates a number of delete tags with context func PushUpdateDeleteTagsContext(ctx context.Context, repo *repo_model.Repository, tags []string) error { return pushUpdateDeleteTags(db.GetEngine(ctx), repo, tags) } func pushUpdateDeleteTags(e db.Engine, repo *repo_model.Repository, tags []string) error { if len(tags) == 0 { return nil } lowerTags := make([]string, 0, len(tags)) for _, tag := range tags { lowerTags = append(lowerTags, strings.ToLower(tag)) } if _, err := e. Where("repo_id = ? AND is_tag = ?", repo.ID, true). In("lower_tag_name", lowerTags). Delete(new(Release)); err != nil { return fmt.Errorf("Delete: %v", err) } if _, err := e. Where("repo_id = ? AND is_tag = ?", repo.ID, false). In("lower_tag_name", lowerTags). Cols("is_draft", "num_commits", "sha1"). Update(&Release{ IsDraft: true, }); err != nil { return fmt.Errorf("Update: %v", err) } return nil } // PushUpdateDeleteTag must be called for any push actions to delete tag func PushUpdateDeleteTag(repo *repo_model.Repository, tagName string) error { rel, err := GetRelease(repo.ID, tagName) if err != nil { if IsErrReleaseNotExist(err) { return nil } return fmt.Errorf("GetRelease: %v", err) } if rel.IsTag { if _, err = db.GetEngine(db.DefaultContext).ID(rel.ID).Delete(new(Release)); err != nil { return fmt.Errorf("Delete: %v", err) } } else { rel.IsDraft = true rel.NumCommits = 0 rel.Sha1 = "" if _, err = db.GetEngine(db.DefaultContext).ID(rel.ID).AllCols().Update(rel); err != nil { return fmt.Errorf("Update: %v", err) } } return nil } // SaveOrUpdateTag must be called for any push actions to add tag func SaveOrUpdateTag(repo *repo_model.Repository, newRel *Release) error { rel, err := GetRelease(repo.ID, newRel.TagName) if err != nil && !IsErrReleaseNotExist(err) { return fmt.Errorf("GetRelease: %v", err) } if rel == nil { rel = newRel if _, err = db.GetEngine(db.DefaultContext).Insert(rel); err != nil { return fmt.Errorf("InsertOne: %v", err) } } else { rel.Sha1 = newRel.Sha1 rel.CreatedUnix = newRel.CreatedUnix rel.NumCommits = newRel.NumCommits rel.IsDraft = false if rel.IsTag && newRel.PublisherID > 0 { rel.PublisherID = newRel.PublisherID } if _, err = db.GetEngine(db.DefaultContext).ID(rel.ID).AllCols().Update(rel); err != nil { return fmt.Errorf("Update: %v", err) } } return nil }
-
-
-
@@ -14,7 +14,6 @@ import ("sort" "strconv" "strings" "time" "unicode/utf8" _ "image/jpeg" // Needed for jpeg support
-
@@ -218,7 +217,7 @@ func getReviewers(ctx context.Context, repo *repo_model.Repository, doerID, post"SELECT uid AS user_id FROM `org_user` WHERE org_id = ? "+ ") AND id NOT IN (?, ?) ORDER BY name", repo.ID, perm.AccessModeRead, repo.ID, RepoWatchModeNormal, RepoWatchModeAuto, repo.ID, repo_model.WatchModeNormal, repo_model.WatchModeAuto, repo.OwnerID, doerID, posterID). Find(&users); err != nil {
-
@@ -280,7 +279,7 @@ func CanUserForkRepo(user *user_model.User, repo *repo_model.Repository) (bool,if user == nil { return false, nil } if repo.OwnerID != user.ID && !HasForkedRepo(user.ID, repo.ID) { if repo.OwnerID != user.ID && !repo_model.HasForkedRepo(user.ID, repo.ID) { return true, nil } ownedOrgs, err := GetOrgsCanCreateRepoByUserID(user.ID)
-
@@ -288,7 +287,7 @@ func CanUserForkRepo(user *user_model.User, repo *repo_model.Repository) (bool,return false, err } for _, org := range ownedOrgs { if repo.OwnerID != org.ID && !HasForkedRepo(org.ID, repo.ID) { if repo.OwnerID != org.ID && !repo_model.HasForkedRepo(org.ID, repo.ID) { return true, nil } }
-
@@ -317,24 +316,6 @@ func CanUserDelete(repo *repo_model.Repository, user *user_model.User) (bool, erreturn false, nil } // GetRepoReaders returns all users that have explicit read access or higher to the repository. func GetRepoReaders(repo *repo_model.Repository) (_ []*user_model.User, err error) { return getUsersWithAccessMode(db.DefaultContext, repo, perm.AccessModeRead) } // GetRepoWriters returns all users that have write access to the repository. func GetRepoWriters(repo *repo_model.Repository) (_ []*user_model.User, err error) { return getUsersWithAccessMode(db.DefaultContext, repo, perm.AccessModeWrite) } // IsRepoReader returns true if user has explicit read access or higher to the repository. func IsRepoReader(repo *repo_model.Repository, userID int64) (bool, error) { if repo.OwnerID == userID { return true, nil } return db.GetEngine(db.DefaultContext).Where("repo_id = ? AND user_id = ? AND mode >= ?", repo.ID, userID, perm.AccessModeRead).Get(&Access{}) } // getUsersWithAccessMode returns users that have at least given access mode to the repository. func getUsersWithAccessMode(ctx context.Context, repo *repo_model.Repository, mode perm.AccessMode) (_ []*user_model.User, err error) { if err = repo.GetOwner(ctx); err != nil {
-
@@ -372,35 +353,6 @@ func SetRepoReadBy(repoID, userID int64) error {return setRepoNotificationStatusReadIfUnread(db.GetEngine(db.DefaultContext), userID, repoID) } // CheckCreateRepository check if could created a repository func CheckCreateRepository(doer, u *user_model.User, name string, overwriteOrAdopt bool) error { if !doer.CanCreateRepo() { return ErrReachLimitOfRepo{u.MaxRepoCreation} } if err := IsUsableRepoName(name); err != nil { return err } has, err := repo_model.IsRepositoryExist(u, name) if err != nil { return fmt.Errorf("IsRepositoryExist: %v", err) } else if has { return ErrRepoAlreadyExist{u.Name, name} } repoPath := repo_model.RepoPath(u.Name, name) isExist, err := util.IsExist(repoPath) if err != nil { log.Error("Unable to check if %s exists. Error: %v", repoPath, err) return err } if !overwriteOrAdopt && isExist { return ErrRepoFilesAlreadyExist{u.Name, name} } return nil } // CreateRepoOptions contains the create repository options type CreateRepoOptions struct { Name string
-
@@ -421,13 +373,6 @@ type CreateRepoOptions struct {MirrorInterval string } // ForkRepoOptions contains the fork repository options type ForkRepoOptions struct { BaseRepo *repo_model.Repository Name string Description string } // GetRepoInitFile returns repository init files func GetRepoInitFile(tp, name string) ([]byte, error) { cleanedName := strings.TrimLeft(path.Clean("/"+name), "/")
-
@@ -457,23 +402,9 @@ func GetRepoInitFile(tp, name string) ([]byte, error) {} } var ( reservedRepoNames = []string{".", ".."} reservedRepoPatterns = []string{"*.git", "*.wiki", "*.rss", "*.atom"} ) // IsUsableRepoName returns true when repository is usable func IsUsableRepoName(name string) error { if db.AlphaDashDotPattern.MatchString(name) { // Note: usually this error is normally caught up earlier in the UI return db.ErrNameCharsNotAllowed{Name: name} } return db.IsUsableName(reservedRepoNames, reservedRepoPatterns, name) } // CreateRepository creates a repository for the user/organization. func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository, overwriteOrAdopt bool) (err error) { if err = IsUsableRepoName(repo.Name); err != nil { if err = repo_model.IsUsableRepoName(repo.Name); err != nil { return err }
-
@@ -481,7 +412,10 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_if err != nil { return fmt.Errorf("IsRepositoryExist: %v", err) } else if has { return ErrRepoAlreadyExist{u.Name, repo.Name} return repo_model.ErrRepoAlreadyExist{ Uname: u.Name, Name: repo.Name, } } repoPath := repo_model.RepoPath(u.Name, repo.Name)
-
@@ -492,7 +426,7 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_} if !overwriteOrAdopt && isExist { log.Error("Files already exist in %s and we are not going to adopt or delete.", repoPath) return ErrRepoFilesAlreadyExist{ return repo_model.ErrRepoFilesAlreadyExist{ Uname: u.Name, Name: repo.Name, }
-
@@ -501,7 +435,7 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_if err = db.Insert(ctx, repo); err != nil { return err } if err = deleteRepoRedirect(db.GetEngine(ctx), u.ID, repo.Name); err != nil { if err = repo_model.DeleteRedirect(ctx, u.ID, repo.Name); err != nil { return err }
-
@@ -578,7 +512,7 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_} if setting.Service.AutoWatchNewRepos { if err = watchRepo(db.GetEngine(ctx), doer.ID, repo.ID, true); err != nil { if err = repo_model.WatchRepoCtx(ctx, doer.ID, repo.ID, true); err != nil { return fmt.Errorf("watchRepo: %v", err) } }
-
@@ -633,67 +567,6 @@ func DecrementRepoForkNum(ctx context.Context, repoID int64) error {return err } // ChangeRepositoryName changes all corresponding setting from old repository name to new one. func ChangeRepositoryName(doer *user_model.User, repo *repo_model.Repository, newRepoName string) (err error) { oldRepoName := repo.Name newRepoName = strings.ToLower(newRepoName) if err = IsUsableRepoName(newRepoName); err != nil { return err } if err := repo.GetOwner(db.DefaultContext); err != nil { return err } has, err := repo_model.IsRepositoryExist(repo.Owner, newRepoName) if err != nil { return fmt.Errorf("IsRepositoryExist: %v", err) } else if has { return ErrRepoAlreadyExist{repo.Owner.Name, newRepoName} } newRepoPath := repo_model.RepoPath(repo.Owner.Name, newRepoName) if err = util.Rename(repo.RepoPath(), newRepoPath); err != nil { return fmt.Errorf("rename repository directory: %v", err) } wikiPath := repo.WikiPath() isExist, err := util.IsExist(wikiPath) if err != nil { log.Error("Unable to check if %s exists. Error: %v", wikiPath, err) return err } if isExist { if err = util.Rename(wikiPath, repo_model.WikiPath(repo.Owner.Name, newRepoName)); err != nil { return fmt.Errorf("rename repository wiki: %v", err) } } ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() if err := newRepoRedirect(db.GetEngine(ctx), repo.Owner.ID, repo.ID, oldRepoName, newRepoName); err != nil { return err } return committer.Commit() } func getRepositoriesByForkID(e db.Engine, forkID int64) ([]*repo_model.Repository, error) { repos := make([]*repo_model.Repository, 0, 10) return repos, e. Where("fork_id=?", forkID). Find(&repos) } // GetRepositoriesByForkID returns all repositories with given fork ID. func GetRepositoriesByForkID(forkID int64) ([]*repo_model.Repository, error) { return getRepositoriesByForkID(db.GetEngine(db.DefaultContext), forkID) } func updateRepository(ctx context.Context, repo *repo_model.Repository, visibilityChanged bool) (err error) { repo.LowerName = strings.ToLower(repo.Name)
-
@@ -740,7 +613,7 @@ func updateRepository(ctx context.Context, repo *repo_model.Repository, visibilireturn err } forkRepos, err := getRepositoriesByForkID(e, repo.ID) forkRepos, err := repo_model.GetRepositoriesByForkID(ctx, repo.ID) if err != nil { return fmt.Errorf("getRepositoriesByForkID: %v", err) }
-
@@ -775,58 +648,6 @@ func UpdateRepository(repo *repo_model.Repository, visibilityChanged bool) (errreturn committer.Commit() } // UpdateRepositoryOwnerNames updates repository owner_names (this should only be used when the ownerName has changed case) func UpdateRepositoryOwnerNames(ownerID int64, ownerName string) error { if ownerID == 0 { return nil } ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() if _, err := db.GetEngine(ctx).Where("owner_id = ?", ownerID).Cols("owner_name").Update(&repo_model.Repository{ OwnerName: ownerName, }); err != nil { return err } return committer.Commit() } // UpdateRepositoryUpdatedTime updates a repository's updated time func UpdateRepositoryUpdatedTime(repoID int64, updateTime time.Time) error { _, err := db.GetEngine(db.DefaultContext).Exec("UPDATE repository SET updated_unix = ? WHERE id = ?", updateTime.Unix(), repoID) return err } // UpdateRepositoryUnits updates a repository's units func UpdateRepositoryUnits(repo *repo_model.Repository, units []repo_model.RepoUnit, deleteUnitTypes []unit.Type) (err error) { ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() // Delete existing settings of units before adding again for _, u := range units { deleteUnitTypes = append(deleteUnitTypes, u.Type) } if _, err = db.GetEngine(ctx).Where("repo_id = ?", repo.ID).In("type", deleteUnitTypes).Delete(new(repo_model.RepoUnit)); err != nil { return err } if len(units) > 0 { if err = db.Insert(ctx, units); err != nil { return err } } return committer.Commit() } // DeleteRepository deletes a repository for a user or organization. // make sure if you call this func to close open sessions (sqlite will otherwise get a deadlock) func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
-
@@ -927,11 +748,11 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {&repo_model.PushMirror{RepoID: repoID}, &Release{RepoID: repoID}, &repo_model.RepoIndexerStatus{RepoID: repoID}, &RepoRedirect{RedirectRepoID: repoID}, &repo_model.Redirect{RedirectRepoID: repoID}, &repo_model.RepoUnit{RepoID: repoID}, &Star{RepoID: repoID}, &repo_model.Star{RepoID: repoID}, &Task{RepoID: repoID}, &Watch{RepoID: repoID}, &repo_model.Watch{RepoID: repoID}, &webhook.Webhook{RepoID: repoID}, ); err != nil { return fmt.Errorf("deleteBeans: %v", err)
-
@@ -964,7 +785,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {} if len(repo.Topics) > 0 { if err := removeTopicsFromRepo(sess, repo.ID); err != nil { if err := repo_model.RemoveTopicsFromRepo(ctx, repo.ID); err != nil { return err } }
-
@@ -1261,76 +1082,6 @@ func CheckRepoStats(ctx context.Context) error {return nil } // SetArchiveRepoState sets if a repo is archived func SetArchiveRepoState(repo *repo_model.Repository, isArchived bool) (err error) { repo.IsArchived = isArchived _, err = db.GetEngine(db.DefaultContext).Where("id = ?", repo.ID).Cols("is_archived").NoAutoTime().Update(repo) return } // ___________ __ // \_ _____/__________| | __ // | __)/ _ \_ __ \ |/ / // | \( <_> ) | \/ < // \___ / \____/|__| |__|_ \ // \/ \/ // GetForkedRepo checks if given user has already forked a repository with given ID. func GetForkedRepo(ownerID, repoID int64) *repo_model.Repository { repo := new(repo_model.Repository) has, _ := db.GetEngine(db.DefaultContext). Where("owner_id=? AND fork_id=?", ownerID, repoID). Get(repo) if has { return repo } return nil } // HasForkedRepo checks if given user has already forked a repository with given ID. func HasForkedRepo(ownerID, repoID int64) bool { has, _ := db.GetEngine(db.DefaultContext). Table("repository"). Where("owner_id=? AND fork_id=?", ownerID, repoID). Exist() return has } // GetForks returns all the forks of the repository func GetForks(repo *repo_model.Repository, listOptions db.ListOptions) ([]*repo_model.Repository, error) { if listOptions.Page == 0 { forks := make([]*repo_model.Repository, 0, repo.NumForks) return forks, db.GetEngine(db.DefaultContext).Find(&forks, &repo_model.Repository{ForkID: repo.ID}) } sess := db.GetPaginatedSession(&listOptions) forks := make([]*repo_model.Repository, 0, listOptions.PageSize) return forks, sess.Find(&forks, &repo_model.Repository{ForkID: repo.ID}) } // GetUserFork return user forked repository from this repository, if not forked return nil func GetUserFork(repoID, userID int64) (*repo_model.Repository, error) { var forkedRepo repo_model.Repository has, err := db.GetEngine(db.DefaultContext).Where("fork_id = ?", repoID).And("owner_id = ?", userID).Get(&forkedRepo) if err != nil { return nil, err } if !has { return nil, nil } return &forkedRepo, nil } func updateRepositoryCols(e db.Engine, repo *repo_model.Repository, cols ...string) error { _, err := e.ID(repo.ID).Cols(cols...).Update(repo) return err } // UpdateRepositoryCols updates repository's columns func UpdateRepositoryCols(repo *repo_model.Repository, cols ...string) error { return updateRepositoryCols(db.GetEngine(db.DefaultContext), repo, cols...) } func updateUserStarNumbers(users []user_model.User) error { ctx, committer, err := db.TxContext() if err != nil {
-
@@ -1370,28 +1121,6 @@ func DoctorUserStarNum() (err error) {return } // IterateRepository iterate repositories func IterateRepository(f func(repo *repo_model.Repository) error) error { var start int batchSize := setting.Database.IterateBufferSize for { repos := make([]*repo_model.Repository, 0, batchSize) if err := db.GetEngine(db.DefaultContext).Limit(batchSize, start).Find(&repos); err != nil { return err } if len(repos) == 0 { return nil } start += len(repos) for _, repo := range repos { if err := f(repo); err != nil { return err } } } } // LinkedRepository returns the linked repo if any func LinkedRepository(a *repo_model.Attachment) (*repo_model.Repository, unit.Type, error) { if a.IssueID != 0 {
-
-
-
@@ -107,3 +107,10 @@ func FindRepoArchives(opts FindRepoArchiversOption) ([]*RepoArchiver, error) {Find(&archivers) return archivers, err } // SetArchiveRepoState sets if a repo is archived func SetArchiveRepoState(repo *Repository, isArchived bool) (err error) { repo.IsArchived = isArchived _, err = db.GetEngine(db.DefaultContext).Where("id = ?", repo.ID).Cols("is_archived").NoAutoTime().Update(repo) return }
-
-
models/repo/fork.go (new)
-
@@ -0,0 +1,69 @@// 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 repo import ( "context" "code.gitea.io/gitea/models/db" ) func getRepositoriesByForkID(e db.Engine, forkID int64) ([]*Repository, error) { repos := make([]*Repository, 0, 10) return repos, e. Where("fork_id=?", forkID). Find(&repos) } // GetRepositoriesByForkID returns all repositories with given fork ID. func GetRepositoriesByForkID(ctx context.Context, forkID int64) ([]*Repository, error) { return getRepositoriesByForkID(db.GetEngine(ctx), forkID) } // GetForkedRepo checks if given user has already forked a repository with given ID. func GetForkedRepo(ownerID, repoID int64) *Repository { repo := new(Repository) has, _ := db.GetEngine(db.DefaultContext). Where("owner_id=? AND fork_id=?", ownerID, repoID). Get(repo) if has { return repo } return nil } // HasForkedRepo checks if given user has already forked a repository with given ID. func HasForkedRepo(ownerID, repoID int64) bool { has, _ := db.GetEngine(db.DefaultContext). Table("repository"). Where("owner_id=? AND fork_id=?", ownerID, repoID). Exist() return has } // GetUserFork return user forked repository from this repository, if not forked return nil func GetUserFork(repoID, userID int64) (*Repository, error) { var forkedRepo Repository has, err := db.GetEngine(db.DefaultContext).Where("fork_id = ?", repoID).And("owner_id = ?", userID).Get(&forkedRepo) if err != nil { return nil, err } if !has { return nil, nil } return &forkedRepo, nil } // GetForks returns all the forks of the repository func GetForks(repo *Repository, listOptions db.ListOptions) ([]*Repository, error) { if listOptions.Page == 0 { forks := make([]*Repository, 0, repo.NumForks) return forks, db.GetEngine(db.DefaultContext).Find(&forks, &Repository{ForkID: repo.ID}) } sess := db.GetPaginatedSession(&listOptions) forks := make([]*Repository, 0, listOptions.PageSize) return forks, sess.Find(&forks, &Repository{ForkID: repo.ID}) }
-
-
models/repo/fork_test.go (new)
-
@@ -0,0 +1,32 @@// 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 repo import ( "testing" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" ) func TestGetUserFork(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // User13 has repo 11 forked from repo10 repo, err := GetRepositoryByID(10) assert.NoError(t, err) assert.NotNil(t, repo) repo, err = GetUserFork(repo.ID, 13) assert.NoError(t, err) assert.NotNil(t, repo) repo, err = GetRepositoryByID(9) assert.NoError(t, err) assert.NotNil(t, repo) repo, err = GetUserFork(repo.ID, 13) assert.NoError(t, err) assert.Nil(t, repo) }
-
-
-
@@ -18,5 +18,11 @@ func TestMain(m *testing.M) {"repository.yml", "repo_unit.yml", "repo_indexer_status.yml", "repo_redirect.yml", "watch.yml", "star.yml", "topic.yml", "repo_topic.yml", "user.yml", ) }
-
-
models/repo/redirect.go (new)
-
@@ -0,0 +1,82 @@// Copyright 2017 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 repo import ( "context" "fmt" "strings" "code.gitea.io/gitea/models/db" ) // ErrRedirectNotExist represents a "RedirectNotExist" kind of error. type ErrRedirectNotExist struct { OwnerID int64 RepoName string } // IsErrRedirectNotExist check if an error is an ErrRepoRedirectNotExist. func IsErrRedirectNotExist(err error) bool { _, ok := err.(ErrRedirectNotExist) return ok } func (err ErrRedirectNotExist) Error() string { return fmt.Sprintf("repository redirect does not exist [uid: %d, name: %s]", err.OwnerID, err.RepoName) } // Redirect represents that a repo name should be redirected to another type Redirect struct { ID int64 `xorm:"pk autoincr"` OwnerID int64 `xorm:"UNIQUE(s)"` LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"` RedirectRepoID int64 // repoID to redirect to } // TableName represents real table name in database func (Redirect) TableName() string { return "repo_redirect" } func init() { db.RegisterModel(new(Redirect)) } // LookupRedirect look up if a repository has a redirect name func LookupRedirect(ownerID int64, repoName string) (int64, error) { repoName = strings.ToLower(repoName) redirect := &Redirect{OwnerID: ownerID, LowerName: repoName} if has, err := db.GetEngine(db.DefaultContext).Get(redirect); err != nil { return 0, err } else if !has { return 0, ErrRedirectNotExist{OwnerID: ownerID, RepoName: repoName} } return redirect.RedirectRepoID, nil } // NewRedirect create a new repo redirect func NewRedirect(ctx context.Context, ownerID, repoID int64, oldRepoName, newRepoName string) error { oldRepoName = strings.ToLower(oldRepoName) newRepoName = strings.ToLower(newRepoName) if err := DeleteRedirect(ctx, ownerID, newRepoName); err != nil { return err } return db.Insert(ctx, &Redirect{ OwnerID: ownerID, LowerName: oldRepoName, RedirectRepoID: repoID, }) } // DeleteRedirect delete any redirect from the specified repo name to // anything else func DeleteRedirect(ctx context.Context, ownerID int64, repoName string) error { repoName = strings.ToLower(repoName) _, err := db.GetEngine(ctx).Delete(&Redirect{OwnerID: ownerID, LowerName: repoName}) return err }
-
-
-
@@ -0,0 +1,77 @@// Copyright 2017 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 repo import ( "testing" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" ) func TestLookupRedirect(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repoID, err := LookupRedirect(2, "oldrepo1") assert.NoError(t, err) assert.EqualValues(t, 1, repoID) _, err = LookupRedirect(unittest.NonexistentID, "doesnotexist") assert.True(t, IsErrRedirectNotExist(err)) } func TestNewRedirect(t *testing.T) { // redirect to a completely new name assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository) assert.NoError(t, NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "newreponame")) unittest.AssertExistsAndLoadBean(t, &Redirect{ OwnerID: repo.OwnerID, LowerName: repo.LowerName, RedirectRepoID: repo.ID, }) unittest.AssertExistsAndLoadBean(t, &Redirect{ OwnerID: repo.OwnerID, LowerName: "oldrepo1", RedirectRepoID: repo.ID, }) } func TestNewRedirect2(t *testing.T) { // redirect to previously used name assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository) assert.NoError(t, NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "oldrepo1")) unittest.AssertExistsAndLoadBean(t, &Redirect{ OwnerID: repo.OwnerID, LowerName: repo.LowerName, RedirectRepoID: repo.ID, }) unittest.AssertNotExistsBean(t, &Redirect{ OwnerID: repo.OwnerID, LowerName: "oldrepo1", RedirectRepoID: repo.ID, }) } func TestNewRedirect3(t *testing.T) { // redirect for a previously-unredirected repo assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository) assert.NoError(t, NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "newreponame")) unittest.AssertExistsAndLoadBean(t, &Redirect{ OwnerID: repo.OwnerID, LowerName: repo.LowerName, RedirectRepoID: repo.ID, }) }
-
-
-
@@ -25,6 +25,20 @@ import ("code.gitea.io/gitea/modules/util" ) var ( reservedRepoNames = []string{".", ".."} reservedRepoPatterns = []string{"*.git", "*.wiki", "*.rss", "*.atom"} ) // IsUsableRepoName returns true when repository is usable func IsUsableRepoName(name string) error { if db.AlphaDashDotPattern.MatchString(name) { // Note: usually this error is normally caught up earlier in the UI return db.ErrNameCharsNotAllowed{Name: name} } return db.IsUsableName(reservedRepoNames, reservedRepoPatterns, name) } // TrustModelType defines the types of trust model for this repository type TrustModelType int
-
@@ -734,3 +748,25 @@ func GetPublicRepositoryCount(u *user_model.User) (int64, error) {func GetPrivateRepositoryCount(u *user_model.User) (int64, error) { return getPrivateRepositoryCount(db.GetEngine(db.DefaultContext), u) } // IterateRepository iterate repositories func IterateRepository(f func(repo *Repository) error) error { var start int batchSize := setting.Database.IterateBufferSize for { repos := make([]*Repository, 0, batchSize) if err := db.GetEngine(db.DefaultContext).Limit(batchSize, start).Find(&repos); err != nil { return err } if len(repos) == 0 { return nil } start += len(repos) for _, repo := range repos { if err := f(repo); err != nil { return err } } } }
-
-
-
@@ -42,3 +42,10 @@ func TestGetPrivateRepositoryCount(t *testing.T) {assert.NoError(t, err) assert.Equal(t, int64(2), count) } func TestRepoAPIURL(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 10}).(*Repository) assert.Equal(t, "https://try.gitea.io/api/v1/repos/user12/repo10", repo.APIURL()) }
-
-
-
@@ -242,3 +242,29 @@ func UpdateRepoUnit(unit *RepoUnit) error {_, err := db.GetEngine(db.DefaultContext).ID(unit.ID).Update(unit) return err } // UpdateRepositoryUnits updates a repository's units func UpdateRepositoryUnits(repo *Repository, units []RepoUnit, deleteUnitTypes []unit.Type) (err error) { ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() // Delete existing settings of units before adding again for _, u := range units { deleteUnitTypes = append(deleteUnitTypes, u.Type) } if _, err = db.GetEngine(ctx).Where("repo_id = ?", repo.ID).In("type", deleteUnitTypes).Delete(new(RepoUnit)); err != nil { return err } if len(units) > 0 { if err = db.Insert(ctx, units); err != nil { return err } } return committer.Commit() }
-
-
-
@@ -2,11 +2,10 @@// Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package models package repo import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/timeutil" )
-
@@ -76,7 +75,7 @@ func isStaring(e db.Engine, userID, repoID int64) bool {} // GetStargazers returns the users that starred the repo. func GetStargazers(repo *repo_model.Repository, opts db.ListOptions) ([]*user_model.User, error) { func GetStargazers(repo *Repository, opts db.ListOptions) ([]*user_model.User, error) { sess := db.GetEngine(db.DefaultContext).Where("star.repo_id = ?", repo.ID). Join("LEFT", "star", "`user`.id = star.uid") if opts.Page > 0 {
-
-
-
@@ -2,13 +2,12 @@// Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package models package repo import ( "testing" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert"
-
@@ -36,7 +35,7 @@ func TestIsStaring(t *testing.T) {func TestRepository_GetStargazers(t *testing.T) { // repo with stargazers assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 4}).(*Repository) gazers, err := GetStargazers(repo, db.ListOptions{Page: 0}) assert.NoError(t, err) if assert.Len(t, gazers, 1) {
-
@@ -47,7 +46,7 @@ func TestRepository_GetStargazers(t *testing.T) {func TestRepository_GetStargazers2(t *testing.T) { // repo with stargazers assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository) gazers, err := GetStargazers(repo, db.ListOptions{Page: 0}) assert.NoError(t, err) assert.Len(t, gazers, 0)
-
-
-
@@ -2,15 +2,15 @@// Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package models package repo import ( "context" "fmt" "regexp" "strings" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/timeutil" "xorm.io/builder"
-
@@ -33,7 +33,7 @@ type Topic struct {} // RepoTopic represents associated repositories and topics type RepoTopic struct { type RepoTopic struct { //revive:disable-line:exported RepoID int64 `xorm:"pk"` TopicID int64 `xorm:"pk"` }
-
@@ -145,8 +145,9 @@ func removeTopicFromRepo(e db.Engine, repoID int64, topic *Topic) error {return nil } // removeTopicsFromRepo remove all topics from the repo and decrements respective topics repo count func removeTopicsFromRepo(e db.Engine, repoID int64) error { // RemoveTopicsFromRepo remove all topics from the repo and decrements respective topics repo count func RemoveTopicsFromRepo(ctx context.Context, repoID int64) error { e := db.GetEngine(ctx) _, err := e.Where( builder.In("id", builder.Select("topic_id").From("repo_topic").Where(builder.Eq{"repo_id": repoID}),
-
@@ -254,7 +255,7 @@ func AddTopic(repoID int64, topicName string) (*Topic, error) {return nil, err } if _, err := sess.ID(repoID).Cols("topics").Update(&repo_model.Repository{ if _, err := sess.ID(repoID).Cols("topics").Update(&Repository{ Topics: topicNames, }); err != nil { return nil, err
-
@@ -348,7 +349,7 @@ func SaveTopics(repoID int64, topicNames ...string) error {return err } if _, err := sess.ID(repoID).Cols("topics").Update(&repo_model.Repository{ if _, err := sess.ID(repoID).Cols("topics").Update(&Repository{ Topics: topicNames, }); err != nil { return err
-
@@ -356,3 +357,13 @@ func SaveTopics(repoID int64, topicNames ...string) error {return committer.Commit() } // GenerateTopics generates topics from a template repository func GenerateTopics(ctx context.Context, templateRepo, generateRepo *Repository) error { for _, topic := range templateRepo.Topics { if _, err := addTopicByNameToRepo(db.GetEngine(ctx), generateRepo.ID, topic); err != nil { return err } } return nil }
-
-
-
@@ -2,7 +2,7 @@// Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package models package repo import ( "testing"
-
-
models/repo/update.go (new)
-
@@ -0,0 +1,179 @@// 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 repo import ( "context" "fmt" "strings" "time" "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" ) // UpdateRepositoryOwnerNames updates repository owner_names (this should only be used when the ownerName has changed case) func UpdateRepositoryOwnerNames(ownerID int64, ownerName string) error { if ownerID == 0 { return nil } ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() if _, err := db.GetEngine(ctx).Where("owner_id = ?", ownerID).Cols("owner_name").Update(&Repository{ OwnerName: ownerName, }); err != nil { return err } return committer.Commit() } // UpdateRepositoryUpdatedTime updates a repository's updated time func UpdateRepositoryUpdatedTime(repoID int64, updateTime time.Time) error { _, err := db.GetEngine(db.DefaultContext).Exec("UPDATE repository SET updated_unix = ? WHERE id = ?", updateTime.Unix(), repoID) return err } // UpdateRepositoryColsCtx updates repository's columns func UpdateRepositoryColsCtx(ctx context.Context, repo *Repository, cols ...string) error { _, err := db.GetEngine(ctx).ID(repo.ID).Cols(cols...).Update(repo) return err } // UpdateRepositoryCols updates repository's columns func UpdateRepositoryCols(repo *Repository, cols ...string) error { return UpdateRepositoryColsCtx(db.DefaultContext, repo, cols...) } // ErrReachLimitOfRepo represents a "ReachLimitOfRepo" kind of error. type ErrReachLimitOfRepo struct { Limit int } // IsErrReachLimitOfRepo checks if an error is a ErrReachLimitOfRepo. func IsErrReachLimitOfRepo(err error) bool { _, ok := err.(ErrReachLimitOfRepo) return ok } func (err ErrReachLimitOfRepo) Error() string { return fmt.Sprintf("user has reached maximum limit of repositories [limit: %d]", err.Limit) } // ErrRepoAlreadyExist represents a "RepoAlreadyExist" kind of error. type ErrRepoAlreadyExist struct { Uname string Name string } // IsErrRepoAlreadyExist checks if an error is a ErrRepoAlreadyExist. func IsErrRepoAlreadyExist(err error) bool { _, ok := err.(ErrRepoAlreadyExist) return ok } func (err ErrRepoAlreadyExist) Error() string { return fmt.Sprintf("repository already exists [uname: %s, name: %s]", err.Uname, err.Name) } // ErrRepoFilesAlreadyExist represents a "RepoFilesAlreadyExist" kind of error. type ErrRepoFilesAlreadyExist struct { Uname string Name string } // IsErrRepoFilesAlreadyExist checks if an error is a ErrRepoAlreadyExist. func IsErrRepoFilesAlreadyExist(err error) bool { _, ok := err.(ErrRepoFilesAlreadyExist) return ok } func (err ErrRepoFilesAlreadyExist) Error() string { return fmt.Sprintf("repository files already exist [uname: %s, name: %s]", err.Uname, err.Name) } // CheckCreateRepository check if could created a repository func CheckCreateRepository(doer, u *user_model.User, name string, overwriteOrAdopt bool) error { if !doer.CanCreateRepo() { return ErrReachLimitOfRepo{u.MaxRepoCreation} } if err := IsUsableRepoName(name); err != nil { return err } has, err := IsRepositoryExist(u, name) if err != nil { return fmt.Errorf("IsRepositoryExist: %v", err) } else if has { return ErrRepoAlreadyExist{u.Name, name} } repoPath := RepoPath(u.Name, name) isExist, err := util.IsExist(repoPath) if err != nil { log.Error("Unable to check if %s exists. Error: %v", repoPath, err) return err } if !overwriteOrAdopt && isExist { return ErrRepoFilesAlreadyExist{u.Name, name} } return nil } // ChangeRepositoryName changes all corresponding setting from old repository name to new one. func ChangeRepositoryName(doer *user_model.User, repo *Repository, newRepoName string) (err error) { oldRepoName := repo.Name newRepoName = strings.ToLower(newRepoName) if err = IsUsableRepoName(newRepoName); err != nil { return err } if err := repo.GetOwner(db.DefaultContext); err != nil { return err } has, err := IsRepositoryExist(repo.Owner, newRepoName) if err != nil { return fmt.Errorf("IsRepositoryExist: %v", err) } else if has { return ErrRepoAlreadyExist{repo.Owner.Name, newRepoName} } newRepoPath := RepoPath(repo.Owner.Name, newRepoName) if err = util.Rename(repo.RepoPath(), newRepoPath); err != nil { return fmt.Errorf("rename repository directory: %v", err) } wikiPath := repo.WikiPath() isExist, err := util.IsExist(wikiPath) if err != nil { log.Error("Unable to check if %s exists. Error: %v", wikiPath, err) return err } if isExist { if err = util.Rename(wikiPath, WikiPath(repo.Owner.Name, newRepoName)); err != nil { return fmt.Errorf("rename repository wiki: %v", err) } } ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() if err := NewRedirect(ctx, repo.Owner.ID, repo.ID, oldRepoName, newRepoName); err != nil { return err } return committer.Commit() }
-
-
models/repo/watch.go (new)
-
@@ -0,0 +1,196 @@// Copyright 2017 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 repo import ( "context" "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" ) // WatchMode specifies what kind of watch the user has on a repository type WatchMode int8 const ( // WatchModeNone don't watch WatchModeNone WatchMode = iota // 0 // WatchModeNormal watch repository (from other sources) WatchModeNormal // 1 // WatchModeDont explicit don't auto-watch WatchModeDont // 2 // WatchModeAuto watch repository (from AutoWatchOnChanges) WatchModeAuto // 3 ) // Watch is connection request for receiving repository notification. type Watch struct { ID int64 `xorm:"pk autoincr"` UserID int64 `xorm:"UNIQUE(watch)"` RepoID int64 `xorm:"UNIQUE(watch)"` Mode WatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` } func init() { db.RegisterModel(new(Watch)) } // GetWatch gets what kind of subscription a user has on a given repository; returns dummy record if none found func GetWatch(ctx context.Context, userID, repoID int64) (Watch, error) { watch := Watch{UserID: userID, RepoID: repoID} has, err := db.GetEngine(ctx).Get(&watch) if err != nil { return watch, err } if !has { watch.Mode = WatchModeNone } return watch, nil } // IsWatchMode Decodes watchability of WatchMode func IsWatchMode(mode WatchMode) bool { return mode != WatchModeNone && mode != WatchModeDont } // IsWatching checks if user has watched given repository. func IsWatching(userID, repoID int64) bool { watch, err := GetWatch(db.DefaultContext, userID, repoID) return err == nil && IsWatchMode(watch.Mode) } func watchRepoMode(ctx context.Context, watch Watch, mode WatchMode) (err error) { if watch.Mode == mode { return nil } if mode == WatchModeAuto && (watch.Mode == WatchModeDont || IsWatchMode(watch.Mode)) { // Don't auto watch if already watching or deliberately not watching return nil } hadrec := watch.Mode != WatchModeNone needsrec := mode != WatchModeNone repodiff := 0 if IsWatchMode(mode) && !IsWatchMode(watch.Mode) { repodiff = 1 } else if !IsWatchMode(mode) && IsWatchMode(watch.Mode) { repodiff = -1 } watch.Mode = mode e := db.GetEngine(ctx) if !hadrec && needsrec { watch.Mode = mode if _, err = e.Insert(watch); err != nil { return err } } else if needsrec { watch.Mode = mode if _, err := e.ID(watch.ID).AllCols().Update(watch); err != nil { return err } } else if _, err = e.Delete(Watch{ID: watch.ID}); err != nil { return err } if repodiff != 0 { _, err = e.Exec("UPDATE `repository` SET num_watches = num_watches + ? WHERE id = ?", repodiff, watch.RepoID) } return err } // WatchRepoMode watch repository in specific mode. func WatchRepoMode(userID, repoID int64, mode WatchMode) (err error) { var watch Watch if watch, err = GetWatch(db.DefaultContext, userID, repoID); err != nil { return err } return watchRepoMode(db.DefaultContext, watch, mode) } // WatchRepoCtx watch or unwatch repository. func WatchRepoCtx(ctx context.Context, userID, repoID int64, doWatch bool) (err error) { var watch Watch if watch, err = GetWatch(ctx, userID, repoID); err != nil { return err } if !doWatch && watch.Mode == WatchModeAuto { err = watchRepoMode(ctx, watch, WatchModeDont) } else if !doWatch { err = watchRepoMode(ctx, watch, WatchModeNone) } else { err = watchRepoMode(ctx, watch, WatchModeNormal) } return err } // WatchRepo watch or unwatch repository. func WatchRepo(userID, repoID int64, watch bool) (err error) { return WatchRepoCtx(db.DefaultContext, userID, repoID, watch) } // GetWatchers returns all watchers of given repository. func GetWatchers(ctx context.Context, repoID int64) ([]*Watch, error) { watches := make([]*Watch, 0, 10) return watches, db.GetEngine(ctx).Where("`watch`.repo_id=?", repoID). And("`watch`.mode<>?", WatchModeDont). And("`user`.is_active=?", true). And("`user`.prohibit_login=?", false). Join("INNER", "`user`", "`user`.id = `watch`.user_id"). Find(&watches) } // GetRepoWatchersIDs returns IDs of watchers for a given repo ID // but avoids joining with `user` for performance reasons // User permissions must be verified elsewhere if required func GetRepoWatchersIDs(ctx context.Context, repoID int64) ([]int64, error) { ids := make([]int64, 0, 64) return ids, db.GetEngine(ctx).Table("watch"). Where("watch.repo_id=?", repoID). And("watch.mode<>?", WatchModeDont). Select("user_id"). Find(&ids) } // GetRepoWatchers returns range of users watching given repository. func GetRepoWatchers(repoID int64, opts db.ListOptions) ([]*user_model.User, error) { sess := db.GetEngine(db.DefaultContext).Where("watch.repo_id=?", repoID). Join("LEFT", "watch", "`user`.id=`watch`.user_id"). And("`watch`.mode<>?", WatchModeDont) if opts.Page > 0 { sess = db.SetSessionPagination(sess, &opts) users := make([]*user_model.User, 0, opts.PageSize) return users, sess.Find(&users) } users := make([]*user_model.User, 0, 8) return users, sess.Find(&users) } func watchIfAuto(ctx context.Context, userID, repoID int64, isWrite bool) error { if !isWrite || !setting.Service.AutoWatchOnChanges { return nil } watch, err := GetWatch(ctx, userID, repoID) if err != nil { return err } if watch.Mode != WatchModeNone { return nil } return watchRepoMode(ctx, watch, WatchModeAuto) } // WatchIfAuto subscribes to repo if AutoWatchOnChanges is set func WatchIfAuto(userID, repoID int64, isWrite bool) error { return watchIfAuto(db.DefaultContext, userID, repoID, isWrite) }
-
-
-
@@ -2,13 +2,12 @@// Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package models package repo import ( "testing" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting"
-
@@ -27,25 +26,11 @@ func TestIsWatching(t *testing.T) {assert.False(t, IsWatching(unittest.NonexistentID, unittest.NonexistentID)) } func TestWatchRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) const repoID = 3 const userID = 2 assert.NoError(t, WatchRepo(userID, repoID, true)) unittest.AssertExistsAndLoadBean(t, &Watch{RepoID: repoID, UserID: userID}) unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}) assert.NoError(t, WatchRepo(userID, repoID, false)) unittest.AssertNotExistsBean(t, &Watch{RepoID: repoID, UserID: userID}) unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}) } func TestGetWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) watches, err := GetWatchers(repo.ID) repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository) watches, err := GetWatchers(db.DefaultContext, repo.ID) assert.NoError(t, err) // One watchers are inactive, thus minus 1 assert.Len(t, watches, repo.NumWatches-1)
-
@@ -53,7 +38,7 @@ func TestGetWatchers(t *testing.T) {assert.EqualValues(t, repo.ID, watch.RepoID) } watches, err = GetWatchers(unittest.NonexistentID) watches, err = GetWatchers(db.DefaultContext, unittest.NonexistentID) assert.NoError(t, err) assert.Len(t, watches, 0) }
-
@@ -61,7 +46,7 @@ func TestGetWatchers(t *testing.T) {func TestRepository_GetWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository) watchers, err := GetRepoWatchers(repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, repo.NumWatches)
-
@@ -69,53 +54,16 @@ func TestRepository_GetWatchers(t *testing.T) {unittest.AssertExistsAndLoadBean(t, &Watch{UserID: watcher.ID, RepoID: repo.ID}) } repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 9}).(*repo_model.Repository) repo = unittest.AssertExistsAndLoadBean(t, &Repository{ID: 9}).(*Repository) watchers, err = GetRepoWatchers(repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, 0) } func TestNotifyWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) action := &Action{ ActUserID: 8, RepoID: 1, OpType: ActionStarRepo, } assert.NoError(t, NotifyWatchers(action)) // One watchers are inactive, thus action is only created for user 8, 1, 4, 11 unittest.AssertExistsAndLoadBean(t, &Action{ ActUserID: action.ActUserID, UserID: 8, RepoID: action.RepoID, OpType: action.OpType, }) unittest.AssertExistsAndLoadBean(t, &Action{ ActUserID: action.ActUserID, UserID: 1, RepoID: action.RepoID, OpType: action.OpType, }) unittest.AssertExistsAndLoadBean(t, &Action{ ActUserID: action.ActUserID, UserID: 4, RepoID: action.RepoID, OpType: action.OpType, }) unittest.AssertExistsAndLoadBean(t, &Action{ ActUserID: action.ActUserID, UserID: 11, RepoID: action.RepoID, OpType: action.OpType, }) } func TestWatchIfAuto(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository) watchers, err := GetRepoWatchers(repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, repo.NumWatches)
-
@@ -174,18 +122,18 @@ func TestWatchRepoMode(t *testing.T) {unittest.AssertCount(t, &Watch{UserID: 12, RepoID: 1}, 0) assert.NoError(t, WatchRepoMode(12, 1, RepoWatchModeAuto)) assert.NoError(t, WatchRepoMode(12, 1, WatchModeAuto)) unittest.AssertCount(t, &Watch{UserID: 12, RepoID: 1}, 1) unittest.AssertCount(t, &Watch{UserID: 12, RepoID: 1, Mode: RepoWatchModeAuto}, 1) unittest.AssertCount(t, &Watch{UserID: 12, RepoID: 1, Mode: WatchModeAuto}, 1) assert.NoError(t, WatchRepoMode(12, 1, RepoWatchModeNormal)) assert.NoError(t, WatchRepoMode(12, 1, WatchModeNormal)) unittest.AssertCount(t, &Watch{UserID: 12, RepoID: 1}, 1) unittest.AssertCount(t, &Watch{UserID: 12, RepoID: 1, Mode: RepoWatchModeNormal}, 1) unittest.AssertCount(t, &Watch{UserID: 12, RepoID: 1, Mode: WatchModeNormal}, 1) assert.NoError(t, WatchRepoMode(12, 1, RepoWatchModeDont)) assert.NoError(t, WatchRepoMode(12, 1, WatchModeDont)) unittest.AssertCount(t, &Watch{UserID: 12, RepoID: 1}, 1) unittest.AssertCount(t, &Watch{UserID: 12, RepoID: 1, Mode: RepoWatchModeDont}, 1) unittest.AssertCount(t, &Watch{UserID: 12, RepoID: 1, Mode: WatchModeDont}, 1) assert.NoError(t, WatchRepoMode(12, 1, RepoWatchModeNone)) assert.NoError(t, WatchRepoMode(12, 1, WatchModeNone)) unittest.AssertCount(t, &Watch{UserID: 12, RepoID: 1}, 0) }
-
-
models/repo_archiver.go (deleted)
-
@@ -1,25 +0,0 @@// 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 models import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" ) // LoadArchiverRepo loads repository func LoadArchiverRepo(archiver *repo_model.RepoArchiver) (*repo_model.Repository, error) { var repo repo_model.Repository has, err := db.GetEngine(db.DefaultContext).ID(archiver.RepoID).Get(&repo) if err != nil { return nil, err } if !has { return nil, repo_model.ErrRepoNotExist{ ID: archiver.RepoID, } } return &repo, nil }
-
-
-
@@ -207,15 +207,13 @@ func DeleteCollaboration(repo *repo_model.Repository, uid int64) (err error) {} defer committer.Close() sess := db.GetEngine(ctx) if has, err := sess.Delete(collaboration); err != nil || has == 0 { if has, err := db.GetEngine(ctx).Delete(collaboration); err != nil || has == 0 { return err } else if err = recalculateAccesses(ctx, repo); err != nil { return err } if err = watchRepo(sess, uid, repo.ID, false); err != nil { if err = repo_model.WatchRepoCtx(ctx, uid, repo.ID, false); err != nil { return err }
-
@@ -253,13 +251,12 @@ func reconsiderWatches(ctx context.Context, repo *repo_model.Repository, uid intif has, err := hasAccess(ctx, uid, repo); err != nil || has { return err } e := db.GetEngine(ctx) if err := watchRepo(e, uid, repo.ID, false); err != nil { if err := repo_model.WatchRepoCtx(ctx, uid, repo.ID, false); err != nil { return err } // Remove all IssueWatches a user has subscribed to in the repository return removeIssueWatchersByRepoID(e, uid, repo.ID) return removeIssueWatchersByRepoID(db.GetEngine(ctx), uid, repo.ID) } func getRepoTeams(e db.Engine, repo *repo_model.Repository) (teams []*Team, err error) {
-
-
-
@@ -8,15 +8,12 @@ import ("bufio" "bytes" "context" "strconv" "strings" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/storage" "github.com/gobwas/glob" )
-
@@ -70,49 +67,6 @@ func (gt GiteaTemplate) Globs() []glob.Glob {return gt.globs } // GenerateTopics generates topics from a template repository func GenerateTopics(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error { for _, topic := range templateRepo.Topics { if _, err := addTopicByNameToRepo(db.GetEngine(ctx), generateRepo.ID, topic); err != nil { return err } } return nil } // GenerateGitHooks generates git hooks from a template repository func GenerateGitHooks(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error { generateGitRepo, err := git.OpenRepository(generateRepo.RepoPath()) if err != nil { return err } defer generateGitRepo.Close() templateGitRepo, err := git.OpenRepository(templateRepo.RepoPath()) if err != nil { return err } defer templateGitRepo.Close() templateHooks, err := templateGitRepo.Hooks() if err != nil { return err } for _, templateHook := range templateHooks { generateHook, err := generateGitRepo.GetHook(templateHook.Name()) if err != nil { return err } generateHook.Content = templateHook.Content if err := generateHook.Update(); err != nil { return err } } return nil } // GenerateWebhooks generates webhooks from a template repository func GenerateWebhooks(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error { templateWebhooks, err := webhook.ListWebhooksByOpts(&webhook.ListWebhookOptions{RepoID: templateRepo.ID})
-
@@ -141,16 +95,6 @@ func GenerateWebhooks(ctx context.Context, templateRepo, generateRepo *repo_modereturn nil } // GenerateAvatar generates the avatar from a template repository func GenerateAvatar(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error { generateRepo.Avatar = strings.Replace(templateRepo.Avatar, strconv.FormatInt(templateRepo.ID, 10), strconv.FormatInt(generateRepo.ID, 10), 1) if _, err := storage.Copy(storage.RepoAvatars, generateRepo.CustomAvatarRelativePath(), storage.RepoAvatars, templateRepo.CustomAvatarRelativePath()); err != nil { return err } return updateRepositoryCols(db.GetEngine(ctx), generateRepo, "avatar") } // GenerateIssueLabels generates issue labels from a template repository func GenerateIssueLabels(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error { templateLabels, err := getLabelsByRepoID(db.GetEngine(ctx), templateRepo.ID, "", db.ListOptions{})
-
-
-
@@ -419,3 +419,21 @@ func FilterOutRepoIdsWithoutUnitAccess(u *user_model.User, repoIDs []int64, unit} return repoIDs[:i], nil } // GetRepoReaders returns all users that have explicit read access or higher to the repository. func GetRepoReaders(repo *repo_model.Repository) (_ []*user_model.User, err error) { return getUsersWithAccessMode(db.DefaultContext, repo, perm_model.AccessModeRead) } // GetRepoWriters returns all users that have write access to the repository. func GetRepoWriters(repo *repo_model.Repository) (_ []*user_model.User, err error) { return getUsersWithAccessMode(db.DefaultContext, repo, perm_model.AccessModeWrite) } // IsRepoReader returns true if user has explicit read access or higher to the repository. func IsRepoReader(repo *repo_model.Repository, userID int64) (bool, error) { if repo.OwnerID == userID { return true, nil } return db.GetEngine(db.DefaultContext).Where("repo_id = ? AND user_id = ? AND mode >= ?", repo.ID, userID, perm_model.AccessModeRead).Get(&Access{}) }
-
-
models/repo_redirect.go (deleted)
-
@@ -1,62 +0,0 @@// Copyright 2017 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 models import ( "strings" "code.gitea.io/gitea/models/db" ) // RepoRedirect represents that a repo name should be redirected to another type RepoRedirect struct { ID int64 `xorm:"pk autoincr"` OwnerID int64 `xorm:"UNIQUE(s)"` LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"` RedirectRepoID int64 // repoID to redirect to } func init() { db.RegisterModel(new(RepoRedirect)) } // LookupRepoRedirect look up if a repository has a redirect name func LookupRepoRedirect(ownerID int64, repoName string) (int64, error) { repoName = strings.ToLower(repoName) redirect := &RepoRedirect{OwnerID: ownerID, LowerName: repoName} if has, err := db.GetEngine(db.DefaultContext).Get(redirect); err != nil { return 0, err } else if !has { return 0, ErrRepoRedirectNotExist{OwnerID: ownerID, RepoName: repoName} } return redirect.RedirectRepoID, nil } // newRepoRedirect create a new repo redirect func newRepoRedirect(e db.Engine, ownerID, repoID int64, oldRepoName, newRepoName string) error { oldRepoName = strings.ToLower(oldRepoName) newRepoName = strings.ToLower(newRepoName) if err := deleteRepoRedirect(e, ownerID, newRepoName); err != nil { return err } if _, err := e.Insert(&RepoRedirect{ OwnerID: ownerID, LowerName: oldRepoName, RedirectRepoID: repoID, }); err != nil { return err } return nil } // deleteRepoRedirect delete any redirect from the specified repo name to // anything else func deleteRepoRedirect(e db.Engine, ownerID int64, repoName string) error { repoName = strings.ToLower(repoName) _, err := e.Delete(&RepoRedirect{OwnerID: ownerID, LowerName: repoName}) return err }
-
-
models/repo_redirect_test.go (deleted)
-
@@ -1,78 +0,0 @@// Copyright 2017 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 models import ( "testing" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" ) func TestLookupRepoRedirect(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repoID, err := LookupRepoRedirect(2, "oldrepo1") assert.NoError(t, err) assert.EqualValues(t, 1, repoID) _, err = LookupRepoRedirect(unittest.NonexistentID, "doesnotexist") assert.True(t, IsErrRepoRedirectNotExist(err)) } func TestNewRepoRedirect(t *testing.T) { // redirect to a completely new name assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) assert.NoError(t, newRepoRedirect(db.GetEngine(db.DefaultContext), repo.OwnerID, repo.ID, repo.Name, "newreponame")) unittest.AssertExistsAndLoadBean(t, &RepoRedirect{ OwnerID: repo.OwnerID, LowerName: repo.LowerName, RedirectRepoID: repo.ID, }) unittest.AssertExistsAndLoadBean(t, &RepoRedirect{ OwnerID: repo.OwnerID, LowerName: "oldrepo1", RedirectRepoID: repo.ID, }) } func TestNewRepoRedirect2(t *testing.T) { // redirect to previously used name assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) assert.NoError(t, newRepoRedirect(db.GetEngine(db.DefaultContext), repo.OwnerID, repo.ID, repo.Name, "oldrepo1")) unittest.AssertExistsAndLoadBean(t, &RepoRedirect{ OwnerID: repo.OwnerID, LowerName: repo.LowerName, RedirectRepoID: repo.ID, }) unittest.AssertNotExistsBean(t, &RepoRedirect{ OwnerID: repo.OwnerID, LowerName: "oldrepo1", RedirectRepoID: repo.ID, }) } func TestNewRepoRedirect3(t *testing.T) { // redirect for a previously-unredirected repo assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) assert.NoError(t, newRepoRedirect(db.GetEngine(db.DefaultContext), repo.OwnerID, repo.ID, repo.Name, "newreponame")) unittest.AssertExistsAndLoadBean(t, &RepoRedirect{ OwnerID: repo.OwnerID, LowerName: repo.LowerName, RedirectRepoID: repo.ID, }) }
-
-
-
@@ -5,11 +5,6 @@package models import ( "bytes" "crypto/md5" "fmt" "image" "image/png" "testing" "code.gitea.io/gitea/models/db"
-
@@ -22,6 +17,20 @@ import ("github.com/stretchr/testify/assert" ) func TestWatchRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) const repoID = 3 const userID = 2 assert.NoError(t, repo_model.WatchRepo(userID, repoID, true)) unittest.AssertExistsAndLoadBean(t, &repo_model.Watch{RepoID: repoID, UserID: userID}) unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}) assert.NoError(t, repo_model.WatchRepo(userID, repoID, false)) unittest.AssertNotExistsBean(t, &repo_model.Watch{RepoID: repoID, UserID: userID}) unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}) } func TestMetas(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase())
-
@@ -90,77 +99,6 @@ func TestUpdateRepositoryVisibilityChanged(t *testing.T) {assert.True(t, act.IsPrivate) } func TestGetUserFork(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // User13 has repo 11 forked from repo10 repo, err := repo_model.GetRepositoryByID(10) assert.NoError(t, err) assert.NotNil(t, repo) repo, err = GetUserFork(repo.ID, 13) assert.NoError(t, err) assert.NotNil(t, repo) repo, err = repo_model.GetRepositoryByID(9) assert.NoError(t, err) assert.NotNil(t, repo) repo, err = GetUserFork(repo.ID, 13) assert.NoError(t, err) assert.Nil(t, repo) } func TestRepoAPIURL(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) assert.Equal(t, "https://try.gitea.io/api/v1/repos/user12/repo10", repo.APIURL()) } func TestUploadAvatar(t *testing.T) { // Generate image myImage := image.NewRGBA(image.Rect(0, 0, 1, 1)) var buff bytes.Buffer png.Encode(&buff, myImage) assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) err := UploadRepoAvatar(repo, buff.Bytes()) assert.NoError(t, err) assert.Equal(t, fmt.Sprintf("%d-%x", 10, md5.Sum(buff.Bytes())), repo.Avatar) } func TestUploadBigAvatar(t *testing.T) { // Generate BIG image myImage := image.NewRGBA(image.Rect(0, 0, 5000, 1)) var buff bytes.Buffer png.Encode(&buff, myImage) assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) err := UploadRepoAvatar(repo, buff.Bytes()) assert.Error(t, err) } func TestDeleteAvatar(t *testing.T) { // Generate image myImage := image.NewRGBA(image.Rect(0, 0, 1, 1)) var buff bytes.Buffer png.Encode(&buff, myImage) assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) err := UploadRepoAvatar(repo, buff.Bytes()) assert.NoError(t, err) err = DeleteRepoAvatar(repo) assert.NoError(t, err) assert.Equal(t, "", repo.Avatar) } func TestDoctorUserStarNum(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase())
-
-
-
@@ -5,6 +5,7 @@package models import ( "context" "fmt" "os"
-
@@ -112,8 +113,8 @@ func GetPendingRepositoryTransfer(repo *repo_model.Repository) (*RepoTransfer, ereturn transfer, nil } func deleteRepositoryTransfer(e db.Engine, repoID int64) error { _, err := e.Where("repo_id = ?", repoID).Delete(&RepoTransfer{}) func deleteRepositoryTransfer(ctx context.Context, repoID int64) error { _, err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Delete(&RepoTransfer{}) return err }
-
@@ -125,14 +126,13 @@ func CancelRepositoryTransfer(repo *repo_model.Repository) error {return err } defer committer.Close() sess := db.GetEngine(ctx) repo.Status = repo_model.RepositoryReady if err := updateRepositoryCols(sess, repo, "status"); err != nil { if err := repo_model.UpdateRepositoryColsCtx(ctx, repo, "status"); err != nil { return err } if err := deleteRepositoryTransfer(sess, repo.ID); err != nil { if err := deleteRepositoryTransfer(ctx, repo.ID); err != nil { return err }
-
@@ -158,7 +158,6 @@ func CreatePendingRepositoryTransfer(doer, newOwner *user_model.User, repoID intreturn err } defer committer.Close() sess := db.GetEngine(ctx) repo, err := repo_model.GetRepositoryByIDCtx(ctx, repoID) if err != nil {
-
@@ -171,7 +170,7 @@ func CreatePendingRepositoryTransfer(doer, newOwner *user_model.User, repoID int} repo.Status = repo_model.RepositoryPendingTransfer if err := updateRepositoryCols(sess, repo, "status"); err != nil { if err := repo_model.UpdateRepositoryColsCtx(ctx, repo, "status"); err != nil { return err }
-
@@ -179,7 +178,10 @@ func CreatePendingRepositoryTransfer(doer, newOwner *user_model.User, repoID intif has, err := repo_model.IsRepositoryExistCtx(ctx, newOwner, repo.Name); err != nil { return fmt.Errorf("IsRepositoryExist: %v", err) } else if has { return ErrRepoAlreadyExist{newOwner.LowerName, repo.Name} return repo_model.ErrRepoAlreadyExist{ Uname: newOwner.LowerName, Name: repo.Name, } } transfer := &RepoTransfer{
-
@@ -256,7 +258,10 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *repo_moif has, err := repo_model.IsRepositoryExistCtx(ctx, newOwner, repo.Name); err != nil { return fmt.Errorf("IsRepositoryExist: %v", err) } else if has { return ErrRepoAlreadyExist{newOwnerName, repo.Name} return repo_model.ErrRepoAlreadyExist{ Uname: newOwnerName, Name: repo.Name, } } oldOwner := repo.Owner
-
@@ -336,13 +341,13 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *repo_moreturn fmt.Errorf("decrease old owner repository count: %v", err) } if err := watchRepo(sess, doer.ID, repo.ID, true); err != nil { if err := repo_model.WatchRepoCtx(ctx, doer.ID, repo.ID, true); err != nil { return fmt.Errorf("watchRepo: %v", err) } // Remove watch for organization. if oldOwner.IsOrganization() { if err := watchRepo(sess, oldOwner.ID, repo.ID, false); err != nil { if err := repo_model.WatchRepoCtx(ctx, oldOwner.ID, repo.ID, false); err != nil { return fmt.Errorf("watchRepo [false]: %v", err) } }
-
@@ -399,21 +404,21 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *repo_mowikiRenamed = true } if err := deleteRepositoryTransfer(sess, repo.ID); err != nil { if err := deleteRepositoryTransfer(ctx, repo.ID); err != nil { return fmt.Errorf("deleteRepositoryTransfer: %v", err) } repo.Status = repo_model.RepositoryReady if err := updateRepositoryCols(sess, repo, "status"); err != nil { if err := repo_model.UpdateRepositoryColsCtx(ctx, repo, "status"); err != nil { return err } // If there was previously a redirect at this location, remove it. if err := deleteRepoRedirect(sess, newOwner.ID, repo.Name); err != nil { if err := repo_model.DeleteRedirect(ctx, newOwner.ID, repo.Name); err != nil { return fmt.Errorf("delete repo redirect: %v", err) } if err := newRepoRedirect(sess, oldOwner.ID, repo.ID, repo.Name, repo.Name); err != nil { return fmt.Errorf("newRepoRedirect: %v", err) if err := repo_model.NewRedirect(ctx, oldOwner.ID, repo.ID, repo.Name, repo.Name); err != nil { return fmt.Errorf("repo_model.NewRedirect: %v", err) } return committer.Commit()
-
-
models/repo_watch.go (deleted)
-
@@ -1,328 +0,0 @@// Copyright 2017 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 models import ( "context" "fmt" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" ) // RepoWatchMode specifies what kind of watch the user has on a repository type RepoWatchMode int8 const ( // RepoWatchModeNone don't watch RepoWatchModeNone RepoWatchMode = iota // 0 // RepoWatchModeNormal watch repository (from other sources) RepoWatchModeNormal // 1 // RepoWatchModeDont explicit don't auto-watch RepoWatchModeDont // 2 // RepoWatchModeAuto watch repository (from AutoWatchOnChanges) RepoWatchModeAuto // 3 ) // Watch is connection request for receiving repository notification. type Watch struct { ID int64 `xorm:"pk autoincr"` UserID int64 `xorm:"UNIQUE(watch)"` RepoID int64 `xorm:"UNIQUE(watch)"` Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` } func init() { db.RegisterModel(new(Watch)) } // getWatch gets what kind of subscription a user has on a given repository; returns dummy record if none found func getWatch(e db.Engine, userID, repoID int64) (Watch, error) { watch := Watch{UserID: userID, RepoID: repoID} has, err := e.Get(&watch) if err != nil { return watch, err } if !has { watch.Mode = RepoWatchModeNone } return watch, nil } // Decodes watchability of RepoWatchMode func isWatchMode(mode RepoWatchMode) bool { return mode != RepoWatchModeNone && mode != RepoWatchModeDont } // IsWatching checks if user has watched given repository. func IsWatching(userID, repoID int64) bool { watch, err := getWatch(db.GetEngine(db.DefaultContext), userID, repoID) return err == nil && isWatchMode(watch.Mode) } func watchRepoMode(e db.Engine, watch Watch, mode RepoWatchMode) (err error) { if watch.Mode == mode { return nil } if mode == RepoWatchModeAuto && (watch.Mode == RepoWatchModeDont || isWatchMode(watch.Mode)) { // Don't auto watch if already watching or deliberately not watching return nil } hadrec := watch.Mode != RepoWatchModeNone needsrec := mode != RepoWatchModeNone repodiff := 0 if isWatchMode(mode) && !isWatchMode(watch.Mode) { repodiff = 1 } else if !isWatchMode(mode) && isWatchMode(watch.Mode) { repodiff = -1 } watch.Mode = mode if !hadrec && needsrec { watch.Mode = mode if _, err = e.Insert(watch); err != nil { return err } } else if needsrec { watch.Mode = mode if _, err := e.ID(watch.ID).AllCols().Update(watch); err != nil { return err } } else if _, err = e.Delete(Watch{ID: watch.ID}); err != nil { return err } if repodiff != 0 { _, err = e.Exec("UPDATE `repository` SET num_watches = num_watches + ? WHERE id = ?", repodiff, watch.RepoID) } return err } // WatchRepoMode watch repository in specific mode. func WatchRepoMode(userID, repoID int64, mode RepoWatchMode) (err error) { var watch Watch if watch, err = getWatch(db.GetEngine(db.DefaultContext), userID, repoID); err != nil { return err } return watchRepoMode(db.GetEngine(db.DefaultContext), watch, mode) } func watchRepo(e db.Engine, userID, repoID int64, doWatch bool) (err error) { var watch Watch if watch, err = getWatch(e, userID, repoID); err != nil { return err } if !doWatch && watch.Mode == RepoWatchModeAuto { err = watchRepoMode(e, watch, RepoWatchModeDont) } else if !doWatch { err = watchRepoMode(e, watch, RepoWatchModeNone) } else { err = watchRepoMode(e, watch, RepoWatchModeNormal) } return err } // WatchRepo watch or unwatch repository. func WatchRepo(userID, repoID int64, watch bool) (err error) { return watchRepo(db.GetEngine(db.DefaultContext), userID, repoID, watch) } func getWatchers(e db.Engine, repoID int64) ([]*Watch, error) { watches := make([]*Watch, 0, 10) return watches, e.Where("`watch`.repo_id=?", repoID). And("`watch`.mode<>?", RepoWatchModeDont). And("`user`.is_active=?", true). And("`user`.prohibit_login=?", false). Join("INNER", "`user`", "`user`.id = `watch`.user_id"). Find(&watches) } // GetWatchers returns all watchers of given repository. func GetWatchers(repoID int64) ([]*Watch, error) { return getWatchers(db.GetEngine(db.DefaultContext), repoID) } // GetRepoWatchersIDs returns IDs of watchers for a given repo ID // but avoids joining with `user` for performance reasons // User permissions must be verified elsewhere if required func GetRepoWatchersIDs(repoID int64) ([]int64, error) { return getRepoWatchersIDs(db.GetEngine(db.DefaultContext), repoID) } func getRepoWatchersIDs(e db.Engine, repoID int64) ([]int64, error) { ids := make([]int64, 0, 64) return ids, e.Table("watch"). Where("watch.repo_id=?", repoID). And("watch.mode<>?", RepoWatchModeDont). Select("user_id"). Find(&ids) } // GetRepoWatchers returns range of users watching given repository. func GetRepoWatchers(repoID int64, opts db.ListOptions) ([]*user_model.User, error) { sess := db.GetEngine(db.DefaultContext).Where("watch.repo_id=?", repoID). Join("LEFT", "watch", "`user`.id=`watch`.user_id"). And("`watch`.mode<>?", RepoWatchModeDont) if opts.Page > 0 { sess = db.SetSessionPagination(sess, &opts) users := make([]*user_model.User, 0, opts.PageSize) return users, sess.Find(&users) } users := make([]*user_model.User, 0, 8) return users, sess.Find(&users) } func notifyWatchers(ctx context.Context, actions ...*Action) error { var watchers []*Watch var repo *repo_model.Repository var err error var permCode []bool var permIssue []bool var permPR []bool e := db.GetEngine(ctx) for _, act := range actions { repoChanged := repo == nil || repo.ID != act.RepoID if repoChanged { // Add feeds for user self and all watchers. watchers, err = getWatchers(e, act.RepoID) if err != nil { return fmt.Errorf("get watchers: %v", err) } } // Add feed for actioner. act.UserID = act.ActUserID if _, err = e.InsertOne(act); err != nil { return fmt.Errorf("insert new actioner: %v", err) } if repoChanged { act.loadRepo() repo = act.Repo // check repo owner exist. if err := act.Repo.GetOwner(ctx); err != nil { return fmt.Errorf("can't get repo owner: %v", err) } } else if act.Repo == nil { act.Repo = repo } // Add feed for organization if act.Repo.Owner.IsOrganization() && act.ActUserID != act.Repo.Owner.ID { act.ID = 0 act.UserID = act.Repo.Owner.ID if _, err = e.InsertOne(act); err != nil { return fmt.Errorf("insert new actioner: %v", err) } } if repoChanged { permCode = make([]bool, len(watchers)) permIssue = make([]bool, len(watchers)) permPR = make([]bool, len(watchers)) for i, watcher := range watchers { user, err := user_model.GetUserByIDEngine(e, watcher.UserID) if err != nil { permCode[i] = false permIssue[i] = false permPR[i] = false continue } perm, err := getUserRepoPermission(ctx, repo, user) if err != nil { permCode[i] = false permIssue[i] = false permPR[i] = false continue } permCode[i] = perm.CanRead(unit.TypeCode) permIssue[i] = perm.CanRead(unit.TypeIssues) permPR[i] = perm.CanRead(unit.TypePullRequests) } } for i, watcher := range watchers { if act.ActUserID == watcher.UserID { continue } act.ID = 0 act.UserID = watcher.UserID act.Repo.Units = nil switch act.OpType { case ActionCommitRepo, ActionPushTag, ActionDeleteTag, ActionPublishRelease, ActionDeleteBranch: if !permCode[i] { continue } case ActionCreateIssue, ActionCommentIssue, ActionCloseIssue, ActionReopenIssue: if !permIssue[i] { continue } case ActionCreatePullRequest, ActionCommentPull, ActionMergePullRequest, ActionClosePullRequest, ActionReopenPullRequest: if !permPR[i] { continue } } if _, err = e.InsertOne(act); err != nil { return fmt.Errorf("insert new action: %v", err) } } } return nil } // NotifyWatchers creates batch of actions for every watcher. func NotifyWatchers(actions ...*Action) error { return notifyWatchers(db.DefaultContext, actions...) } // NotifyWatchersActions creates batch of actions for every watcher. func NotifyWatchersActions(acts []*Action) error { ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() for _, act := range acts { if err := notifyWatchers(ctx, act); err != nil { return err } } return committer.Commit() } func watchIfAuto(e db.Engine, userID, repoID int64, isWrite bool) error { if !isWrite || !setting.Service.AutoWatchOnChanges { return nil } watch, err := getWatch(e, userID, repoID) if err != nil { return err } if watch.Mode != RepoWatchModeNone { return nil } return watchRepoMode(e, watch, RepoWatchModeAuto) } // WatchIfAuto subscribes to repo if AutoWatchOnChanges is set func WatchIfAuto(userID, repoID int64, isWrite bool) error { return watchIfAuto(db.GetEngine(db.DefaultContext), userID, repoID, isWrite) }
-
-
-
@@ -50,8 +50,8 @@ func GetStatistic() (stats Statistic) {stats.Counter.Org = CountOrganizations() stats.Counter.PublicKey, _ = e.Count(new(asymkey_model.PublicKey)) stats.Counter.Repo = repo_model.CountRepositories(true) stats.Counter.Watch, _ = e.Count(new(Watch)) stats.Counter.Star, _ = e.Count(new(Star)) stats.Counter.Watch, _ = e.Count(new(repo_model.Watch)) stats.Counter.Star, _ = e.Count(new(repo_model.Star)) stats.Counter.Action, _ = e.Count(new(Action)) stats.Counter.Access, _ = e.Count(new(Access))
-
-
models/update.go (deleted)
-
@@ -1,100 +0,0 @@// Copyright 2014 The Gogs 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 models import ( "context" "fmt" "strings" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" ) // PushUpdateDeleteTagsContext updates a number of delete tags with context func PushUpdateDeleteTagsContext(ctx context.Context, repo *repo_model.Repository, tags []string) error { return pushUpdateDeleteTags(db.GetEngine(ctx), repo, tags) } func pushUpdateDeleteTags(e db.Engine, repo *repo_model.Repository, tags []string) error { if len(tags) == 0 { return nil } lowerTags := make([]string, 0, len(tags)) for _, tag := range tags { lowerTags = append(lowerTags, strings.ToLower(tag)) } if _, err := e. Where("repo_id = ? AND is_tag = ?", repo.ID, true). In("lower_tag_name", lowerTags). Delete(new(Release)); err != nil { return fmt.Errorf("Delete: %v", err) } if _, err := e. Where("repo_id = ? AND is_tag = ?", repo.ID, false). In("lower_tag_name", lowerTags). Cols("is_draft", "num_commits", "sha1"). Update(&Release{ IsDraft: true, }); err != nil { return fmt.Errorf("Update: %v", err) } return nil } // PushUpdateDeleteTag must be called for any push actions to delete tag func PushUpdateDeleteTag(repo *repo_model.Repository, tagName string) error { rel, err := GetRelease(repo.ID, tagName) if err != nil { if IsErrReleaseNotExist(err) { return nil } return fmt.Errorf("GetRelease: %v", err) } if rel.IsTag { if _, err = db.GetEngine(db.DefaultContext).ID(rel.ID).Delete(new(Release)); err != nil { return fmt.Errorf("Delete: %v", err) } } else { rel.IsDraft = true rel.NumCommits = 0 rel.Sha1 = "" if _, err = db.GetEngine(db.DefaultContext).ID(rel.ID).AllCols().Update(rel); err != nil { return fmt.Errorf("Update: %v", err) } } return nil } // SaveOrUpdateTag must be called for any push actions to add tag func SaveOrUpdateTag(repo *repo_model.Repository, newRel *Release) error { rel, err := GetRelease(repo.ID, newRel.TagName) if err != nil && !IsErrReleaseNotExist(err) { return fmt.Errorf("GetRelease: %v", err) } if rel == nil { rel = newRel if _, err = db.GetEngine(db.DefaultContext).Insert(rel); err != nil { return fmt.Errorf("InsertOne: %v", err) } } else { rel.Sha1 = newRel.Sha1 rel.CreatedUnix = newRel.CreatedUnix rel.NumCommits = newRel.NumCommits rel.IsDraft = false if rel.IsTag && newRel.PublisherID > 0 { rel.PublisherID = newRel.PublisherID } if _, err = db.GetEngine(db.DefaultContext).ID(rel.ID).AllCols().Update(rel); err != nil { return fmt.Errorf("Update: %v", err) } } return nil }
-
-
-
@@ -150,7 +150,7 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {// ***** START: Watch ***** watchedRepoIDs := make([]int64, 0, 10) if err = e.Table("watch").Cols("watch.repo_id"). Where("watch.user_id = ?", u.ID).And("watch.mode <>?", RepoWatchModeDont).Find(&watchedRepoIDs); err != nil { Where("watch.user_id = ?", u.ID).And("watch.mode <>?", repo_model.WatchModeDont).Find(&watchedRepoIDs); err != nil { return fmt.Errorf("get all watches: %v", err) } if _, err = e.Decr("num_watches").In("id", watchedRepoIDs).NoAutoTime().Update(new(repo_model.Repository)); err != nil {
-
@@ -190,8 +190,8 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {&AccessToken{UID: u.ID}, &Collaboration{UserID: u.ID}, &Access{UserID: u.ID}, &Watch{UserID: u.ID}, &Star{UID: u.ID}, &repo_model.Watch{UserID: u.ID}, &repo_model.Star{UID: u.ID}, &user_model.Follow{UserID: u.ID}, &user_model.Follow{FollowID: u.ID}, &Action{UserID: u.ID},
-
@@ -296,7 +296,7 @@ func GetStarredRepos(userID int64, private bool, listOptions db.ListOptions) ([]// GetWatchedRepos returns the repos watched by a particular user func GetWatchedRepos(userID int64, private bool, listOptions db.ListOptions) ([]*repo_model.Repository, int64, error) { sess := db.GetEngine(db.DefaultContext).Where("watch.user_id=?", userID). And("`watch`.mode<>?", RepoWatchModeDont). And("`watch`.mode<>?", repo_model.WatchModeDont). Join("LEFT", "watch", "`repository`.id=`watch`.repo_id") if !private { sess = sess.And("is_private=?", false)
-
-
-
@@ -443,10 +443,10 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {repo, err := repo_model.GetRepositoryByName(owner.ID, repoName) if err != nil { if repo_model.IsErrRepoNotExist(err) { redirectRepoID, err := models.LookupRepoRedirect(owner.ID, repoName) redirectRepoID, err := repo_model.LookupRedirect(owner.ID, repoName) if err == nil { RedirectToRepo(ctx, redirectRepoID) } else if models.IsErrRepoRedirectNotExist(err) { } else if repo_model.IsErrRedirectNotExist(err) { if ctx.FormString("go-get") == "1" { EarlyResponseForGoGetMeta(ctx) return
-
@@ -512,8 +512,8 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {ctx.Data["WikiCloneLink"] = repo.WikiCloneLink() if ctx.IsSigned { ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.ID, repo.ID) ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID) ctx.Data["IsWatchingRepo"] = repo_model.IsWatching(ctx.User.ID, repo.ID) ctx.Data["IsStaringRepo"] = repo_model.IsStaring(ctx.User.ID, repo.ID) } if repo.IsFork {
-
@@ -613,7 +613,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {// People who have push access or have forked repository can propose a new pull request. canPush := ctx.Repo.CanWrite(unit_model.TypeCode) || (ctx.IsSigned && models.HasForkedRepo(ctx.User.ID, ctx.Repo.Repository.ID)) (ctx.IsSigned && repo_model.HasForkedRepo(ctx.User.ID, ctx.Repo.Repository.ID)) canCompare := false // Pull request is allowed if this is a fork repository
-
-
-
@@ -334,7 +334,7 @@ func ToAnnotatedTagObject(repo *repo_model.Repository, commit *git.Commit) *api.} // ToTopicResponse convert from models.Topic to api.TopicResponse func ToTopicResponse(topic *models.Topic) *api.TopicResponse { func ToTopicResponse(topic *repo_model.Topic) *api.TopicResponse { return &api.TopicResponse{ ID: topic.ID, Name: topic.Name,
-
-
-
@@ -6,6 +6,7 @@ package uiimport ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/graceful"
-
@@ -122,7 +123,7 @@ func (ns *notificationService) NotifyNewPullRequest(pr *models.PullRequest, mentreturn } toNotify := make(map[int64]struct{}, 32) repoWatchers, err := models.GetRepoWatchersIDs(pr.Issue.RepoID) repoWatchers, err := repo_model.GetRepoWatchersIDs(db.DefaultContext, pr.Issue.RepoID) if err != nil { log.Error("GetRepoWatchersIDs: %v", err) return
-
-
modules/repofiles/commit_status.go (deleted)
-
@@ -1,43 +0,0 @@// Copyright 2019 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 repofiles import ( "fmt" "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" ) // CreateCommitStatus creates a new CommitStatus given a bunch of parameters // NOTE: All text-values will be trimmed from whitespaces. // Requires: Repo, Creator, SHA func CreateCommitStatus(repo *repo_model.Repository, creator *user_model.User, sha string, status *models.CommitStatus) error { repoPath := repo.RepoPath() // confirm that commit is exist gitRepo, err := git.OpenRepository(repoPath) if err != nil { return fmt.Errorf("OpenRepository[%s]: %v", repoPath, err) } if _, err := gitRepo.GetCommit(sha); err != nil { gitRepo.Close() return fmt.Errorf("GetCommit[%s]: %v", sha, err) } gitRepo.Close() if err := models.NewCommitStatus(models.NewCommitStatusOptions{ Repo: repo, Creator: creator, SHA: sha, CommitStatus: status, }); err != nil { return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %v", repo.ID, creator.ID, sha, err) } return nil }
-
-
-
@@ -22,7 +22,7 @@ import (// CreateRepository creates a repository for the user/organization. func CreateRepository(doer, u *user_model.User, opts models.CreateRepoOptions) (*repo_model.Repository, error) { if !doer.IsAdmin && !u.CanCreateRepo() { return nil, models.ErrReachLimitOfRepo{ return nil, repo_model.ErrReachLimitOfRepo{ Limit: u.MaxRepoCreation, } }
-
@@ -83,7 +83,7 @@ func CreateRepository(doer, u *user_model.User, opts models.CreateRepoOptions) (// Previously Gitea would just delete and start afresh - this was naughty. // So we will now fail and delegate to other functionality to adopt or delete log.Error("Files already exist in %s and we are not going to adopt or delete.", repoPath) return models.ErrRepoFilesAlreadyExist{ return repo_model.ErrRepoFilesAlreadyExist{ Uname: u.Name, Name: repo.Name, }
-
-
-
@@ -267,7 +267,7 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templreturn nil, err } if isExist { return nil, models.ErrRepoFilesAlreadyExist{ return nil, repo_model.ErrRepoFilesAlreadyExist{ Uname: generateRepo.OwnerName, Name: generateRepo.Name, }
-
-
-
@@ -184,7 +184,7 @@ func checkInitRepository(owner, name string) (err error) {return err } if isExist { return models.ErrRepoFilesAlreadyExist{ return repo_model.ErrRepoFilesAlreadyExist{ Uname: owner, Name: name, }
-
-
-
@@ -161,10 +161,10 @@ func repoAssignment() func(ctx *context.APIContext) {repo, err := repo_model.GetRepositoryByName(owner.ID, repoName) if err != nil { if repo_model.IsErrRepoNotExist(err) { redirectRepoID, err := models.LookupRepoRedirect(owner.ID, repoName) redirectRepoID, err := repo_model.LookupRedirect(owner.ID, repoName) if err == nil { context.RedirectToRepo(ctx.Context, redirectRepoID) } else if models.IsErrRepoRedirectNotExist(err) { } else if repo_model.IsErrRedirectNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "LookupRepoRedirect", err)
-
-
-
@@ -11,6 +11,7 @@ import ("code.gitea.io/gitea/models" "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert"
-
@@ -50,7 +51,7 @@ func ListForks(ctx *context.APIContext) {// "200": // "$ref": "#/responses/RepositoryList" forks, err := models.GetForks(ctx.Repo.Repository, utils.GetListOptions(ctx)) forks, err := repo_model.GetForks(ctx.Repo.Repository, utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetForks", err) return
-
@@ -125,7 +126,7 @@ func CreateFork(ctx *context.APIContext) {forker = org.AsUser() } fork, err := repo_service.ForkRepository(ctx.User, forker, models.ForkRepoOptions{ fork, err := repo_service.ForkRepository(ctx.User, forker, repo_service.ForkRepoOptions{ BaseRepo: repo, Name: repo.Name, Description: repo.Description,
-
-
-
@@ -214,15 +214,15 @@ func Migrate(ctx *context.APIContext) {func handleMigrateError(ctx *context.APIContext, repoOwner *user_model.User, remoteAddr string, err error) { switch { case models.IsErrRepoAlreadyExist(err): case repo_model.IsErrRepoAlreadyExist(err): ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.") case models.IsErrRepoFilesAlreadyExist(err): case repo_model.IsErrRepoFilesAlreadyExist(err): ctx.Error(http.StatusConflict, "", "Files already exist for this repository. Adopt them or delete them.") case migrations.IsRateLimitError(err): ctx.Error(http.StatusUnprocessableEntity, "", "Remote visit addressed rate limitation.") case migrations.IsTwoFactorAuthError(err): ctx.Error(http.StatusUnprocessableEntity, "", "Remote visit required two factors authentication.") case models.IsErrReachLimitOfRepo(err): case repo_model.IsErrReachLimitOfRepo(err): ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("You have already reached your limit of %d repositories.", repoOwner.MaxCreationLimit())) case db.IsErrNameReserved(err): ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("The username '%s' is reserved.", err.(db.ErrNameReserved).Name))
-
-
-
@@ -956,7 +956,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)} // Check if current user has fork of repository or in the same repository. headRepo := models.GetForkedRepo(headUser.ID, baseRepo.ID) headRepo := repo_model.GetForkedRepo(headUser.ID, baseRepo.ID) if headRepo == nil && !isSameRepo { log.Trace("parseCompareInfo[%d]: does not have fork or in same repository", baseRepo.ID) ctx.NotFound("GetForkedRepo")
-
-
-
@@ -261,7 +261,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.CreIsTemplate: opt.Template, }) if err != nil { if models.IsErrRepoAlreadyExist(err) { if repo_model.IsErrRepoAlreadyExist(err) { ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.") } else if db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) {
-
@@ -410,7 +410,7 @@ func Generate(ctx *context.APIContext) {repo, err := repo_service.GenerateRepository(ctx.User, ctxUser, ctx.Repo.Repository, opts) if err != nil { if models.IsErrRepoAlreadyExist(err) { if repo_model.IsErrRepoAlreadyExist(err) { ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.") } else if db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) {
-
@@ -650,7 +650,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) errif repo.LowerName != strings.ToLower(newRepoName) { if err := repo_service.ChangeRepositoryName(ctx.User, repo, newRepoName); err != nil { switch { case models.IsErrRepoAlreadyExist(err): case repo_model.IsErrRepoAlreadyExist(err): ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is already taken [name: %s]", newRepoName), err) case db.IsErrNameReserved(err): ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is reserved [name: %s]", newRepoName), err)
-
@@ -911,7 +911,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {} } if err := models.UpdateRepositoryUnits(repo, units, deleteUnitTypes); err != nil { if err := repo_model.UpdateRepositoryUnits(repo, units, deleteUnitTypes); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateRepositoryUnits", err) return err }
-
@@ -931,14 +931,14 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) ereturn err } if *opts.Archived { if err := models.SetArchiveRepoState(repo, *opts.Archived); err != nil { if err := repo_model.SetArchiveRepoState(repo, *opts.Archived); err != nil { log.Error("Tried to archive a repo: %s", err) ctx.Error(http.StatusInternalServerError, "ArchiveRepoState", err) return err } log.Trace("Repository was archived: %s/%s", ctx.Repo.Owner.Name, repo.Name) } else { if err := models.SetArchiveRepoState(repo, *opts.Archived); err != nil { if err := repo_model.SetArchiveRepoState(repo, *opts.Archived); err != nil { log.Error("Tried to un-archive a repo: %s", err) ctx.Error(http.StatusInternalServerError, "ArchiveRepoState", err) return err
-
-
-
@@ -7,7 +7,7 @@ package repoimport ( "net/http" "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs"
-
@@ -44,7 +44,7 @@ func ListStargazers(ctx *context.APIContext) {// "200": // "$ref": "#/responses/UserList" stargazers, err := models.GetStargazers(ctx.Repo.Repository, utils.GetListOptions(ctx)) stargazers, err := repo_model.GetStargazers(ctx.Repo.Repository, utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetStargazers", err) return
-
-
-
@@ -7,7 +7,7 @@ package repoimport ( "net/http" "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs"
-
@@ -44,9 +44,9 @@ func ListSubscribers(ctx *context.APIContext) {// "200": // "$ref": "#/responses/UserList" subscribers, err := models.GetRepoWatchers(ctx.Repo.Repository.ID, utils.GetListOptions(ctx)) subscribers, err := repo_model.GetRepoWatchers(ctx.Repo.Repository.ID, utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetWatchers", err) ctx.Error(http.StatusInternalServerError, "GetRepoWatchers", err) return } users := make([]*api.User, len(subscribers))
-
-
-
@@ -8,7 +8,7 @@ import ("net/http" "strings" "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log"
-
@@ -47,12 +47,12 @@ func ListTopics(ctx *context.APIContext) {// "200": // "$ref": "#/responses/TopicNames" opts := &models.FindTopicOptions{ opts := &repo_model.FindTopicOptions{ ListOptions: utils.GetListOptions(ctx), RepoID: ctx.Repo.Repository.ID, } topics, total, err := models.FindTopics(opts) topics, total, err := repo_model.FindTopics(opts) if err != nil { ctx.InternalServerError(err) return
-
@@ -99,7 +99,7 @@ func UpdateTopics(ctx *context.APIContext) {form := web.GetForm(ctx).(*api.RepoTopicOptions) topicNames := form.Topics validTopics, invalidTopics := models.SanitizeAndValidateTopics(topicNames) validTopics, invalidTopics := repo_model.SanitizeAndValidateTopics(topicNames) if len(validTopics) > 25 { ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{
-
@@ -117,7 +117,7 @@ func UpdateTopics(ctx *context.APIContext) {return } err := models.SaveTopics(ctx.Repo.Repository.ID, validTopics...) err := repo_model.SaveTopics(ctx.Repo.Repository.ID, validTopics...) if err != nil { log.Error("SaveTopics failed: %v", err) ctx.InternalServerError(err)
-
@@ -158,7 +158,7 @@ func AddTopic(ctx *context.APIContext) {topicName := strings.TrimSpace(strings.ToLower(ctx.Params(":topic"))) if !models.ValidateTopic(topicName) { if !repo_model.ValidateTopic(topicName) { ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ "invalidTopics": topicName, "message": "Topic name is invalid",
-
@@ -167,7 +167,7 @@ func AddTopic(ctx *context.APIContext) {} // Prevent adding more topics than allowed to repo count, err := models.CountTopics(&models.FindTopicOptions{ count, err := repo_model.CountTopics(&repo_model.FindTopicOptions{ RepoID: ctx.Repo.Repository.ID, }) if err != nil {
-
@@ -182,7 +182,7 @@ func AddTopic(ctx *context.APIContext) {return } _, err = models.AddTopic(ctx.Repo.Repository.ID, topicName) _, err = repo_model.AddTopic(ctx.Repo.Repository.ID, topicName) if err != nil { log.Error("AddTopic failed: %v", err) ctx.InternalServerError(err)
-
@@ -223,7 +223,7 @@ func DeleteTopic(ctx *context.APIContext) {topicName := strings.TrimSpace(strings.ToLower(ctx.Params(":topic"))) if !models.ValidateTopic(topicName) { if !repo_model.ValidateTopic(topicName) { ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ "invalidTopics": topicName, "message": "Topic name is invalid",
-
@@ -231,7 +231,7 @@ func DeleteTopic(ctx *context.APIContext) {return } topic, err := models.DeleteTopic(ctx.Repo.Repository.ID, topicName) topic, err := repo_model.DeleteTopic(ctx.Repo.Repository.ID, topicName) if err != nil { log.Error("DeleteTopic failed: %v", err) ctx.InternalServerError(err)
-
@@ -272,12 +272,12 @@ func TopicSearch(ctx *context.APIContext) {// "403": // "$ref": "#/responses/forbidden" opts := &models.FindTopicOptions{ opts := &repo_model.FindTopicOptions{ Keyword: ctx.FormString("q"), ListOptions: utils.GetListOptions(ctx), } topics, total, err := models.FindTopics(opts) topics, total, err := repo_model.FindTopics(opts) if err != nil { ctx.InternalServerError(err) return
-
-
-
@@ -104,7 +104,7 @@ func Transfer(ctx *context.APIContext) {return } if models.IsErrRepoAlreadyExist(err) { if repo_model.IsErrRepoAlreadyExist(err) { ctx.Error(http.StatusUnprocessableEntity, "CreatePendingRepositoryTransfer", err) return }
-
-
-
@@ -10,6 +10,7 @@ import ("code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert"
-
@@ -121,7 +122,7 @@ func IsStarring(ctx *context.APIContext) {// "404": // "$ref": "#/responses/notFound" if models.IsStaring(ctx.User.ID, ctx.Repo.Repository.ID) { if repo_model.IsStaring(ctx.User.ID, ctx.Repo.Repository.ID) { ctx.Status(http.StatusNoContent) } else { ctx.NotFound()
-
@@ -148,7 +149,7 @@ func Star(ctx *context.APIContext) {// "204": // "$ref": "#/responses/empty" err := models.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, true) err := repo_model.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, true) if err != nil { ctx.Error(http.StatusInternalServerError, "StarRepo", err) return
-
@@ -176,7 +177,7 @@ func Unstar(ctx *context.APIContext) {// "204": // "$ref": "#/responses/empty" err := models.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) err := repo_model.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) if err != nil { ctx.Error(http.StatusInternalServerError, "StarRepo", err) return
-
-
-
@@ -123,7 +123,7 @@ func IsWatching(ctx *context.APIContext) {// "404": // description: User is not watching this repo or repo do not exist if models.IsWatching(ctx.User.ID, ctx.Repo.Repository.ID) { if repo_model.IsWatching(ctx.User.ID, ctx.Repo.Repository.ID) { ctx.JSON(http.StatusOK, api.WatchInfo{ Subscribed: true, Ignored: false,
-
@@ -157,7 +157,7 @@ func Watch(ctx *context.APIContext) {// "200": // "$ref": "#/responses/WatchInfo" err := models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true) err := repo_model.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true) if err != nil { ctx.Error(http.StatusInternalServerError, "WatchRepo", err) return
-
@@ -193,7 +193,7 @@ func Unwatch(ctx *context.APIContext) {// "204": // "$ref": "#/responses/empty" err := models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) err := repo_model.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) if err != nil { ctx.Error(http.StatusInternalServerError, "UnwatchRepo", err) return
-
-
-
@@ -105,7 +105,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {repo.IsPrivate = opts.GitPushOptions.Bool(private.GitPushOptionRepoPrivate, repo.IsPrivate) repo.IsTemplate = opts.GitPushOptions.Bool(private.GitPushOptionRepoTemplate, repo.IsTemplate) if err := models.UpdateRepositoryCols(repo, "is_private", "is_template"); err != nil { if err := repo_model.UpdateRepositoryCols(repo, "is_private", "is_template"); err != nil { log.Error("Failed to Update: %s/%s Error: %v", ownerName, repoName, err) ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{ Err: fmt.Sprintf("Failed to Update: %s/%s Error: %v", ownerName, repoName, err),
-
-
-
@@ -12,6 +12,7 @@ import ("code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/base"
-
@@ -125,7 +126,7 @@ func SettingsPost(ctx *context.Context) {} } } else if nameChanged { if err := models.UpdateRepositoryOwnerNames(org.ID, org.Name); err != nil { if err := repo_model.UpdateRepositoryOwnerNames(org.ID, org.Name); err != nil { ctx.ServerError("UpdateRepository", err) return }
-
-
-
@@ -56,7 +56,7 @@ func Branches(ctx *context.Context) {ctx.Data["IsWriter"] = ctx.Repo.CanWrite(unit.TypeCode) ctx.Data["IsMirror"] = ctx.Repo.Repository.IsMirror ctx.Data["CanPull"] = ctx.Repo.CanWrite(unit.TypeCode) || (ctx.IsSigned && models.HasForkedRepo(ctx.User.ID, ctx.Repo.Repository.ID)) (ctx.IsSigned && repo_model.HasForkedRepo(ctx.User.ID, ctx.Repo.Repository.ID)) ctx.Data["PageIsViewCode"] = true ctx.Data["PageIsBranches"] = true
-
-
-
@@ -340,7 +340,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {// "OwnForkRepo" var ownForkRepo *repo_model.Repository if ctx.User != nil && baseRepo.OwnerID != ctx.User.ID { repo := models.GetForkedRepo(ctx.User.ID, baseRepo.ID) repo := repo_model.GetForkedRepo(ctx.User.ID, baseRepo.ID) if repo != nil { ownForkRepo = repo ctx.Data["OwnForkRepo"] = ownForkRepo
-
@@ -364,13 +364,13 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {// 5. If the headOwner has a fork of the baseRepo - use that if !has { ci.HeadRepo = models.GetForkedRepo(ci.HeadUser.ID, baseRepo.ID) ci.HeadRepo = repo_model.GetForkedRepo(ci.HeadUser.ID, baseRepo.ID) has = ci.HeadRepo != nil } // 6. If the baseRepo is a fork and the headUser has a fork of that use that if !has && baseRepo.IsFork { ci.HeadRepo = models.GetForkedRepo(ci.HeadUser.ID, baseRepo.ForkID) ci.HeadRepo = repo_model.GetForkedRepo(ci.HeadUser.ID, baseRepo.ForkID) has = ci.HeadRepo != nil }
-
-
-
@@ -134,7 +134,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {repo, err := repo_model.GetRepositoryByName(owner.ID, reponame) if err != nil { if repo_model.IsErrRepoNotExist(err) { if redirectRepoID, err := models.LookupRepoRedirect(owner.ID, reponame); err == nil { if redirectRepoID, err := repo_model.LookupRedirect(owner.ID, reponame); err == nil { context.RedirectToRepo(ctx, redirectRepoID) return }
-
-
-
@@ -108,7 +108,7 @@ func MustAllowPulls(ctx *context.Context) {} // User can send pull request if owns a forked repository. if ctx.IsSigned && models.HasForkedRepo(ctx.User.ID, ctx.Repo.Repository.ID) { if ctx.IsSigned && repo_model.HasForkedRepo(ctx.User.ID, ctx.Repo.Repository.ID) { ctx.Repo.PullRequest.Allowed = true ctx.Repo.PullRequest.HeadInfoSubURL = url.PathEscape(ctx.User.Name) + ":" + util.PathEscapeSegments(ctx.Repo.BranchName) }
-
-
-
@@ -12,6 +12,7 @@ import ("code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context"
-
@@ -79,12 +80,12 @@ func handleMigrateError(ctx *context.Context, owner *user_model.User, err error,ctx.RenderWithErr(ctx.Tr("form.visit_rate_limit"), tpl, form) case migrations.IsTwoFactorAuthError(err): ctx.RenderWithErr(ctx.Tr("form.2fa_auth_required"), tpl, form) case models.IsErrReachLimitOfRepo(err): case repo_model.IsErrReachLimitOfRepo(err): ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", owner.MaxCreationLimit()), tpl, form) case models.IsErrRepoAlreadyExist(err): case repo_model.IsErrRepoAlreadyExist(err): ctx.Data["Err_RepoName"] = true ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), tpl, form) case models.IsErrRepoFilesAlreadyExist(err): case repo_model.IsErrRepoFilesAlreadyExist(err): ctx.Data["Err_RepoName"] = true switch { case ctx.IsUserSiteAdmin() || (setting.Repository.AllowAdoptionOfUnadoptedRepositories && setting.Repository.AllowDeleteOfUnadoptedRepositories):
-
@@ -230,7 +231,7 @@ func MigratePost(ctx *context.Context) {opts.Releases = false } err = models.CheckCreateRepository(ctx.User, ctxUser, opts.RepoName, false) err = repo_model.CheckCreateRepository(ctx.User, ctxUser, opts.RepoName, false) if err != nil { handleMigrateError(ctx, ctxUser, err, "MigratePost", tpl, form) return
-
-
-
@@ -110,7 +110,7 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {ctx.Data["repo_name"] = forkRepo.Name ctx.Data["description"] = forkRepo.Description ctx.Data["IsPrivate"] = forkRepo.IsPrivate || forkRepo.Owner.Visibility == structs.VisibleTypePrivate canForkToUser := forkRepo.OwnerID != ctx.User.ID && !models.HasForkedRepo(ctx.User.ID, forkRepo.ID) canForkToUser := forkRepo.OwnerID != ctx.User.ID && !repo_model.HasForkedRepo(ctx.User.ID, forkRepo.ID) ctx.Data["ForkRepo"] = forkRepo
-
@@ -121,7 +121,7 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {} var orgs []*models.Organization for _, org := range ownedOrgs { if forkRepo.OwnerID != org.ID && !models.HasForkedRepo(org.ID, forkRepo.ID) { if forkRepo.OwnerID != org.ID && !repo_model.HasForkedRepo(org.ID, forkRepo.ID) { orgs = append(orgs, org) } }
-
@@ -202,7 +202,7 @@ func ForkPost(ctx *context.Context) {ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplFork, &form) return } repo := models.GetForkedRepo(ctxUser.ID, traverseParentRepo.ID) repo := repo_model.GetForkedRepo(ctxUser.ID, traverseParentRepo.ID) if repo != nil { ctx.Redirect(ctxUser.HomeLink() + "/" + url.PathEscape(repo.Name)) return
-
@@ -229,7 +229,7 @@ func ForkPost(ctx *context.Context) {} } repo, err := repo_service.ForkRepository(ctx.User, ctxUser, models.ForkRepoOptions{ repo, err := repo_service.ForkRepository(ctx.User, ctxUser, repo_service.ForkRepoOptions{ BaseRepo: forkRepo, Name: form.RepoName, Description: form.Description,
-
@@ -237,7 +237,7 @@ func ForkPost(ctx *context.Context) {if err != nil { ctx.Data["Err_RepoName"] = true switch { case models.IsErrRepoAlreadyExist(err): case repo_model.IsErrRepoAlreadyExist(err): ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplFork, &form) case db.IsErrNameReserved(err): ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(db.ErrNameReserved).Name), tplFork, &form)
-
-
-
@@ -161,12 +161,12 @@ func Create(ctx *context.Context) {func handleCreateError(ctx *context.Context, owner *user_model.User, err error, name string, tpl base.TplName, form interface{}) { switch { case models.IsErrReachLimitOfRepo(err): case repo_model.IsErrReachLimitOfRepo(err): ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", owner.MaxCreationLimit()), tpl, form) case models.IsErrRepoAlreadyExist(err): case repo_model.IsErrRepoAlreadyExist(err): ctx.Data["Err_RepoName"] = true ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), tpl, form) case models.IsErrRepoFilesAlreadyExist(err): case repo_model.IsErrRepoFilesAlreadyExist(err): ctx.Data["Err_RepoName"] = true switch { case ctx.IsUserSiteAdmin() || (setting.Repository.AllowAdoptionOfUnadoptedRepositories && setting.Repository.AllowDeleteOfUnadoptedRepositories):
-
@@ -278,13 +278,13 @@ func Action(ctx *context.Context) {var err error switch ctx.Params(":action") { case "watch": err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true) err = repo_model.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true) case "unwatch": err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) err = repo_model.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) case "star": err = models.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, true) err = repo_model.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, true) case "unstar": err = models.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) err = repo_model.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) case "accept_transfer": err = acceptOrRejectRepoTransfer(ctx, true) case "reject_transfer":
-
-
-
@@ -103,11 +103,11 @@ func SettingsPost(ctx *context.Context) {if err := repo_service.ChangeRepositoryName(ctx.User, repo, newRepoName); err != nil { ctx.Data["Err_RepoName"] = true switch { case models.IsErrRepoAlreadyExist(err): case repo_model.IsErrRepoAlreadyExist(err): ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), tplSettingsOptions, &form) case db.IsErrNameReserved(err): ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(db.ErrNameReserved).Name), tplSettingsOptions, &form) case models.IsErrRepoFilesAlreadyExist(err): case repo_model.IsErrRepoFilesAlreadyExist(err): ctx.Data["Err_RepoName"] = true switch { case ctx.IsUserSiteAdmin() || (setting.Repository.AllowAdoptionOfUnadoptedRepositories && setting.Repository.AllowDeleteOfUnadoptedRepositories):
-
@@ -461,7 +461,7 @@ func SettingsPost(ctx *context.Context) {deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePullRequests) } if err := models.UpdateRepositoryUnits(repo, units, deleteUnitTypes); err != nil { if err := repo_model.UpdateRepositoryUnits(repo, units, deleteUnitTypes); err != nil { ctx.ServerError("UpdateRepositoryUnits", err) return }
-
@@ -612,7 +612,7 @@ func SettingsPost(ctx *context.Context) {} if err := repo_service.StartRepositoryTransfer(ctx.User, newOwner, repo, nil); err != nil { if models.IsErrRepoAlreadyExist(err) { if repo_model.IsErrRepoAlreadyExist(err) { ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil) } else if models.IsErrRepoTransferInProgress(err) { ctx.RenderWithErr(ctx.Tr("repo.settings.transfer_in_progress"), tplSettingsOptions, nil)
-
@@ -714,7 +714,7 @@ func SettingsPost(ctx *context.Context) {return } if err := models.SetArchiveRepoState(repo, true); err != nil { if err := repo_model.SetArchiveRepoState(repo, true); err != nil { log.Error("Tried to archive a repo: %s", err) ctx.Flash.Error(ctx.Tr("repo.settings.archive.error")) ctx.Redirect(ctx.Repo.RepoLink + "/settings")
-
@@ -732,7 +732,7 @@ func SettingsPost(ctx *context.Context) {return } if err := models.SetArchiveRepoState(repo, false); err != nil { if err := repo_model.SetArchiveRepoState(repo, false); err != nil { log.Error("Tried to unarchive a repo: %s", err) ctx.Flash.Error(ctx.Tr("repo.settings.unarchive.error")) ctx.Redirect(ctx.Repo.RepoLink + "/settings")
-
@@ -1145,7 +1145,7 @@ func UpdateAvatarSetting(ctx *context.Context, form forms.AvatarForm) error {if !(st.IsImage() && !st.IsSvgImage()) { return errors.New(ctx.Tr("settings.uploaded_avatar_not_a_image")) } if err = models.UploadRepoAvatar(ctxRepo, data); err != nil { if err = repo_service.UploadAvatar(ctxRepo, data); err != nil { return fmt.Errorf("UploadAvatar: %v", err) } return nil
-
@@ -1165,7 +1165,7 @@ func SettingsAvatar(ctx *context.Context) {// SettingsDeleteAvatar delete repository avatar func SettingsDeleteAvatar(ctx *context.Context) { if err := models.DeleteRepoAvatar(ctx.Repo.Repository); err != nil { if err := repo_service.DeleteAvatar(ctx.Repo.Repository); err != nil { ctx.Flash.Error(fmt.Sprintf("DeleteAvatar: %v", err)) } ctx.Redirect(ctx.Repo.RepoLink + "/settings")
-
-
-
@@ -8,7 +8,7 @@ import ("net/http" "strings" "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" )
-
@@ -28,7 +28,7 @@ func TopicsPost(ctx *context.Context) {topics = strings.Split(topicsStr, ",") } validTopics, invalidTopics := models.SanitizeAndValidateTopics(topics) validTopics, invalidTopics := repo_model.SanitizeAndValidateTopics(topics) if len(validTopics) > 25 { ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{
-
@@ -46,7 +46,7 @@ func TopicsPost(ctx *context.Context) {return } err := models.SaveTopics(ctx.Repo.Repository.ID, validTopics...) err := repo_model.SaveTopics(ctx.Repo.Repository.ID, validTopics...) if err != nil { log.Error("SaveTopics failed: %v", err) ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
-
-
-
@@ -822,7 +822,7 @@ func renderLanguageStats(ctx *context.Context) {} func renderRepoTopics(ctx *context.Context) { topics, _, err := models.FindTopics(&models.FindTopicOptions{ topics, _, err := repo_model.FindTopics(&repo_model.FindTopicOptions{ RepoID: ctx.Repo.Repository.ID, }) if err != nil {
-
@@ -931,7 +931,7 @@ func Watchers(ctx *context.Context) {ctx.Data["PageIsWatchers"] = true RenderUserCards(ctx, ctx.Repo.Repository.NumWatches, func(opts db.ListOptions) ([]*user_model.User, error) { return models.GetRepoWatchers(ctx.Repo.Repository.ID, opts) return repo_model.GetRepoWatchers(ctx.Repo.Repository.ID, opts) }, tplWatchers) }
-
@@ -941,7 +941,7 @@ func Stars(ctx *context.Context) {ctx.Data["CardsTitle"] = ctx.Tr("repo.stargazers") ctx.Data["PageIsStargazers"] = true RenderUserCards(ctx, ctx.Repo.Repository.NumStars, func(opts db.ListOptions) ([]*user_model.User, error) { return models.GetStargazers(ctx.Repo.Repository, opts) return repo_model.GetStargazers(ctx.Repo.Repository, opts) }, tplWatchers) }
-
@@ -957,7 +957,7 @@ func Forks(ctx *context.Context) {pager := context.NewPagination(ctx.Repo.Repository.NumForks, models.ItemsPerPage, page, 5) ctx.Data["Page"] = pager forks, err := models.GetForks(ctx.Repo.Repository, db.ListOptions{ forks, err := repo_model.GetForks(ctx.Repo.Repository, db.ListOptions{ Page: pager.Paginater.Current(), PageSize: models.ItemsPerPage, })
-
-
-
@@ -77,7 +77,7 @@ func HandleUsernameChange(ctx *context.Context, user *user_model.User, newName sreturn err } } else { if err := models.UpdateRepositoryOwnerNames(user.ID, newName); err != nil { if err := repo_model.UpdateRepositoryOwnerNames(user.ID, newName); err != nil { ctx.ServerError("UpdateRepository", err) return err }
-
@@ -290,7 +290,7 @@ func Repos(ctx *context.Context) {return filepath.SkipDir } name = name[:len(name)-4] if models.IsUsableRepoName(name) != nil || strings.ToLower(name) != name { if repo_model.IsUsableRepoName(name) != nil || strings.ToLower(name) != name { return filepath.SkipDir } if count >= start && count < end {
-
-
-
@@ -118,7 +118,7 @@ func registerRemoveRandomAvatars() {RunAtStart: false, Schedule: "@every 72h", }, func(ctx context.Context, _ *user_model.User, _ Config) error { return models.RemoveRandomAvatars(ctx) return repo_service.RemoveRandomAvatars(ctx) }) }
-
-
-
@@ -8,6 +8,8 @@ import ("fmt" "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log"
-
@@ -78,7 +80,7 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo// =========== Repo watchers =========== // Make repo watchers last, since it's likely the list with the most users if !(ctx.Issue.IsPull && ctx.Issue.PullRequest.IsWorkInProgress() && ctx.ActionType != models.ActionCreatePullRequest) { ids, err = models.GetRepoWatchersIDs(ctx.Issue.RepoID) ids, err = repo_model.GetRepoWatchersIDs(db.DefaultContext, ctx.Issue.RepoID) if err != nil { return fmt.Errorf("GetRepoWatchersIDs(%d): %v", ctx.Issue.RepoID, err) }
-
-
-
@@ -8,6 +8,8 @@ import ("bytes" "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log"
-
@@ -29,7 +31,7 @@ func MailNewRelease(rel *models.Release) {return } watcherIDList, err := models.GetRepoWatchersIDs(rel.RepoID) watcherIDList, err := repo_model.GetRepoWatchersIDs(db.DefaultContext, rel.RepoID) if err != nil { log.Error("GetRepoWatchersIDs(%d): %v", rel.RepoID, err) return
-
-
-
@@ -154,7 +154,7 @@ func (g *GiteaLocalUploader) CreateTopics(topics ...string) error {} } topics = topics[:c] return models.SaveTopics(g.repo.ID, topics...) return repo_model.SaveTopics(g.repo.ID, topics...) } // CreateMilestones creates milestones
-
@@ -980,5 +980,5 @@ func (g *GiteaLocalUploader) Finish() error {} g.repo.Status = repo_model.RepositoryReady return models.UpdateRepositoryCols(g.repo, "status") return repo_model.UpdateRepositoryCols(g.repo, "status") }
-
-
-
@@ -60,7 +60,7 @@ func UpdateAddress(m *repo_model.Mirror, addr string) error {} m.Repo.OriginalURL = addr return models.UpdateRepositoryCols(m.Repo, "original_url") return repo_model.UpdateRepositoryCols(m.Repo, "original_url") } // mirrorSyncResult contains information of a updated reference.
-
@@ -476,7 +476,7 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool {return false } if err = models.UpdateRepositoryUpdatedTime(m.RepoID, commitDate); err != nil { if err = repo_model.UpdateRepositoryUpdatedTime(m.RepoID, commitDate); err != nil { log.Error("Update repository 'updated_unix' [%d]: %v", m.RepoID, err) return false }
-
@@ -539,7 +539,7 @@ func checkAndUpdateEmptyRepository(m *repo_model.Mirror, gitRepo *git.Repository} m.Repo.IsEmpty = false // Update the is empty and default_branch columns if err := models.UpdateRepositoryCols(m.Repo, "default_branch", "is_empty"); err != nil { if err := repo_model.UpdateRepositoryCols(m.Repo, "default_branch", "is_empty"); err != nil { log.Error("Failed to update default branch of repository %-v. Error: %v", m.Repo, err) desc := fmt.Sprintf("Failed to uupdate default branch of repository '%s': %v", m.Repo.RepoPath(), err) if err = admin_model.CreateRepositoryNotice(desc); err != nil {
-
-
-
@@ -28,7 +28,7 @@ import (// AdoptRepository adopts pre-existing repository files for the user/organization. func AdoptRepository(doer, u *user_model.User, opts models.CreateRepoOptions) (*repo_model.Repository, error) { if !doer.IsAdmin && !u.CanCreateRepo() { return nil, models.ErrReachLimitOfRepo{ return nil, repo_model.ErrReachLimitOfRepo{ Limit: u.MaxRepoCreation, } }
-
@@ -188,7 +188,7 @@ func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, r// DeleteUnadoptedRepository deletes unadopted repository files from the filesystem func DeleteUnadoptedRepository(doer, u *user_model.User, repoName string) error { if err := models.IsUsableRepoName(repoName); err != nil { if err := repo_model.IsUsableRepoName(repoName); err != nil { return err }
-
@@ -208,7 +208,7 @@ func DeleteUnadoptedRepository(doer, u *user_model.User, repoName string) errorif exist, err := repo_model.IsRepositoryExist(u, repoName); err != nil { return err } else if exist { return models.ErrRepoAlreadyExist{ return repo_model.ErrRepoAlreadyExist{ Uname: u.Name, Name: repoName, }
-
@@ -312,7 +312,7 @@ func ListUnadoptedRepositories(query string, opts *db.ListOptions) ([]string, inreturn filepath.SkipDir } name = name[:len(name)-4] if models.IsUsableRepoName(name) != nil || strings.ToLower(name) != name || !globRepo.Match(name) { if repo_model.IsUsableRepoName(name) != nil || strings.ToLower(name) != name || !globRepo.Match(name) { return filepath.SkipDir } if count < end {
-
-
-
@@ -1,8 +1,8 @@// Copyright 2020 The Gitea Authors. All rights reserved. // 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 models package repository import ( "context"
-
@@ -11,38 +11,18 @@ import ("image/png" "io" "strconv" "strings" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/avatar" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" ) // RemoveRandomAvatars removes the randomly generated avatars that were created for repositories func RemoveRandomAvatars(ctx context.Context) error { return db.GetEngine(db.DefaultContext). Where("id > 0").BufferSize(setting.Database.IterateBufferSize). Iterate(new(repo_model.Repository), func(idx int, bean interface{}) error { repository := bean.(*repo_model.Repository) select { case <-ctx.Done(): return db.ErrCancelledf("before random avatars removed for %s", repository.FullName()) default: } stringifiedID := strconv.FormatInt(repository.ID, 10) if repository.Avatar == stringifiedID { return DeleteRepoAvatar(repository) } return nil }) } // UploadRepoAvatar saves custom avatar for repository. // UploadAvatar saves custom avatar for repository. // FIXME: split uploads to different subdirs in case we have massive number of repos. func UploadRepoAvatar(repo *repo_model.Repository, data []byte) error { func UploadAvatar(repo *repo_model.Repository, data []byte) error { m, err := avatar.Prepare(data) if err != nil { return err
-
@@ -64,7 +44,7 @@ func UploadRepoAvatar(repo *repo_model.Repository, data []byte) error {// Users can upload the same image to other repo - prefix it with ID // Then repo will be removed - only it avatar file will be removed repo.Avatar = newAvatar if _, err := db.GetEngine(ctx).ID(repo.ID).Cols("avatar").Update(repo); err != nil { if err := repo_model.UpdateRepositoryColsCtx(ctx, repo, "avatar"); err != nil { return fmt.Errorf("UploadAvatar: Update repository avatar: %v", err) }
-
@@ -86,8 +66,8 @@ func UploadRepoAvatar(repo *repo_model.Repository, data []byte) error {return committer.Commit() } // DeleteRepoAvatar deletes the repos's custom avatar. func DeleteRepoAvatar(repo *repo_model.Repository) error { // DeleteAvatar deletes the repos's custom avatar. func DeleteAvatar(repo *repo_model.Repository) error { // Avatar not exists if len(repo.Avatar) == 0 { return nil
-
@@ -103,7 +83,7 @@ func DeleteRepoAvatar(repo *repo_model.Repository) error {defer committer.Close() repo.Avatar = "" if _, err := db.GetEngine(ctx).ID(repo.ID).Cols("avatar").Update(repo); err != nil { if err := repo_model.UpdateRepositoryColsCtx(ctx, repo, "avatar"); err != nil { return fmt.Errorf("DeleteAvatar: Update repository avatar: %v", err) }
-
@@ -113,3 +93,29 @@ func DeleteRepoAvatar(repo *repo_model.Repository) error {return committer.Commit() } // RemoveRandomAvatars removes the randomly generated avatars that were created for repositories func RemoveRandomAvatars(ctx context.Context) error { return repo_model.IterateRepository(func(repository *repo_model.Repository) error { select { case <-ctx.Done(): return db.ErrCancelledf("before random avatars removed for %s", repository.FullName()) default: } stringifiedID := strconv.FormatInt(repository.ID, 10) if repository.Avatar == stringifiedID { return DeleteAvatar(repository) } return nil }) } // generateAvatar generates the avatar from a template repository func generateAvatar(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error { generateRepo.Avatar = strings.Replace(templateRepo.Avatar, strconv.FormatInt(templateRepo.ID, 10), strconv.FormatInt(generateRepo.ID, 10), 1) if _, err := storage.Copy(storage.RepoAvatars, generateRepo.CustomAvatarRelativePath(), storage.RepoAvatars, templateRepo.CustomAvatarRelativePath()); err != nil { return err } return repo_model.UpdateRepositoryColsCtx(ctx, generateRepo, "avatar") }
-
-
-
@@ -0,0 +1,64 @@// 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 ( "bytes" "crypto/md5" "fmt" "image" "image/png" "testing" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" ) func TestUploadAvatar(t *testing.T) { // Generate image myImage := image.NewRGBA(image.Rect(0, 0, 1, 1)) var buff bytes.Buffer png.Encode(&buff, myImage) assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) err := UploadAvatar(repo, buff.Bytes()) assert.NoError(t, err) assert.Equal(t, fmt.Sprintf("%d-%x", 10, md5.Sum(buff.Bytes())), repo.Avatar) } func TestUploadBigAvatar(t *testing.T) { // Generate BIG image myImage := image.NewRGBA(image.Rect(0, 0, 5000, 1)) var buff bytes.Buffer png.Encode(&buff, myImage) assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) err := UploadAvatar(repo, buff.Bytes()) assert.Error(t, err) } func TestDeleteAvatar(t *testing.T) { // Generate image myImage := image.NewRGBA(image.Rect(0, 0, 1, 1)) var buff bytes.Buffer png.Encode(&buff, myImage) assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) err := UploadAvatar(repo, buff.Bytes()) assert.NoError(t, err) err = DeleteAvatar(repo) assert.NoError(t, err) assert.Equal(t, "", repo.Avatar) }
-
-
-
@@ -22,9 +22,16 @@ import ("code.gitea.io/gitea/modules/util" ) // ForkRepoOptions contains the fork repository options type ForkRepoOptions struct { BaseRepo *repo_model.Repository Name string Description string } // ForkRepository forks a repository func ForkRepository(doer, owner *user_model.User, opts models.ForkRepoOptions) (_ *repo_model.Repository, err error) { forkedRepo, err := models.GetUserFork(opts.BaseRepo.ID, owner.ID) func ForkRepository(doer, owner *user_model.User, opts ForkRepoOptions) (_ *repo_model.Repository, err error) { forkedRepo, err := repo_model.GetUserFork(opts.BaseRepo.ID, owner.ID) if err != nil { return nil, err }
-
-
-
@@ -22,7 +22,7 @@ func TestForkRepository(t *testing.T) {user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 13}).(*user_model.User) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) fork, err := ForkRepository(user, user, models.ForkRepoOptions{ fork, err := ForkRepository(user, user, ForkRepoOptions{ BaseRepo: repo, Name: "test", Description: "test",
-
-
-
@@ -10,6 +10,7 @@ import ("code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository"
-
@@ -50,3 +51,36 @@ func SyncRepositoryHooks(ctx context.Context) error {log.Trace("Finished: SyncRepositoryHooks") return nil } // GenerateGitHooks generates git hooks from a template repository func GenerateGitHooks(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error { generateGitRepo, err := git.OpenRepository(generateRepo.RepoPath()) if err != nil { return err } defer generateGitRepo.Close() templateGitRepo, err := git.OpenRepository(templateRepo.RepoPath()) if err != nil { return err } defer templateGitRepo.Close() templateHooks, err := templateGitRepo.Hooks() if err != nil { return err } for _, templateHook := range templateHooks { generateHook, err := generateGitRepo.GetHook(templateHook.Name()) if err != nil { return err } generateHook.Content = templateHook.Content if err := generateHook.Update(); err != nil { return err } } return nil }
-
-
-
@@ -166,7 +166,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {} } // Update the is empty and default_branch columns if err := models.UpdateRepositoryCols(repo, "default_branch", "is_empty"); err != nil { if err := repo_model.UpdateRepositoryCols(repo, "default_branch", "is_empty"); err != nil { return fmt.Errorf("UpdateRepositoryCols: %v", err) } }
-
@@ -227,7 +227,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {} // Even if user delete a branch on a repository which he didn't watch, he will be watch that. if err = models.WatchIfAuto(opts.PusherID, repo.ID, true); err != nil { if err = repo_model.WatchIfAuto(opts.PusherID, repo.ID, true); err != nil { log.Warn("Fail to perform auto watch on user %v for repo %v: %v", opts.PusherID, repo.ID, err) } } else {
-
@@ -239,7 +239,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {} // Change repository last updated time. if err := models.UpdateRepositoryUpdatedTime(repo.ID, time.Now()); err != nil { if err := repo_model.UpdateRepositoryUpdatedTime(repo.ID, time.Now()); err != nil { return fmt.Errorf("UpdateRepositoryUpdatedTime: %v", err) }
-
-
-
@@ -19,7 +19,7 @@ import (// GenerateRepository generates a repository from a template func GenerateRepository(doer, owner *user_model.User, templateRepo *repo_model.Repository, opts models.GenerateRepoOptions) (_ *repo_model.Repository, err error) { if !doer.IsAdmin && !owner.CanCreateRepo() { return nil, models.ErrReachLimitOfRepo{ return nil, repo_model.ErrReachLimitOfRepo{ Limit: owner.MaxRepoCreation, } }
-
@@ -40,14 +40,14 @@ func GenerateRepository(doer, owner *user_model.User, templateRepo *repo_model.R// Topics if opts.Topics { if err = models.GenerateTopics(ctx, templateRepo, generateRepo); err != nil { if err = repo_model.GenerateTopics(ctx, templateRepo, generateRepo); err != nil { return err } } // Git Hooks if opts.GitHooks { if err = models.GenerateGitHooks(ctx, templateRepo, generateRepo); err != nil { if err = GenerateGitHooks(ctx, templateRepo, generateRepo); err != nil { return err } }
-
@@ -61,7 +61,7 @@ func GenerateRepository(doer, owner *user_model.User, templateRepo *repo_model.R// Avatar if opts.Avatar && len(templateRepo.Avatar) > 0 { if err = models.GenerateAvatar(ctx, templateRepo, generateRepo); err != nil { if err = generateAvatar(ctx, templateRepo, generateRepo); err != nil { return err } }
-
-
-
@@ -64,7 +64,7 @@ func ChangeRepositoryName(doer *user_model.User, repo *repo_model.Repository, ne// local copy's origin accordingly. repoWorkingPool.CheckIn(fmt.Sprint(repo.ID)) if err := models.ChangeRepositoryName(doer, repo, newRepoName); err != nil { if err := repo_model.ChangeRepositoryName(doer, repo, newRepoName); err != nil { repoWorkingPool.CheckOut(fmt.Sprint(repo.ID)) return err }
-
-
-
@@ -27,9 +27,9 @@ import (func handleCreateError(owner *user_model.User, err error) error { switch { case models.IsErrReachLimitOfRepo(err): case repo_model.IsErrReachLimitOfRepo(err): return fmt.Errorf("You have already reached your limit of %d repositories", owner.MaxCreationLimit()) case models.IsErrRepoAlreadyExist(err): case repo_model.IsErrRepoAlreadyExist(err): return errors.New("The repository name is already used") case db.IsErrNameReserved(err): return fmt.Errorf("The repository name '%s' is reserved", err.(db.ErrNameReserved).Name)
-
@@ -123,7 +123,7 @@ func runMigrateTask(t *models.Task) (err error) {return } if models.IsErrRepoAlreadyExist(err) { if repo_model.IsErrRepoAlreadyExist(err) { err = errors.New("The repository name is already used") return }
-
-
-
@@ -375,7 +375,7 @@ func DeleteWikiPage(doer *user_model.User, repo *repo_model.Repository, wikiName// DeleteWiki removes the actual and local copy of repository wiki. func DeleteWiki(repo *repo_model.Repository) error { if err := models.UpdateRepositoryUnits(repo, nil, []unit.Type{unit.TypeWiki}); err != nil { if err := repo_model.UpdateRepositoryUnits(repo, nil, []unit.Type{unit.TypeWiki}); err != nil { return err }
-