diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2014-03-22 00:50:47 +0800 |
---|---|---|
committer | Lunny Xiao <xiaolunwen@gmail.com> | 2014-03-22 00:50:47 +0800 |
commit | 17da2fd2e30e85909394bc58069ecab14d8d8577 (patch) | |
tree | d80e786818d20aed12b7a84f6a9961468a7f70ec /models/repo.go | |
parent | efdaf6ee1536f043d9e242dc16a096c99ec1bfda (diff) | |
parent | f219ddcf4ef13b9d5de129da4eb2b56dbc899d61 (diff) | |
download | gitea-17da2fd2e30e85909394bc58069ecab14d8d8577.tar.gz gitea-17da2fd2e30e85909394bc58069ecab14d8d8577.zip |
merged
Diffstat (limited to 'models/repo.go')
-rw-r--r-- | models/repo.go | 276 |
1 files changed, 173 insertions, 103 deletions
diff --git a/models/repo.go b/models/repo.go index cf1e1df5c4..4972661cb3 100644 --- a/models/repo.go +++ b/models/repo.go @@ -12,6 +12,7 @@ import ( "os" "path" "path/filepath" + "regexp" "strings" "sync" "time" @@ -26,68 +27,26 @@ import ( "github.com/gogits/gogs/modules/log" ) -// Repository represents a git repository. -type Repository struct { - Id int64 - OwnerId int64 `xorm:"unique(s)"` - ForkId int64 - LowerName string `xorm:"unique(s) index not null"` - Name string `xorm:"index not null"` - Description string - Website string - Private bool - NumWatchs int - NumStars int - NumForks int - Created time.Time `xorm:"created"` - Updated time.Time `xorm:"updated"` -} - -// Watch is connection request for receiving repository notifycation. -type Watch struct { - Id int64 - RepoId int64 `xorm:"UNIQUE(watch)"` - UserId int64 `xorm:"UNIQUE(watch)"` -} - -// Watch or unwatch repository. -func WatchRepo(userId, repoId int64, watch bool) (err error) { - if watch { - _, err = orm.Insert(&Watch{RepoId: repoId, UserId: userId}) - } else { - _, err = orm.Delete(&Watch{0, repoId, userId}) - } - return err -} - -// GetWatches returns all watches of given repository. -func GetWatches(repoId int64) ([]Watch, error) { - watches := make([]Watch, 0, 10) - err := orm.Find(&watches, &Watch{RepoId: repoId}) - return watches, err -} - -// IsWatching checks if user has watched given repository. -func IsWatching(userId, repoId int64) bool { - has, _ := orm.Get(&Watch{0, repoId, userId}) - return has -} - var ( - gitInitLocker = sync.Mutex{} - LanguageIgns, Licenses []string + ErrRepoAlreadyExist = errors.New("Repository already exist") + ErrRepoNotExist = errors.New("Repository does not exist") + ErrRepoFileNotExist = errors.New("Target Repo file does not exist") + ErrRepoNameIllegal = errors.New("Repository name contains illegal characters") + ErrRepoFileNotLoaded = fmt.Errorf("repo file not loaded") ) +var gitInitLocker = sync.Mutex{} + var ( - ErrRepoAlreadyExist = errors.New("Repository already exist") - ErrRepoNotExist = errors.New("Repository does not exist") - ErrRepoFileNotExist = errors.New("Target Repo file does not exist") + LanguageIgns, Licenses []string ) -func init() { +func LoadRepoConfig() { LanguageIgns = strings.Split(base.Cfg.MustValue("repository", "LANG_IGNS"), "|") Licenses = strings.Split(base.Cfg.MustValue("repository", "LICENSES"), "|") +} +func NewRepoContext() { zip.Verbose = false // Check if server has basic git setting. @@ -104,6 +63,32 @@ func init() { os.Exit(2) } } + + // Initialize illegal patterns. + for i := range illegalPatterns[1:] { + pattern := "" + for j := range illegalPatterns[i+1] { + pattern += "[" + string(illegalPatterns[i+1][j]-32) + string(illegalPatterns[i+1][j]) + "]" + } + illegalPatterns[i+1] = pattern + } +} + +// Repository represents a git repository. +type Repository struct { + Id int64 + OwnerId int64 `xorm:"unique(s)"` + ForkId int64 + LowerName string `xorm:"unique(s) index not null"` + Name string `xorm:"index not null"` + Description string + Website string + Private bool + NumWatches int + NumStars int + NumForks int + Created time.Time `xorm:"created"` + Updated time.Time `xorm:"updated"` } // IsRepositoryExist returns true if the repository with given name under user has already existed. @@ -120,8 +105,28 @@ func IsRepositoryExist(user *User, repoName string) (bool, error) { return s.IsDir(), nil } +var ( + // Define as all lower case!! + illegalPatterns = []string{"[.][Gg][Ii][Tt]", "user", "help", "stars", "issues", "pulls", "commits", "admin", "repo", "template", "admin"} +) + +// IsLegalName returns false if name contains illegal characters. +func IsLegalName(repoName string) bool { + for _, pattern := range illegalPatterns { + has, _ := regexp.MatchString(pattern, repoName) + if has { + return false + } + } + return true +} + // CreateRepository creates a repository for given user or orgnaziation. func CreateRepository(user *User, repoName, desc, repoLang, license string, private bool, initReadme bool) (*Repository, error) { + if !IsLegalName(repoName) { + return nil, ErrRepoNameIllegal + } + isExist, err := IsRepositoryExist(user, repoName) if err != nil { return nil, err @@ -331,6 +336,82 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep return nil } +// UserRepo reporesents a repository with user name. +type UserRepo struct { + *Repository + UserName string +} + +// GetRepos returns given number of repository objects with offset. +func GetRepos(num, offset int) ([]UserRepo, error) { + repos := make([]Repository, 0, num) + if err := orm.Limit(num, offset).Asc("id").Find(&repos); err != nil { + return nil, err + } + + urepos := make([]UserRepo, len(repos)) + for i := range repos { + urepos[i].Repository = &repos[i] + u := new(User) + has, err := orm.Id(urepos[i].Repository.OwnerId).Get(u) + if err != nil { + return nil, err + } else if !has { + return nil, ErrUserNotExist + } + urepos[i].UserName = u.Name + } + + return urepos, nil +} + +func RepoPath(userName, repoName string) string { + return filepath.Join(UserPath(userName), repoName+".git") +} + +// DeleteRepository deletes a repository for a user or orgnaztion. +func DeleteRepository(userId, repoId int64, userName string) (err error) { + repo := &Repository{Id: repoId, OwnerId: userId} + has, err := orm.Get(repo) + if err != nil { + return err + } else if !has { + return ErrRepoNotExist + } + + session := orm.NewSession() + if err = session.Begin(); err != nil { + return err + } + if _, err = session.Delete(&Repository{Id: repoId}); err != nil { + session.Rollback() + return err + } + if _, err := session.Delete(&Access{UserName: userName, RepoName: repo.Name}); err != nil { + session.Rollback() + return err + } + rawSql := "UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?" + if _, err = session.Exec(rawSql, userId); err != nil { + session.Rollback() + return err + } + if _, err = session.Delete(&Watch{RepoId: repoId}); err != nil { + session.Rollback() + return err + } + if err = session.Commit(); err != nil { + session.Rollback() + return err + } + if err = os.RemoveAll(RepoPath(userName, repo.Name)); err != nil { + // TODO: log and delete manully + log.Error("delete repo %s/%s failed: %v", userName, repo.Name, err) + return err + } + return nil +} + // GetRepositoryByName returns the repository by given name under user if exists. func GetRepositoryByName(user *User, repoName string) (*Repository, error) { repo := &Repository{ @@ -368,6 +449,45 @@ func GetRepositoryCount(user *User) (int64, error) { return orm.Count(&Repository{OwnerId: user.Id}) } +// Watch is connection request for receiving repository notifycation. +type Watch struct { + Id int64 + RepoId int64 `xorm:"UNIQUE(watch)"` + UserId int64 `xorm:"UNIQUE(watch)"` +} + +// Watch or unwatch repository. +func WatchRepo(userId, repoId int64, watch bool) (err error) { + if watch { + if _, err = orm.Insert(&Watch{RepoId: repoId, UserId: userId}); err != nil { + return err + } + + rawSql := "UPDATE `repository` SET num_watches = num_watches + 1 WHERE id = ?" + _, err = orm.Exec(rawSql, repoId) + } else { + if _, err = orm.Delete(&Watch{0, repoId, userId}); err != nil { + return err + } + rawSql := "UPDATE `repository` SET num_watches = num_watches - 1 WHERE id = ?" + _, err = orm.Exec(rawSql, repoId) + } + return err +} + +// GetWatches returns all watches of given repository. +func GetWatches(repoId int64) ([]Watch, error) { + watches := make([]Watch, 0, 10) + err := orm.Find(&watches, &Watch{RepoId: repoId}) + return watches, err +} + +// IsWatching checks if user has watched given repository. +func IsWatching(userId, repoId int64) bool { + has, _ := orm.Get(&Watch{0, repoId, userId}) + return has +} + func StarReposiory(user *User, repoName string) error { return nil } @@ -388,56 +508,6 @@ func ForkRepository(reposName string, userId int64) { } -func RepoPath(userName, repoName string) string { - return filepath.Join(UserPath(userName), repoName+".git") -} - -// DeleteRepository deletes a repository for a user or orgnaztion. -func DeleteRepository(userId, repoId int64, userName string) (err error) { - repo := &Repository{Id: repoId, OwnerId: userId} - has, err := orm.Get(repo) - if err != nil { - return err - } else if !has { - return ErrRepoNotExist - } - - session := orm.NewSession() - if err = session.Begin(); err != nil { - return err - } - if _, err = session.Delete(&Repository{Id: repoId}); err != nil { - session.Rollback() - return err - } - if _, err := session.Delete(&Access{UserName: userName, RepoName: repo.Name}); err != nil { - session.Rollback() - return err - } - rawSql := "UPDATE user SET num_repos = num_repos - 1 WHERE id = ?" - if base.Cfg.MustValue("database", "DB_TYPE") == "postgres" { - rawSql = "UPDATE \"user\" SET num_repos = num_repos - 1 WHERE id = ?" - } - if _, err = session.Exec(rawSql, userId); err != nil { - session.Rollback() - return err - } - if err = session.Commit(); err != nil { - session.Rollback() - return err - } - if err = os.RemoveAll(RepoPath(userName, repo.Name)); err != nil { - // TODO: log and delete manully - log.Error("delete repo %s/%s failed: %v", userName, repo.Name, err) - return err - } - return nil -} - -var ( - ErrRepoFileNotLoaded = fmt.Errorf("repo file not loaded") -) - // RepoFile represents a file object in git repository. type RepoFile struct { *git.TreeEntry |