diff options
author | Ethan Koenig <etk39@cornell.edu> | 2017-02-05 09:35:03 -0500 |
---|---|---|
committer | Lunny Xiao <xiaolunwen@gmail.com> | 2017-02-05 22:35:03 +0800 |
commit | 027591a3a556477a26d6c849e1ed9b9a53c15110 (patch) | |
tree | a2530f9419e864fbb68e6b38dd7b28ce58f592b6 /models | |
parent | e86d9351754f85b1508092b793dbd8a5cd1456f2 (diff) | |
download | gitea-027591a3a556477a26d6c849e1ed9b9a53c15110.tar.gz gitea-027591a3a556477a26d6c849e1ed9b9a53c15110.zip |
Redirects for renamed repos (#807)
* Redirects for renamed repos
* Remove unused phrase from locales
Diffstat (limited to 'models')
-rw-r--r-- | models/error.go | 16 | ||||
-rw-r--r-- | models/models.go | 1 | ||||
-rw-r--r-- | models/repo.go | 3 | ||||
-rw-r--r-- | models/repo_redirect.go | 62 |
4 files changed, 82 insertions, 0 deletions
diff --git a/models/error.go b/models/error.go index e0d33df6dc..8b0781f697 100644 --- a/models/error.go +++ b/models/error.go @@ -408,6 +408,22 @@ func (err ErrRepoAlreadyExist) Error() string { return fmt.Sprintf("repository already exists [uname: %s, name: %s]", err.Uname, err.Name) } +// 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 { IsURLError bool diff --git a/models/models.go b/models/models.go index ec93d4c12b..1f49640dd4 100644 --- a/models/models.go +++ b/models/models.go @@ -109,6 +109,7 @@ func init() { new(LFSMetaObject), new(TwoFactor), new(RepoUnit), + new(RepoRedirect), ) gonicNames := []string{"SSL", "UID"} diff --git a/models/repo.go b/models/repo.go index a16b7a86f0..ab10cb6651 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1054,6 +1054,9 @@ func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) { if _, err = e.Insert(repo); err != nil { return err } + if err = deleteRepoRedirect(e, u.ID, repo.Name); err != nil { + return err + } // insert units for repo var units = make([]RepoUnit, 0, len(defaultRepoUnits)) diff --git a/models/repo_redirect.go b/models/repo_redirect.go new file mode 100644 index 0000000000..813b3e6c9e --- /dev/null +++ b/models/repo_redirect.go @@ -0,0 +1,62 @@ +// 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" + +// 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 +} + +// 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 := x.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(ownerID, repoID int64, oldRepoName, newRepoName string) error { + oldRepoName = strings.ToLower(oldRepoName) + newRepoName = strings.ToLower(newRepoName) + sess := x.NewSession() + defer sess.Close() + + if err := sess.Begin(); err != nil { + return err + } + + if err := deleteRepoRedirect(sess, ownerID, newRepoName); err != nil { + sess.Rollback() + return err + } + + if _, err := sess.Insert(&RepoRedirect{ + OwnerID: ownerID, + LowerName: oldRepoName, + RedirectRepoID: repoID, + }); err != nil { + sess.Rollback() + return err + } + return sess.Commit() +} + +// deleteRepoRedirect delete any redirect from the specified repo name to +// anything else +func deleteRepoRedirect(e Engine, ownerID int64, repoName string) error { + repoName = strings.ToLower(repoName) + _, err := e.Delete(&RepoRedirect{OwnerID: ownerID, LowerName: repoName}) + return err +} |