aboutsummaryrefslogtreecommitdiff
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/action.go95
-rw-r--r--models/issue.go26
-rw-r--r--models/publickey.go4
-rw-r--r--models/repo.go33
4 files changed, 101 insertions, 57 deletions
diff --git a/models/action.go b/models/action.go
index 318a5f6a..5cba2f51 100644
--- a/models/action.go
+++ b/models/action.go
@@ -41,14 +41,21 @@ var (
var (
// Same as Github. See https://help.github.com/articles/closing-issues-via-commit-messages
- IssueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
- IssueCloseKeywordsPat *regexp.Regexp
- IssueReferenceKeywordsPat *regexp.Regexp
+ IssueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
+ IssueReopenKeywords = []string{"reopen", "reopens", "reopened"}
+
+ IssueCloseKeywordsPat, IssueReopenKeywordsPat *regexp.Regexp
+ IssueReferenceKeywordsPat *regexp.Regexp
)
+func assembleKeywordsPattern(words []string) string {
+ return fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(words, "|"))
+}
+
func init() {
- IssueCloseKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(IssueCloseKeywords, "|")))
- IssueReferenceKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:) \S+`))
+ IssueCloseKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(IssueCloseKeywords))
+ IssueReopenKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(IssueReopenKeywords))
+ IssueReferenceKeywordsPat = regexp.MustCompile(`(?i)(?:)(^| )\S+`)
}
// Action represents user operation type and other information to repository.,
@@ -91,7 +98,7 @@ func (a Action) GetRepoName() string {
}
func (a Action) GetRepoLink() string {
- return path.Join(a.RepoUserName, a.RepoName)
+ return path.Join(setting.AppSubUrl, a.RepoUserName, a.RepoName)
}
func (a Action) GetBranch() string {
@@ -112,13 +119,11 @@ func (a Action) GetIssueInfos() []string {
func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, commits []*base.PushCommit) error {
for _, c := range commits {
- references := IssueReferenceKeywordsPat.FindAllString(c.Message, -1)
-
- for _, ref := range references {
+ for _, ref := range IssueReferenceKeywordsPat.FindAllString(c.Message, -1) {
ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool {
- return !unicode.IsDigit(c)
- })
+ return !unicode.IsDigit(c)
+ })
if len(ref) == 0 {
continue
@@ -128,33 +133,29 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if ref[0] == '#' {
ref = fmt.Sprintf("%s/%s%s", repoUserName, repoName, ref)
} else if strings.Contains(ref, "/") == false {
- // We don't support User#ID syntax yet
+ // FIXME: We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
-
if err != nil {
return err
}
url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1)
message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message)
-
- if _, err = CreateComment(userId, issue.RepoId, issue.Id, 0, 0, COMMIT, message, nil); err != nil {
+ if _, err = CreateComment(userId, issue.RepoId, issue.Id, 0, 0, COMMENT_TYPE_COMMIT, message, nil); err != nil {
return err
}
}
- closes := IssueCloseKeywordsPat.FindAllString(c.Message, -1)
-
- for _, ref := range closes {
+ for _, ref := range IssueCloseKeywordsPat.FindAllString(c.Message, -1) {
ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool {
- return !unicode.IsDigit(c)
- })
+ return !unicode.IsDigit(c)
+ })
if len(ref) == 0 {
continue
@@ -171,7 +172,6 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
issue, err := GetIssueByRef(ref)
-
if err != nil {
return err
}
@@ -180,7 +180,6 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if issue.IsClosed {
continue
}
-
issue.IsClosed = true
if err = UpdateIssue(issue); err != nil {
@@ -194,14 +193,60 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
// If commit happened in the referenced repository, it means the issue can be closed.
- if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, CLOSE, "", nil); err != nil {
+ if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, COMMENT_TYPE_CLOSE, "", nil); err != nil {
return err
}
}
}
-
- }
+ for _, ref := range IssueReopenKeywordsPat.FindAllString(c.Message, -1) {
+ ref := ref[strings.IndexByte(ref, byte(' '))+1:]
+ ref = strings.TrimRightFunc(ref, func(c rune) bool {
+ return !unicode.IsDigit(c)
+ })
+
+ if len(ref) == 0 {
+ continue
+ }
+
+ // Add repo name if missing
+ if ref[0] == '#' {
+ ref = fmt.Sprintf("%s/%s%s", repoUserName, repoName, ref)
+ } else if strings.Contains(ref, "/") == false {
+ // We don't support User#ID syntax yet
+ // return ErrNotImplemented
+
+ continue
+ }
+
+ issue, err := GetIssueByRef(ref)
+ if err != nil {
+ return err
+ }
+
+ if issue.RepoId == repoId {
+ if !issue.IsClosed {
+ continue
+ }
+ issue.IsClosed = false
+
+ if err = UpdateIssue(issue); err != nil {
+ return err
+ } else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil {
+ return err
+ }
+
+ if err = ChangeMilestoneIssueStats(issue); err != nil {
+ return err
+ }
+
+ // If commit happened in the referenced repository, it means the issue can be closed.
+ if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, COMMENT_TYPE_REOPEN, "", nil); err != nil {
+ return err
+ }
+ }
+ }
+ }
return nil
}
diff --git a/models/issue.go b/models/issue.go
index c756e497..d9a24063 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -859,22 +859,16 @@ type CommentType int
const (
// Plain comment, can be associated with a commit (CommitId > 0) and a line (Line > 0)
- COMMENT CommentType = iota
-
- // Reopen action
- REOPEN
-
- // Close action
- CLOSE
-
- // Reference from another issue
- ISSUE
+ COMMENT_TYPE_COMMENT CommentType = iota
+ COMMENT_TYPE_REOPEN
+ COMMENT_TYPE_CLOSE
+ // References.
+ COMMENT_TYPE_ISSUE
// Reference from some commit (not part of a pull request)
- COMMIT
-
+ COMMENT_TYPE_COMMIT
// Reference from some pull request
- PULL
+ COMMENT_TYPE_PULL
)
// Comment represents a comment in commit and issue page.
@@ -908,7 +902,7 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType Commen
// Check comment type.
switch cmtType {
- case COMMENT:
+ case COMMENT_TYPE_COMMENT:
rawSql := "UPDATE `issue` SET num_comments = num_comments + 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, issueId); err != nil {
sess.Rollback()
@@ -929,13 +923,13 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType Commen
return nil, err
}
}
- case REOPEN:
+ case COMMENT_TYPE_REOPEN:
rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues - 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, repoId); err != nil {
sess.Rollback()
return nil, err
}
- case CLOSE:
+ case COMMENT_TYPE_CLOSE:
rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues + 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, repoId); err != nil {
sess.Rollback()
diff --git a/models/publickey.go b/models/publickey.go
index 67ab4242..b1c7b624 100644
--- a/models/publickey.go
+++ b/models/publickey.go
@@ -29,7 +29,7 @@ import (
const (
// "### autogenerated by gitgos, DO NOT EDIT\n"
- _TPL_PUBLICK_KEY = `command="%s serv key-%d",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
+ _TPL_PUBLICK_KEY = `command="%s serv --config='%s' key-%d",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
)
var (
@@ -98,7 +98,7 @@ func (k *PublicKey) OmitEmail() string {
// GetAuthorizedString generates and returns formatted public key string for authorized_keys file.
func (key *PublicKey) GetAuthorizedString() string {
- return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, key.Id, key.Content)
+ return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, setting.CustomConf, key.Id, key.Content)
}
var (
diff --git a/models/repo.go b/models/repo.go
index b7458217..f2f10baf 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -30,7 +30,7 @@ import (
)
const (
- TPL_UPDATE_HOOK = "#!/usr/bin/env %s\n%s update $1 $2 $3\n"
+ _TPL_UPDATE_HOOK = "#!/usr/bin/env %s\n%s update --config='%s' $1 $2 $3\n"
)
var (
@@ -247,8 +247,8 @@ func (repo *Repository) CloneLink() (cl CloneLink, err error) {
if err = repo.GetOwner(); err != nil {
return cl, err
}
- if setting.SshPort != 22 {
- cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.Domain, setting.SshPort, repo.Owner.LowerName, repo.LowerName)
+ if setting.SSHPort != 22 {
+ cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.Domain, setting.SSHPort, repo.Owner.LowerName, repo.LowerName)
} else {
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.Domain, repo.Owner.LowerName, repo.LowerName)
}
@@ -402,15 +402,9 @@ func initRepoCommit(tmpPath string, sig *git.Signature) (err error) {
return nil
}
-func createHookUpdate(hookPath, content string) error {
- pu, err := os.OpenFile(hookPath, os.O_CREATE|os.O_WRONLY, 0777)
- if err != nil {
- return err
- }
- defer pu.Close()
-
- _, err = pu.WriteString(content)
- return err
+func createHookUpdate(repoPath string) error {
+ return ioutil.WriteFile(path.Join(repoPath, "hooks/update"),
+ []byte(fmt.Sprintf(_TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"", setting.CustomConf)), 0777)
}
// InitRepository initializes README and .gitignore if needed.
@@ -423,8 +417,7 @@ func initRepository(f string, u *User, repo *Repository, initReadme bool, repoLa
}
// hook/post-update
- if err := createHookUpdate(filepath.Join(repoPath, "hooks", "update"),
- fmt.Sprintf(TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"")); err != nil {
+ if err := createHookUpdate(repoPath); err != nil {
return err
}
@@ -1174,6 +1167,18 @@ func DeleteRepositoryArchives() error {
})
}
+// RewriteRepositoryUpdateHook rewrites all repositories' update hook.
+func RewriteRepositoryUpdateHook() error {
+ return x.Where("id > 0").Iterate(new(Repository),
+ func(idx int, bean interface{}) error {
+ repo := bean.(*Repository)
+ if err := repo.GetOwner(); err != nil {
+ return err
+ }
+ return createHookUpdate(RepoPath(repo.Owner.Name, repo.Name))
+ })
+}
+
var (
// Prevent duplicate tasks.
isMirrorUpdating = false