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