James Moger
2012-11-01 b701ed7c4e138c4aaa3acb029f6e35fdf01388e4
commit | author | age
fa54be 1 /*
JM 2  * Copyright 2011 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 import com.gitblit.GitBlit
17 import com.gitblit.Keys
18 import com.gitblit.models.RepositoryModel
0b9119 19 import com.gitblit.models.TeamModel
fa54be 20 import com.gitblit.models.UserModel
JM 21 import com.gitblit.utils.JGitUtils
098bcd 22 import java.text.SimpleDateFormat
fa54be 23 import org.eclipse.jgit.lib.Repository
JM 24 import org.eclipse.jgit.lib.Config
25 import org.eclipse.jgit.revwalk.RevCommit
26 import org.eclipse.jgit.transport.ReceiveCommand
27 import org.eclipse.jgit.transport.ReceiveCommand.Result
28 import org.slf4j.Logger
29
30 /**
eb96ea 31  * Sample Gitblit Post-Receive Hook: sendmail
fa54be 32  *
JM 33  * The Post-Receive hook is executed AFTER the pushed commits have been applied
34  * to the Git repository.  This is the appropriate point to trigger an
35  * integration build or to send a notification.
36  * 
37  * This script is only executed when pushing to *Gitblit*, not to other Git
38  * tooling you may be using.
39  * 
40  * If this script is specified in *groovy.postReceiveScripts* of gitblit.properties
41  * or web.xml then it will be executed by any repository when it receives a
42  * push.  If you choose to share your script then you may have to consider
43  * tailoring control-flow based on repository access restrictions.
44  *
45  * Scripts may also be specified per-repository in the repository settings page.
46  * Shared scripts will be excluded from this list of available scripts.
47  * 
48  * This script is dynamically reloaded and it is executed within it's own
49  * exception handler so it will not crash another script nor crash Gitblit.
50  *
51  * If you want this hook script to fail and abort all subsequent scripts in the
52  * chain, "return false" at the appropriate failure points.
53  * 
54  * Bound Variables:
2f5d15 55  *  gitblit            Gitblit Server                 com.gitblit.GitBlit
JM 56  *  repository        Gitblit Repository            com.gitblit.models.RepositoryModel
6bb3b2 57  *  receivePack        JGit Receive Pack            org.eclipse.jgit.transport.ReceivePack
2f5d15 58  *  user            Gitblit User                com.gitblit.models.UserModel
JM 59  *  commands        JGit commands                 Collection<org.eclipse.jgit.transport.ReceiveCommand>
60  *    url                Base url for Gitblit        String
61  *  logger            Logs messages to Gitblit     org.slf4j.Logger
62  *  clientLogger    Logs messages to Git client    com.gitblit.utils.ClientLogger
7c1cdc 63  *
JM 64  * Accessing Gitblit Custom Fields:
65  *   def myCustomField = repository.customFields.myCustomField
fa54be 66  *  
JM 67  */
68
69 // Indicate we have started the script
eb96ea 70 logger.info("sendmail hook triggered by ${user.username} for ${repository.name}")
fa54be 71
JM 72 /*
eb96ea 73  * Primitive email notification.
fa54be 74  * This requires the mail settings to be properly configured in Gitblit.
JM 75  */
76
77 Repository r = gitblit.getRepository(repository.name)
78
eb96ea 79 // reuse existing repository config settings, if available
fa54be 80 Config config = r.getConfig()
198fa1 81 def mailinglist = config.getString('hooks', null, 'mailinglist')
JM 82 def emailprefix = config.getString('hooks', null, 'emailprefix')
fa54be 83
JM 84 // set default values
85 def toAddresses = []
86 if (emailprefix == null)
a50c4a 87 emailprefix = '[Gitblit]'
fa54be 88
JM 89 if (mailinglist != null) {
eb96ea 90     def addrs = mailinglist.split(/(,|\s)/)
fa54be 91     toAddresses.addAll(addrs)
JM 92 }
93
94 // add all mailing lists defined in gitblit.properties or web.xml
95 toAddresses.addAll(gitblit.getStrings(Keys.mail.mailingLists))
96
0b9119 97 // add all team mailing lists
JM 98 def teams = gitblit.getRepositoryTeams(repository)
99 for (team in teams) {
100     TeamModel model = gitblit.getTeamModel(team)
101     if (model.mailingLists) {
102         toAddresses.addAll(model.mailingLists)
103     }
104 }
105
eb96ea 106 // add all mailing lists for the repository
JM 107 toAddresses.addAll(repository.mailingLists)
198fa1 108
JM 109 // define the summary and commit urls
836188 110 def repo = repository.name
198fa1 111 def summaryUrl
JM 112 def commitUrl
836188 113 if (gitblit.getBoolean(Keys.web.mountParameters, true)) {
JM 114     repo = repo.replace('/', gitblit.getString(Keys.web.forwardSlashCharacter, '/')).replace('/', '%2F')
916e84 115     summaryUrl = url + "/summary/$repo"
JM 116     commitUrl = url + "/commit/$repo/"
198fa1 117 } else {
916e84 118     summaryUrl = url + "/summary?r=$repo"
JM 119     commitUrl = url + "/commit?r=$repo&h="
fa54be 120 }
JM 121
f47590 122 // construct a simple text summary of the changes contained in the push
098bcd 123 def branchBreak = '>---------------------------------------------------------------\n'
JM 124 def commitBreak = '\n\n ----\n'
f47590 125 def commitCount = 0
198fa1 126 def changes = ''
098bcd 127 SimpleDateFormat df = new SimpleDateFormat(gitblit.getString(Keys.web.datetimestampLongFormat, 'EEEE, MMMM d, yyyy h:mm a z'))
JM 128 def table = { "\n ${JGitUtils.getDisplayName(it.authorIdent)}\n ${df.format(JGitUtils.getCommitDate(it))}\n\n $it.shortMessage\n\n $commitUrl$it.id.name" }
f47590 129 for (command in commands) {
eb96ea 130     def ref = command.refName
4c0100 131     def refType = 'branch'
eb96ea 132     if (ref.startsWith('refs/heads/')) {
JM 133         ref  = command.refName.substring('refs/heads/'.length())
134     } else if (ref.startsWith('refs/tags/')) {
135         ref  = command.refName.substring('refs/tags/'.length())
4c0100 136         refType = 'tag'
eb96ea 137     }
JM 138         
fa54be 139     switch (command.type) {
JM 140         case ReceiveCommand.Type.CREATE:
0fb1fd 141             def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
f47590 142             commitCount += commits.size()
4c0100 143             // new branch
JM 144             changes += "\n$branchBreak new $refType $ref created ($commits.size commits)\n$branchBreak"
145             changes += commits.collect(table).join(commitBreak)
146             changes += '\n'
fa54be 147             break
f47590 148         case ReceiveCommand.Type.UPDATE:
0fb1fd 149             def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
f47590 150             commitCount += commits.size()
JM 151             // fast-forward branch commits table
4c0100 152             changes += "\n$branchBreak $ref $refType updated ($commits.size commits)\n$branchBreak"
098bcd 153             changes += commits.collect(table).join(commitBreak)
198fa1 154             changes += '\n'
f47590 155             break
JM 156         case ReceiveCommand.Type.UPDATE_NONFASTFORWARD:
0fb1fd 157             def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
f47590 158             commitCount += commits.size()
JM 159             // non-fast-forward branch commits table
4c0100 160             changes += "\n$branchBreak $ref $refType updated [NON fast-forward] ($commits.size commits)\n$branchBreak"
098bcd 161             changes += commits.collect(table).join(commitBreak)
198fa1 162             changes += '\n'
f47590 163             break
JM 164         case ReceiveCommand.Type.DELETE:
098bcd 165             // deleted branch/tag
4c0100 166             changes += "\n$branchBreak $ref $refType deleted\n$branchBreak"
f47590 167             break
fa54be 168         default:
JM 169             break
170     }
171 }
172 // close the repository reference
173 r.close()
174
175 // tell Gitblit to send the message (Gitblit filters duplicate addresses)
5e8e7e 176 gitblit.sendMail("$emailprefix $user.username pushed $commitCount commits => $repository.name", "$summaryUrl\n$changes", toAddresses)