James Moger
2012-07-11 d00a0ca46fcde3e3e580afea6a548b9c12aeac25
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
57  *  user            Gitblit User                com.gitblit.models.UserModel
58  *  commands        JGit commands                 Collection<org.eclipse.jgit.transport.ReceiveCommand>
59  *    url                Base url for Gitblit        String
60  *  logger            Logs messages to Gitblit     org.slf4j.Logger
61  *  clientLogger    Logs messages to Git client    com.gitblit.utils.ClientLogger
7c1cdc 62  *
JM 63  * Accessing Gitblit Custom Fields:
64  *   def myCustomField = repository.customFields.myCustomField
fa54be 65  *  
JM 66  */
67
68 // Indicate we have started the script
eb96ea 69 logger.info("sendmail hook triggered by ${user.username} for ${repository.name}")
fa54be 70
JM 71 /*
eb96ea 72  * Primitive email notification.
fa54be 73  * This requires the mail settings to be properly configured in Gitblit.
JM 74  */
75
76 Repository r = gitblit.getRepository(repository.name)
77
eb96ea 78 // reuse existing repository config settings, if available
fa54be 79 Config config = r.getConfig()
198fa1 80 def mailinglist = config.getString('hooks', null, 'mailinglist')
JM 81 def emailprefix = config.getString('hooks', null, 'emailprefix')
fa54be 82
JM 83 // set default values
84 def toAddresses = []
85 if (emailprefix == null)
a50c4a 86 emailprefix = '[Gitblit]'
fa54be 87
JM 88 if (mailinglist != null) {
eb96ea 89     def addrs = mailinglist.split(/(,|\s)/)
fa54be 90     toAddresses.addAll(addrs)
JM 91 }
92
93 // add all mailing lists defined in gitblit.properties or web.xml
94 toAddresses.addAll(gitblit.getStrings(Keys.mail.mailingLists))
95
0b9119 96 // add all team mailing lists
JM 97 def teams = gitblit.getRepositoryTeams(repository)
98 for (team in teams) {
99     TeamModel model = gitblit.getTeamModel(team)
100     if (model.mailingLists) {
101         toAddresses.addAll(model.mailingLists)
102     }
103 }
104
eb96ea 105 // add all mailing lists for the repository
JM 106 toAddresses.addAll(repository.mailingLists)
198fa1 107
JM 108 // define the summary and commit urls
a50c4a 109 def repo = repository.name.replace('/', gitblit.getString(Keys.web.forwardSlashCharacter, '/'))
198fa1 110 def summaryUrl
JM 111 def commitUrl
916e84 112 if (gitblit.getBoolean(Keys.web.mountParameters, true)) {    
JM 113     summaryUrl = url + "/summary/$repo"
114     commitUrl = url + "/commit/$repo/"
198fa1 115 } else {
916e84 116     summaryUrl = url + "/summary?r=$repo"
JM 117     commitUrl = url + "/commit?r=$repo&h="
fa54be 118 }
JM 119
f47590 120 // construct a simple text summary of the changes contained in the push
098bcd 121 def branchBreak = '>---------------------------------------------------------------\n'
JM 122 def commitBreak = '\n\n ----\n'
f47590 123 def commitCount = 0
198fa1 124 def changes = ''
098bcd 125 SimpleDateFormat df = new SimpleDateFormat(gitblit.getString(Keys.web.datetimestampLongFormat, 'EEEE, MMMM d, yyyy h:mm a z'))
JM 126 def table = { "\n ${JGitUtils.getDisplayName(it.authorIdent)}\n ${df.format(JGitUtils.getCommitDate(it))}\n\n $it.shortMessage\n\n $commitUrl$it.id.name" }
f47590 127 for (command in commands) {
eb96ea 128     def ref = command.refName
4c0100 129     def refType = 'branch'
eb96ea 130     if (ref.startsWith('refs/heads/')) {
JM 131         ref  = command.refName.substring('refs/heads/'.length())
132     } else if (ref.startsWith('refs/tags/')) {
133         ref  = command.refName.substring('refs/tags/'.length())
4c0100 134         refType = 'tag'
eb96ea 135     }
JM 136         
fa54be 137     switch (command.type) {
JM 138         case ReceiveCommand.Type.CREATE:
0fb1fd 139             def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
f47590 140             commitCount += commits.size()
4c0100 141             // new branch
JM 142             changes += "\n$branchBreak new $refType $ref created ($commits.size commits)\n$branchBreak"
143             changes += commits.collect(table).join(commitBreak)
144             changes += '\n'
fa54be 145             break
f47590 146         case ReceiveCommand.Type.UPDATE:
0fb1fd 147             def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
f47590 148             commitCount += commits.size()
JM 149             // fast-forward branch commits table
4c0100 150             changes += "\n$branchBreak $ref $refType updated ($commits.size commits)\n$branchBreak"
098bcd 151             changes += commits.collect(table).join(commitBreak)
198fa1 152             changes += '\n'
f47590 153             break
JM 154         case ReceiveCommand.Type.UPDATE_NONFASTFORWARD:
0fb1fd 155             def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
f47590 156             commitCount += commits.size()
JM 157             // non-fast-forward branch commits table
4c0100 158             changes += "\n$branchBreak $ref $refType updated [NON fast-forward] ($commits.size commits)\n$branchBreak"
098bcd 159             changes += commits.collect(table).join(commitBreak)
198fa1 160             changes += '\n'
f47590 161             break
JM 162         case ReceiveCommand.Type.DELETE:
098bcd 163             // deleted branch/tag
4c0100 164             changes += "\n$branchBreak $ref $refType deleted\n$branchBreak"
f47590 165             break
fa54be 166         default:
JM 167             break
168     }
169 }
170 // close the repository reference
171 r.close()
172
173 // tell Gitblit to send the message (Gitblit filters duplicate addresses)
5e8e7e 174 gitblit.sendMail("$emailprefix $user.username pushed $commitCount commits => $repository.name", "$summaryUrl\n$changes", toAddresses)