ruby_git_hooks 0.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +19 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +327 -0
- data/Rakefile +7 -0
- data/TODO +67 -0
- data/bin/git-add-hooks +111 -0
- data/bin/git-clone +57 -0
- data/bin/git-hclone +57 -0
- data/lib/ruby_git_hooks/all.rb +7 -0
- data/lib/ruby_git_hooks/case_clash.rb +30 -0
- data/lib/ruby_git_hooks/copyright_check.rb +181 -0
- data/lib/ruby_git_hooks/email_notify.rb +50 -0
- data/lib/ruby_git_hooks/git_ops.rb +93 -0
- data/lib/ruby_git_hooks/jira_add_comment.rb +354 -0
- data/lib/ruby_git_hooks/jira_ref_check.rb +32 -0
- data/lib/ruby_git_hooks/max_file_size.rb +32 -0
- data/lib/ruby_git_hooks/non_ascii.rb +33 -0
- data/lib/ruby_git_hooks/ruby_debug.rb +26 -0
- data/lib/ruby_git_hooks/version.rb +5 -0
- data/lib/ruby_git_hooks/watermark.rb +27 -0
- data/lib/ruby_git_hooks.rb +343 -0
- data/ruby_git_hooks.gemspec +37 -0
- data/test/basic_hook_test.rb +143 -0
- data/test/case_clash_hook_test.rb +58 -0
- data/test/copyright_check_test.rb +162 -0
- data/test/fake_curl +12 -0
- data/test/fake_mailer +5 -0
- data/test/jira_add_comment_test.rb +151 -0
- data/test/jira_ref_check_test.rb +37 -0
- data/test/max_file_size_hook_test.rb +52 -0
- data/test/multi_hook_test.rb +77 -0
- data/test/non_ascii_hook_test.rb +47 -0
- data/test/repos/.keep +0 -0
- data/test/test_helper.rb +17 -0
- data/test/watermark_test.rb +39 -0
- metadata +226 -0
@@ -0,0 +1,354 @@
|
|
1
|
+
# Copyright (C) 2013 OL2, Inc. See LICENSE.txt for details.
|
2
|
+
|
3
|
+
require "ruby_git_hooks"
|
4
|
+
require "ruby_git_hooks/jira_ref_check"
|
5
|
+
|
6
|
+
require "rest-client"
|
7
|
+
require "json"
|
8
|
+
|
9
|
+
# This hook adds Jira "commit" comments for your commits. It is
|
10
|
+
# called as a post-receive hook with a list of commits - ideally the
|
11
|
+
# ruby_git_hooks framework would allow us to get each commit message
|
12
|
+
# from them but for now we'll do it ourselves.
|
13
|
+
|
14
|
+
# The hook checks that commit message has one or more valid Jira
|
15
|
+
# ticket references. In general we can't always reject a commit. So
|
16
|
+
# we continue through the list of commits, check everything and report
|
17
|
+
# errors.
|
18
|
+
|
19
|
+
|
20
|
+
class JiraCommentAddHook < RubyGitHooks::Hook
|
21
|
+
Hook = RubyGitHooks::Hook
|
22
|
+
|
23
|
+
OPTIONS = [ "protocol", "host", "username", "password",
|
24
|
+
"api_path", "github", "issues",
|
25
|
+
"domain", "from", "subject", "via", "via_options", "intro", "conclusion",
|
26
|
+
"no_send", "check_status"]
|
27
|
+
VALID_ERROR_TYPES = [:no_jira, :invalid_jira]
|
28
|
+
|
29
|
+
attr_accessor :errors_to_report
|
30
|
+
|
31
|
+
def initialize(options = {})
|
32
|
+
bad_options = options.keys - OPTIONS
|
33
|
+
raise "JiraCommentAddHook created with unrecognized options: " +
|
34
|
+
"#{bad_options.inspect}!" if bad_options.size > 0
|
35
|
+
|
36
|
+
if !options.has_key?("username") || !options.has_key?("password")
|
37
|
+
raise "You must provide Jira server user name and password in options"
|
38
|
+
end
|
39
|
+
|
40
|
+
@options = options
|
41
|
+
@options["protocol"] ||= "https"
|
42
|
+
@options["host"] ||= "jira"
|
43
|
+
@options["api_path"] ||= "rest/api/latest/issue"
|
44
|
+
@options["github"] ||= "github.com"
|
45
|
+
@options["check_status"] = true if !@options.has_key? "check_status" # don't allow "closed" issues by default
|
46
|
+
|
47
|
+
# options for error emailing
|
48
|
+
|
49
|
+
@options["domain"] ||= "mydomain.com"
|
50
|
+
@options["from"] ||= "Jira Jailer <noreply@#{@options["domain"]}>"
|
51
|
+
@options["subject"] ||= "Use Jira Ticket Numbers, Please!"
|
52
|
+
@options["via"] ||= "no_send"
|
53
|
+
@options["via_options"] ||= {}
|
54
|
+
|
55
|
+
|
56
|
+
@errors_to_report = {} # listed in hash indexed by user
|
57
|
+
end
|
58
|
+
|
59
|
+
def build_uri(ticket, command=nil)
|
60
|
+
uri = "#{@options['protocol']}://#{@options['username']}:#{@options['password']}@#{@options['host']}/#{@options['api_path']}/#{ticket}"
|
61
|
+
uri = "#{uri}/#{command}" if command
|
62
|
+
return uri
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def check
|
67
|
+
if commits.empty?
|
68
|
+
STDERR.puts "JiraCommentAddHook - need list of commits to process"
|
69
|
+
end
|
70
|
+
# called with a list of commits to check, as post-receive.
|
71
|
+
# consider it a success for now only if all commit checks are successful
|
72
|
+
# may cause us to redo some of the checks.
|
73
|
+
# but for now it's all or nothing.
|
74
|
+
success = true
|
75
|
+
commits.reverse_each do |commit|
|
76
|
+
commit_message = RubyGitHooks::Hook.shell!("git log #{commit} -1 --pretty=%B").rstrip
|
77
|
+
success = false unless check_one_commit(commit, commit_message )
|
78
|
+
end
|
79
|
+
|
80
|
+
# send email regarding failed commits
|
81
|
+
report_errors
|
82
|
+
return success
|
83
|
+
end
|
84
|
+
|
85
|
+
# Do not show password when converting to string
|
86
|
+
def to_s
|
87
|
+
"<JiraCommentAddHook:#{object_id} #{@options.merge("password" => :redacted)}>"
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
def repo_remote_path
|
92
|
+
remote_urls = RubyGitHooks::Hook.shell!("git remote -v").split
|
93
|
+
remote = remote_urls[1] # ["origin", "git@github.com:my_github_name/ruby_git_hooks.git", "fetch", ...]
|
94
|
+
return "" if !remote # No remote.
|
95
|
+
|
96
|
+
uri = URI.parse(remote) rescue nil
|
97
|
+
if uri
|
98
|
+
# "https://github.com/my_github_name/ruby_git_hooks.git "
|
99
|
+
uri.to_s.sub(/.git\z/, "")
|
100
|
+
else
|
101
|
+
# "git@github.com:my_github_name/ruby_git_hooks.git"
|
102
|
+
# ?? Can there be a "." in a repo name?
|
103
|
+
path = remote[/:([\w\/.-]*)/,1]
|
104
|
+
path.sub!(/.git\z/, "") if path
|
105
|
+
"#{@options['protocol']}://#{@options['github']}/#{path}"
|
106
|
+
end
|
107
|
+
# in either case return "https://github.com/my_github_name/ruby_git_hooks"
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
def build_commit_uri(commit)
|
112
|
+
# like https://github.com/my_github_name/ruby_git_hooks/commit/b067c718a74315224bf88a267a82ac85054cdf6e
|
113
|
+
|
114
|
+
uri = "#{repo_remote_path}/commit/#{commit}"
|
115
|
+
end
|
116
|
+
|
117
|
+
def get_change_list(commit)
|
118
|
+
# we want changes from the previous commit, if any
|
119
|
+
# ideally this list should be available from the ruby_git_hooks directly
|
120
|
+
# since they go through this same process.
|
121
|
+
current, base = Hook.shell!("git log #{commit} -2 --pretty=%H").split
|
122
|
+
if !base
|
123
|
+
# This is the initial commit so all files were added, but have to add the A ourselves
|
124
|
+
files_with_status = Hook.shell!("git ls-tree --name-status -r #{commit}").split("\n")
|
125
|
+
# put the A at the front
|
126
|
+
files_with_status.map!{|filename| "A\t" + filename}
|
127
|
+
else
|
128
|
+
|
129
|
+
files_with_status = Hook.shell!("git diff --name-status #{base}..#{current}")
|
130
|
+
end
|
131
|
+
files_with_status
|
132
|
+
end
|
133
|
+
|
134
|
+
def get_comment_content(commit, commit_message)
|
135
|
+
# Needs to look like the git equivalent of this
|
136
|
+
#/opt/svn/ops rev 37251 committed by john.doe (commit shah and committer)
|
137
|
+
#http://viewvc.example.com/viewvc/ops?rev=37251&view=rev (github link)
|
138
|
+
#BUG-3863 adding check to configs for testing (commit message and changes)
|
139
|
+
# U /trunk/puppet/dist/nagios/nrpe.cfg
|
140
|
+
# U /trunk/puppet/dist/nagios/ol_checks.cfg
|
141
|
+
# return as a string
|
142
|
+
# revision bac9b85f2 committed by Ruth Helfinstein
|
143
|
+
# Fri Jul 12 13:57:28 2013 -0700
|
144
|
+
# https://github.com/ruth-helfinstein/ruth-test/commit/bac9b85f2c98ccdba8d25f0b9a6e855cd2535901
|
145
|
+
# BUG-5366 commit message
|
146
|
+
#
|
147
|
+
# M test.txt
|
148
|
+
|
149
|
+
github_link = build_commit_uri(commit) # have to do this separately
|
150
|
+
changes = get_change_list(commit)
|
151
|
+
|
152
|
+
revision_and_date = Hook.shell!("git log #{commit} -1 --pretty='Revision: %h committed by %cn%nCommit date: %cd'") rescue ""
|
153
|
+
|
154
|
+
text = "#{revision_and_date}#{github_link}\n\n#{commit_message}\n{noformat}#{changes}{noformat}"
|
155
|
+
end
|
156
|
+
|
157
|
+
def check_one_commit(commit, commit_message)
|
158
|
+
STDERR.puts "Checking #{commit[0..6]} #{commit_message.lines.first}"
|
159
|
+
|
160
|
+
jira_tickets = commit_message.scan(JiraReferenceCheckHook::JIRA_TICKET_REGEXP).map(&:strip)
|
161
|
+
if jira_tickets.length == 0
|
162
|
+
STDERR.puts ">>Commit message must refer to a jira ticket"
|
163
|
+
add_error_to_report(commit, commit_message, "no_jira")
|
164
|
+
return false
|
165
|
+
end
|
166
|
+
|
167
|
+
# we know we have to add comments for at least one ticket
|
168
|
+
# so build up the options with more info about the commit.
|
169
|
+
# the comment will be the same in each ticket
|
170
|
+
|
171
|
+
comment_text = get_comment_content(commit, commit_message)
|
172
|
+
|
173
|
+
success = false
|
174
|
+
jira_tickets.each do |ticket|
|
175
|
+
valid_ticket = check_for_valid_ticket(ticket)
|
176
|
+
if valid_ticket
|
177
|
+
add_comment(ticket, comment_text)
|
178
|
+
success = true
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
unless success
|
183
|
+
STDERR.puts ">>Commit message must refer to a valid jira ticket"
|
184
|
+
add_error_to_report(commit, commit_message, "invalid_jira")
|
185
|
+
end
|
186
|
+
|
187
|
+
return success # did we find any valid tickets?
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
|
192
|
+
def add_comment(ticket, comment_text)
|
193
|
+
STDERR.puts "ADDING COMMENT for ticket #{ticket}"
|
194
|
+
uri = build_uri(ticket, "comment")
|
195
|
+
data = {"body" => comment_text}
|
196
|
+
|
197
|
+
STDERR.puts comment_text
|
198
|
+
|
199
|
+
if !@options["issues"] || @options["issues"].include?(ticket) # can limit to single issue until get the text right.
|
200
|
+
resp = RestClient.post(uri, data.to_json, :content_type => :json, :accept=>:json)
|
201
|
+
# hash = JSON.parse(resp)
|
202
|
+
# do we need to check anything about the response to see if it went ok?
|
203
|
+
# it will throw an error if ticket not found or something.
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def check_for_valid_ticket(ticket)
|
208
|
+
begin
|
209
|
+
|
210
|
+
uri = build_uri(ticket)
|
211
|
+
resp = RestClient.get uri
|
212
|
+
hash = JSON.parse(resp)
|
213
|
+
|
214
|
+
if @options["check_status"]
|
215
|
+
# Grab the Jira bug status, or fall back to allowing
|
216
|
+
# if the format is unexpected.
|
217
|
+
|
218
|
+
status = hash["fields"]["status"]["name"] rescue "open"
|
219
|
+
|
220
|
+
if status.downcase == "closed"
|
221
|
+
STDERR.puts "Issue #{ticket} is closed, not allowing."
|
222
|
+
return false
|
223
|
+
end
|
224
|
+
end
|
225
|
+
# The bug (probably) isn't closed (or we aren't checking),so we're valid!
|
226
|
+
return true
|
227
|
+
rescue SocketError
|
228
|
+
STDERR.puts "SocketError finding '#{@options["host"]}': #{$!.inspect}"
|
229
|
+
STDERR.puts "Is '#{@options["host"]}' the right Jira hostname? "
|
230
|
+
STDERR.puts "I'm allowing this in case you're offline, but make sure"
|
231
|
+
STDERR.puts "your hostname is right, please!"
|
232
|
+
return true
|
233
|
+
rescue RestClient::Exception
|
234
|
+
if $!.http_code == 401
|
235
|
+
STDERR.puts "You're not authorized on this server!"
|
236
|
+
STDERR.puts "Please set your username and password correctly."
|
237
|
+
return false
|
238
|
+
elsif $!.http_code == 404
|
239
|
+
# Nope, not a valid issue. Keep trying
|
240
|
+
elsif $!.http_code == 407
|
241
|
+
STDERR.puts "We don't support proxies to Jira yet!"
|
242
|
+
STDERR.puts "I'll give you the benefit of the doubt."
|
243
|
+
return true
|
244
|
+
elsif $!.http_code >= 500
|
245
|
+
STDERR.puts "Jira got a server error."
|
246
|
+
STDERR.puts "I'll give you the benefit of the doubt."
|
247
|
+
return true
|
248
|
+
else
|
249
|
+
STDERR.puts "Unexpected HTTP Error: #{$!.http_code}!"
|
250
|
+
return false
|
251
|
+
end
|
252
|
+
|
253
|
+
rescue
|
254
|
+
STDERR.puts "Unexpected exception: #{$!.inspect}!"
|
255
|
+
return false
|
256
|
+
end
|
257
|
+
false # if we get to this point it's not a valid ticket
|
258
|
+
end
|
259
|
+
|
260
|
+
def commit_list
|
261
|
+
# return the list of commits to display. We don't want to show them all
|
262
|
+
# (it looks scary when there's a lot)
|
263
|
+
# when there's only one, just return the commit
|
264
|
+
# when more than one return first_commit..last_commit
|
265
|
+
# use the shortened SHAH1 for readability
|
266
|
+
return "" if !self.commits || self.commits.empty?
|
267
|
+
|
268
|
+
if self.commits.size == 1
|
269
|
+
"#{self.commits.first[0..6]}"
|
270
|
+
else
|
271
|
+
"#{self.commits.last[0..6]}..#{self.commits.first[0..6]}"
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
|
276
|
+
def add_error_to_report(commit, msg, error_type = "no_jira")
|
277
|
+
# remember this error so we can report it later with others by this author
|
278
|
+
# store the string we'd like to print out about this commit (commit link and msg)
|
279
|
+
# to make it easier to print later
|
280
|
+
# (could store commit and message separately and process later if necessary)
|
281
|
+
# format:
|
282
|
+
# {"email1@test.com"" => {"no_jira" => ["www.github.com/commit/1234 invalid commit message",
|
283
|
+
# "www.github.com/commit/6789 also invalid"]
|
284
|
+
# "invalid_jira" => ["www.github.com/commit/1212 ABC-123 invalid commit message"]}
|
285
|
+
# "email2@test.com" => {...} }
|
286
|
+
|
287
|
+
|
288
|
+
author_email = Hook.shell!("git log #{commit} -1 --pretty='%aN <%aE>'").chomp rescue "no email"
|
289
|
+
|
290
|
+
errors_to_report[author_email] ||= {"no_jira" => [], "invalid_jira" => []} # in case first error for this author
|
291
|
+
errors_to_report[author_email][error_type] << "#{build_commit_uri(commit[0..7])}\n#{msg}"
|
292
|
+
end
|
293
|
+
|
294
|
+
def report_errors
|
295
|
+
# report any errors we have reported
|
296
|
+
require "pony" unless @options["no_send"] || @options["via"] == "no_send" # wait until we need it
|
297
|
+
# NOTE: Pony breaks on Windows so don't use this option in Windows.
|
298
|
+
errors_to_report.each do |email, details|
|
299
|
+
desc = build_message(details["no_jira"], details["invalid_jira"])
|
300
|
+
STDERR.puts "Warnings for commit from Jira Add Comment Check:\n--"
|
301
|
+
STDERR.puts "#{desc}\n--"
|
302
|
+
|
303
|
+
unless @options["no_send"] || @options["via"] == "no_send"
|
304
|
+
STDERR.puts "Sending warning email to #{email}"
|
305
|
+
ret = Pony.mail :to => email,
|
306
|
+
:from => @options["from"],
|
307
|
+
:subject => @options["subject"],
|
308
|
+
:body => desc,
|
309
|
+
:via => @options["via"],
|
310
|
+
:via_options => @options["via_options"]
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
# Build the email message.
|
316
|
+
# use the remote repo path for the name of the repo
|
317
|
+
# since this is always run as post_receive, there should always be a remote path.
|
318
|
+
|
319
|
+
def build_message(no_jira = [], invalid_jira= [])
|
320
|
+
description = @options["intro"] || ""
|
321
|
+
description.concat <<DESCRIPTION
|
322
|
+
This notice is to remind you that you need to include valid Jira ticket
|
323
|
+
numbers in all of your Git commits!
|
324
|
+
|
325
|
+
We encountered the following problems in your recent commits.
|
326
|
+
|
327
|
+
DESCRIPTION
|
328
|
+
if no_jira.size > 0
|
329
|
+
description.concat <<DESCRIPTION
|
330
|
+
Commits with no reference to any jira tickets:
|
331
|
+
|
332
|
+
#{no_jira.join("\n--\n ")}
|
333
|
+
-----
|
334
|
+
DESCRIPTION
|
335
|
+
end
|
336
|
+
|
337
|
+
if invalid_jira.size > 0
|
338
|
+
description.concat <<DESCRIPTION
|
339
|
+
Commits which reference invalid Jira ticket numbers
|
340
|
+
that don't exist or have already been closed:
|
341
|
+
|
342
|
+
#{invalid_jira.join("\n--\n ")}
|
343
|
+
-----
|
344
|
+
DESCRIPTION
|
345
|
+
end
|
346
|
+
|
347
|
+
description.concat @options["conclusion"] if @options["conclusion"]
|
348
|
+
|
349
|
+
description
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
|
354
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright (C) 2013 OL2, Inc. See LICENSE.txt for details.
|
2
|
+
|
3
|
+
require "ruby_git_hooks"
|
4
|
+
|
5
|
+
# This hook checks that the commit message has one or more correctly-formatted
|
6
|
+
# Jira ticket references.
|
7
|
+
|
8
|
+
class JiraReferenceCheckHook < RubyGitHooks::Hook
|
9
|
+
Hook = RubyGitHooks::Hook
|
10
|
+
|
11
|
+
JIRA_TICKET_REGEXP = /(?<=\W|^)[A-Z]{2,10}-\d{1,6}(?=\W|$)/
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
# not using options now, but leave this here for backwards compatibility
|
15
|
+
end
|
16
|
+
|
17
|
+
def check
|
18
|
+
if !commit_message || commit_message.length == 0
|
19
|
+
STDERR.puts "Commit message is missing or empty!"
|
20
|
+
return false
|
21
|
+
end
|
22
|
+
|
23
|
+
jira_tickets = commit_message.scan(JIRA_TICKET_REGEXP).map(&:strip)
|
24
|
+
if jira_tickets.length == 0
|
25
|
+
STDERR.puts "Commit message must refer to a jira ticket"
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
|
29
|
+
return true
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright (C) 2013 OL2, Inc. See LICENSE.txt for details.
|
2
|
+
|
3
|
+
require "ruby_git_hooks"
|
4
|
+
|
5
|
+
# This hook checks the size of each individual file against a
|
6
|
+
# configurable maximum size. Once a huge file is in your git history
|
7
|
+
# it can't be fully removed without rewriting history, so you're
|
8
|
+
# usually better off preventing them in the first place.
|
9
|
+
|
10
|
+
class MaxFileSizeHook < RubyGitHooks::Hook
|
11
|
+
DEFAULT_MAX_FILE_SIZE = 10*1024*1024;
|
12
|
+
VERBOSE = false
|
13
|
+
|
14
|
+
def initialize(max_size = DEFAULT_MAX_FILE_SIZE)
|
15
|
+
@max_file_size = max_size
|
16
|
+
end
|
17
|
+
|
18
|
+
def check
|
19
|
+
STDERR.puts "Checking, max file size: #{@max_file_size}" if VERBOSE
|
20
|
+
okay = true
|
21
|
+
file_contents.each do |name, file|
|
22
|
+
STDERR.puts "File length: #{file.length}" if VERBOSE
|
23
|
+
if file.length > @max_file_size
|
24
|
+
okay = false
|
25
|
+
STDERR.puts "File #{name} exceeds maximum allowed size!"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
okay
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Copyright (C) 2013 OL2, Inc. See LICENSE.txt for details.
|
2
|
+
|
3
|
+
require "ruby_git_hooks"
|
4
|
+
|
5
|
+
# This hook checks that commit message contains only ASCII characters.
|
6
|
+
|
7
|
+
class NonAsciiCharactersCheckHook < RubyGitHooks::Hook
|
8
|
+
Hook = RubyGitHooks::Hook
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
end
|
12
|
+
|
13
|
+
def check
|
14
|
+
if !commit_message || commit_message.length == 0
|
15
|
+
STDERR.puts "Commit message is missing or empty!"
|
16
|
+
return false
|
17
|
+
end
|
18
|
+
|
19
|
+
# Brute force approach. I didn't find any clever way to check for non-ascii
|
20
|
+
# using string encoder tricks
|
21
|
+
count = 0
|
22
|
+
valid_control_chars = [13, 10, 9]
|
23
|
+
commit_message.each_byte do |b|
|
24
|
+
if b > 127 || (b < 32 && !valid_control_chars.include?(b))
|
25
|
+
count = count + 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
if count > 0
|
29
|
+
STDERR.puts "Commit message has #{count} non-ASCII characters"
|
30
|
+
end
|
31
|
+
return count == 0 ? true : false
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Copyright (C) 2013 OL2, Inc. See LICENSE.txt for details.
|
2
|
+
|
3
|
+
require "ruby_git_hooks"
|
4
|
+
|
5
|
+
# This hook looks for source files that include ruby-debug and fails
|
6
|
+
# if any do. It exists primarily for testing. It's functional, but
|
7
|
+
# not necessarily useful.
|
8
|
+
|
9
|
+
class RubyDebugHook < RubyGitHooks::Hook
|
10
|
+
def check
|
11
|
+
bad_files = []
|
12
|
+
|
13
|
+
file_diffs.each do |file, diff|
|
14
|
+
if diff.include? "require 'ruby-debug'"
|
15
|
+
bad_files << file
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
return true if bad_files.empty?
|
20
|
+
|
21
|
+
puts "You left requires of ruby-debug in the following files:\n"
|
22
|
+
puts bad_files.join("\n")
|
23
|
+
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright (C) 2013 OL2, Inc. See LICENSE.txt for details.
|
2
|
+
|
3
|
+
require "ruby_git_hooks"
|
4
|
+
|
5
|
+
# This hook adds a watermark to the end of commit message so that we
|
6
|
+
# know the hooks have been run. It should be run as the last
|
7
|
+
# commit-msg hook so it changes the message immediately before the
|
8
|
+
# commit is accepted and other hooks can't remove the watermark
|
9
|
+
# afterward.
|
10
|
+
|
11
|
+
class AddWatermarkCommitHook < RubyGitHooks::Hook
|
12
|
+
|
13
|
+
def initialize(mark = "\u00a0")
|
14
|
+
@watermark = mark
|
15
|
+
end
|
16
|
+
|
17
|
+
def check
|
18
|
+
if !commit_message_file
|
19
|
+
STDERR.puts "Warning: Watermark hook must be run as commit-msg only"
|
20
|
+
return true # don't actually cause commit to fail
|
21
|
+
end
|
22
|
+
|
23
|
+
File.open(commit_message_file, 'a') {|f| f.write(@watermark)}
|
24
|
+
return true
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|