Browse Source

models: fix issue with transfer repository

README: fix typo
Unknwon 10 years ago
parent
commit
8896c82d34
8 changed files with 80 additions and 72 deletions
  1. 3 3
      README.md
  2. 3 3
      README_ZH.md
  3. 1 1
      gogs.go
  4. 7 3
      models/access.go
  5. 19 9
      models/org.go
  6. 44 46
      models/repo.go
  7. 2 6
      routers/repo/setting.go
  8. 1 1
      templates/.VERSION

+ 3 - 3
README.md

@@ -7,13 +7,13 @@ Gogs (Go Git Service) is a painless self-hosted Git service written in Go.
 
 ![Demo](http://gogs.qiniudn.com/gogs_demo.gif)
 
-##### Current version: 0.5.13 Beta
+##### Current version: 0.5.15 Beta
 
 ### NOTICES
 
 - Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) has been reset in **Jan 28, 2015** and will reset multiple times after. Please do **NOT** put your important data on the site.
 - The demo site [try.gogs.io](https://try.gogs.io) is running under `dev` branch.
-- You **MUST** read [CONTRIBUTING.md](CONTRIBUTING.md) before you start filing a issue or making a Pull Request.
+- You **MUST** read [CONTRIBUTING.md](CONTRIBUTING.md) before you start filing an issue or making a Pull Request.
 - If you think there are vulnerabilities in the project, please talk privately to **[email protected]**.  Thanks!
 
 #### Other language version
@@ -57,7 +57,7 @@ The goal of this project is to make the easiest, fastest, and most painless way
 ## System Requirements
 
 - A cheap Raspberry Pi is powerful enough for basic functionality.
-- At least 4 CPU cores and 1GB RAM would be the baseline for teamwork.
+- At least 2 CPU cores and 1GB RAM would be the baseline for teamwork.
 
 ## Installation
 

+ 3 - 3
README_ZH.md

@@ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个基于 Go 语言的自助 Git 服务。
 
 ![Demo](http://gogs.qiniudn.com/gogs_demo.gif)
 
-##### 当前版本:0.5.13 Beta
+##### 当前版本:0.5.15 Beta
 
 ## 开发目的
 
@@ -44,7 +44,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
 ## 系统要求
 
 - 最低的系统硬件要求为一个廉价的树莓派
-- 如果用于团队项目,建议使用 4 核 CPU 及 1GB 内存
+- 如果用于团队项目,建议使用 2 核 CPU 及 1GB 内存
 
 ## 安装部署
 
@@ -75,4 +75,4 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
 
 ## 授权许可
 
-本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) 文件中。
+本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) 文件中。

+ 1 - 1
gogs.go

@@ -17,7 +17,7 @@ import (
 	"github.com/gogits/gogs/modules/setting"
 )
 
-const APP_VER = "0.5.15.0223 Beta"
+const APP_VER = "0.5.15.0224 Beta"
 
 func init() {
 	runtime.GOMAXPROCS(runtime.NumCPU())

+ 7 - 3
models/access.go

@@ -4,6 +4,10 @@
 
 package models
 
+import (
+	"fmt"
+)
+
 type AccessMode int
 
 const (
@@ -128,7 +132,7 @@ func (repo *Repository) recalculateAccesses(e Engine) error {
 			}
 
 			if err = team.getMembers(e); err != nil {
-				return err
+				return fmt.Errorf("getMembers '%d': %v", team.ID, err)
 			}
 			for _, u := range team.Members {
 				accessMap[u.Id] = maxAccessMode(accessMap[u.Id], team.Authorize)
@@ -157,9 +161,9 @@ func (repo *Repository) recalculateAccesses(e Engine) error {
 
 	// Delete old accesses and insert new ones for repository.
 	if _, err = e.Delete(&Access{RepoID: repo.Id}); err != nil {
-		return err
+		return fmt.Errorf("delete old accesses: %v", err)
 	} else if _, err = e.Insert(newAccesses); err != nil {
-		return err
+		return fmt.Errorf("insert new accesses: %v", err)
 	}
 
 	return nil

+ 19 - 9
models/org.go

@@ -28,7 +28,7 @@ func (org *User) IsOwnedBy(uid int64) bool {
 
 // IsOrgMember returns true if given user is member of organization.
 func (org *User) IsOrgMember(uid int64) bool {
-	return IsOrganizationMember(org.Id, uid)
+	return org.IsOrganization() && IsOrganizationMember(org.Id, uid)
 }
 
 func (org *User) getTeam(e Engine, name string) (*Team, error) {
@@ -493,19 +493,19 @@ func (t *Team) addRepository(e Engine, repo *Repository) (err error) {
 
 	t.NumRepos++
 	if _, err = e.Id(t.ID).AllCols().Update(t); err != nil {
-		return err
+		return fmt.Errorf("update team: %v", err)
 	}
 
 	if err = repo.recalculateAccesses(e); err != nil {
-		return err
+		return fmt.Errorf("recalculateAccesses: %v", err)
 	}
 
 	if err = t.getMembers(e); err != nil {
-		return fmt.Errorf("get team members: %v", err)
+		return fmt.Errorf("getMembers: %v", err)
 	}
 	for _, u := range t.Members {
 		if err = watchRepo(e, u.Id, repo.Id, true); err != nil {
-			return err
+			return fmt.Errorf("watchRepo: %v", err)
 		}
 	}
 	return nil
@@ -772,10 +772,20 @@ func IsTeamMember(orgID, teamID, uid int64) bool {
 	return isTeamMember(x, orgID, teamID, uid)
 }
 
-func getTeamMembers(e Engine, teamID int64) ([]*User, error) {
-	us := make([]*User, 0, 10)
-	err := e.Sql("SELECT * FROM `user` JOIN `team_user` ON `team_user`.`team_id` = ? AND `team_user`.`uid` = `user`.`id`", teamID).Find(&us)
-	return us, err
+func getTeamMembers(e Engine, teamID int64) (_ []*User, err error) {
+	teamUsers := make([]*TeamUser, 0, 10)
+	if err = e.Where("team_id=?", teamID).Find(&teamUsers); err != nil {
+		return nil, fmt.Errorf("get team-users: %v", err)
+	}
+	members := make([]*User, 0, len(teamUsers))
+	for i := range teamUsers {
+		member := new(User)
+		if _, err = e.Id(teamUsers[i].Uid).Get(member); err != nil {
+			return nil, fmt.Errorf("get user '%d': %v", teamUsers[i].Uid, err)
+		}
+		members = append(members, member)
+	}
+	return members, nil
 }
 
 // GetTeamMembers returns all members in given team of organization.

+ 44 - 46
models/repo.go

@@ -223,16 +223,12 @@ func (repo *Repository) DescriptionHtml() template.HTML {
 }
 
 // IsRepositoryExist returns true if the repository with given name under user has already existed.
-func IsRepositoryExist(u *User, repoName string) (bool, error) {
-	repo := Repository{OwnerId: u.Id}
-	has, err := x.Where("lower_name = ?", strings.ToLower(repoName)).Get(&repo)
-	if err != nil {
-		return has, err
-	} else if !has {
-		return false, nil
-	}
-
-	return com.IsDir(RepoPath(u.Name, repoName)), nil
+func IsRepositoryExist(u *User, repoName string) bool {
+	has, _ := x.Get(&Repository{
+		OwnerId:   u.Id,
+		LowerName: strings.ToLower(repoName),
+	})
+	return has && com.IsDir(RepoPath(u.Name, repoName))
 }
 
 // CloneLink represents different types of clone URLs of repository.
@@ -514,15 +510,12 @@ func initRepository(e Engine, f string, u *User, repo *Repository, initReadme bo
 }
 
 // CreateRepository creates a repository for given user or organization.
-func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMirror, initReadme bool) (*Repository, error) {
+func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMirror, initReadme bool) (_ *Repository, err error) {
 	if !IsLegalName(name) {
 		return nil, ErrRepoNameIllegal
 	}
 
-	isExist, err := IsRepositoryExist(u, name)
-	if err != nil {
-		return nil, err
-	} else if isExist {
+	if IsRepositoryExist(u, name) {
 		return nil, ErrRepoAlreadyExist
 	}
 
@@ -631,71 +624,79 @@ func RepoPath(userName, repoName string) string {
 func TransferOwnership(u *User, newOwnerName string, repo *Repository) error {
 	newOwner, err := GetUserByName(newOwnerName)
 	if err != nil {
-		return fmt.Errorf("get new owner(%s): %v", newOwnerName, err)
+		return fmt.Errorf("get new owner '%s': %v", newOwnerName, err)
 	}
 
 	// Check if new owner has repository with same name.
-	has, err := IsRepositoryExist(newOwner, repo.Name)
-	if err != nil {
-		return err
-	} else if has {
+	if IsRepositoryExist(newOwner, repo.Name) {
 		return ErrRepoAlreadyExist
 	}
 
 	sess := x.NewSession()
 	defer sessionRelease(sess)
 	if err = sess.Begin(); err != nil {
-		return err
+		return fmt.Errorf("sess.Begin: %v", err)
 	}
 
 	owner := repo.Owner
 
-	// Update repository.
+	// Note: we have to set value here to make sure recalculate accesses is based on
+	//	new owner.
 	repo.OwnerId = newOwner.Id
 	repo.Owner = newOwner
+
+	// Update repository.
 	if _, err := sess.Id(repo.Id).Update(repo); err != nil {
-		return err
+		return fmt.Errorf("update owner: %v", err)
 	}
 
-	// Remove redundant collaborators
+	// Remove redundant collaborators.
 	collaborators, err := repo.GetCollaborators()
 	if err != nil {
-		return err
+		return fmt.Errorf("GetCollaborators: %v", err)
 	}
+
+	// Dummy object.
+	collaboration := &Collaboration{RepoID: repo.Id}
 	for _, c := range collaborators {
+		collaboration.UserID = c.Id
 		if c.Id == newOwner.Id || newOwner.IsOrgMember(c.Id) {
-			if _, err = sess.Delete(&Collaboration{RepoID: repo.Id, UserID: c.Id}); err != nil {
-				return err
+			if _, err = sess.Delete(collaboration); err != nil {
+				return fmt.Errorf("remove collaborator '%d': %v", c.Id, err)
 			}
 		}
 	}
 
 	if newOwner.IsOrganization() {
-		// Update owner team info and count.
 		t, err := newOwner.GetOwnerTeam()
 		if err != nil {
-			return err
+			return fmt.Errorf("GetOwnerTeam: %v", err)
 		} else if err = t.addRepository(sess, repo); err != nil {
-			return err
+			return fmt.Errorf("add to owner team: %v", err)
+		}
+	} else {
+		// Organization called this in addRepository method.
+		if err = repo.recalculateAccesses(sess); err != nil {
+			return fmt.Errorf("recalculateAccesses: %v", err)
 		}
 	}
 
-	// Update user repository number.
-	if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", newOwner.Id); err != nil {
-		return err
-	} else if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?", owner.Id); err != nil {
-		return err
-	} else if err = repo.recalculateAccesses(sess); err != nil {
-		return err
-	} else if err = watchRepo(sess, newOwner.Id, repo.Id, true); err != nil {
-		return err
+	// Update repository count.
+	if _, err = sess.Exec("UPDATE `user` SET num_repos=num_repos+1 WHERE id=?", newOwner.Id); err != nil {
+		return fmt.Errorf("increase new owner repository count: %v", err)
+	} else if _, err = sess.Exec("UPDATE `user` SET num_repos=num_repos-1 WHERE id=?", owner.Id); err != nil {
+		return fmt.Errorf("decrease old owner repository count: %v", err)
+	}
+
+	if err = watchRepo(sess, newOwner.Id, repo.Id, true); err != nil {
+		return fmt.Errorf("watchRepo: %v", err)
 	} else if err = transferRepoAction(sess, u, owner, newOwner, repo); err != nil {
-		return err
+		return fmt.Errorf("transferRepoAction: %v", err)
 	}
 
 	// Change repository directory name.
 	if err = os.Rename(RepoPath(owner.Name, repo.Name), RepoPath(newOwner.Name, repo.Name)); err != nil {
-		return err
+		return fmt.Errorf("rename directory: %v", err)
 	}
 
 	return sess.Commit()
@@ -1275,11 +1276,8 @@ func IsStaring(uid, repoId int64) bool {
 //  \___  / \____/|__|  |__|_ \
 //      \/                   \/
 
-func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repository, error) {
-	isExist, err := IsRepositoryExist(u, name)
-	if err != nil {
-		return nil, err
-	} else if isExist {
+func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
+	if IsRepositoryExist(u, name) {
 		return nil, ErrRepoAlreadyExist
 	}
 

+ 2 - 6
routers/repo/setting.go

@@ -53,15 +53,11 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
 		newRepoName := form.RepoName
 		// Check if repository name has been changed.
 		if ctx.Repo.Repository.Name != newRepoName {
-			isExist, err := models.IsRepositoryExist(ctx.Repo.Owner, newRepoName)
-			if err != nil {
-				ctx.Handle(500, "IsRepositoryExist", err)
-				return
-			} else if isExist {
+			if models.IsRepositoryExist(ctx.Repo.Owner, newRepoName) {
 				ctx.Data["Err_RepoName"] = true
 				ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), SETTINGS_OPTIONS, nil)
 				return
-			} else if err = models.ChangeRepositoryName(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName); err != nil {
+			} else if err := models.ChangeRepositoryName(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName); err != nil {
 				if err == models.ErrRepoNameIllegal {
 					ctx.Data["Err_RepoName"] = true
 					ctx.RenderWithErr(ctx.Tr("form.illegal_repo_name"), SETTINGS_OPTIONS, nil)

+ 1 - 1
templates/.VERSION

@@ -1 +1 @@
-0.5.15.0223 Beta
+0.5.15.0224 Beta