Skip to content

Commit 79f82be

Browse files
committed
Land rapid7#3188, deluxe msftidy post-merge hook
2 parents e0966f7 + e1071eb commit 79f82be

File tree

3 files changed

+62
-44
lines changed

3 files changed

+62
-44
lines changed

.travis.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
language: ruby
2-
env: MSF_SPOTCHECK_RECENT=1
32
before_install:
43
- rake --version
54
- sudo apt-get update -qq
65
- sudo apt-get install -qq libpcap-dev
6+
- ln -sf ../../tools/dev/pre-commit-hook.rb ./.git/hooks/post-merge
7+
- ls -la ./.git/hooks
8+
- ./.git/hooks/post-merge
79
before_script:
8-
- ./tools/msftidy.rb
910
- cp config/database.yml.travis config/database.yml
1011
- bundle exec rake --version
1112
- bundle exec rake db:create

tools/dev/pre-commit-hook.rb

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,64 @@
11
#!/usr/bin/env ruby
22

3-
# Check that modules actually pass msftidy checks first.
4-
# To install this script, make this your pre-commit hook your local
5-
# metasploit-framework clone. For example, if you have checked out
6-
# the Metasploit Framework to:
3+
# Check that modules actually pass msftidy checks before committing
4+
# or after merging.
75
#
8-
# /home/mcfakepants/git/metasploit-framework
6+
# Simply symlink this script to your local .git/hooks/pre-commit script
7+
# and your .git/hooks/post-merge scripts. Note the lack of a trailing
8+
# .rb
99
#
10-
# then you will copy this script to:
10+
# If you are in the top-level dir, the symlink commands would be:
1111
#
12-
# /home/mcfakepants/git/metasploit-framework/.git/hooks/pre-commit
12+
# ln -sf ../../tools/dev/pre-commit-hook.rb .git/hooks/pre-commit
13+
# ln -sf ../../tools/dev/pre-commit-hook.rb .git/hooks/post-merge
1314
#
14-
# You must mark it executable (chmod +x), and do not name it
15-
# pre-commit.rb (just pre-commit)
16-
#
17-
# If you want to keep up on changes with this hook, just:
18-
#
19-
# ln -sf <this file> <path to commit hook>
15+
# That way, you will track changes to this script when it updates
16+
# (rarely). If you'd prefer to copy it directly, that's okay, too (mark
17+
# it +x and don't name it filename.rb, just filename).
18+
19+
def merge_error_message
20+
msg = []
21+
msg << "[*] This merge contains modules failing msftidy.rb"
22+
msg << "[*] Please fix this if you intend to publish these"
23+
msg << "[*] modules to a popular metasploit-framework repo"
24+
puts "-" * 72
25+
puts msg.join("\n")
26+
puts "-" * 72
27+
end
2028

2129
valid = true # Presume validity
2230
files_to_check = []
2331

24-
results = %x[git diff --cached --name-only]
32+
# Who called us? If it's a post-merge check things operate a little
33+
# differently.
34+
puts "[*] Running msftidy.rb in #{$0} mode"
35+
36+
case $0
37+
when /post-merge/
38+
base_caller = :post_merge
39+
when /pre-commit/
40+
base_caller = :pre_commit
41+
else
42+
base_caller = :msftidy
43+
end
44+
45+
if base_caller == :post_merge
46+
changed_files = %x[git diff --name-only HEAD^ HEAD]
47+
else
48+
changed_files = %x[git diff --cached --name-only]
49+
end
2550

26-
results.each_line do |fname|
51+
changed_files.each_line do |fname|
2752
fname.strip!
2853
next unless File.exist?(fname) and File.file?(fname)
2954
next unless fname =~ /modules.+\.rb/
3055
files_to_check << fname
3156
end
3257

3358
if files_to_check.empty?
34-
puts "--- No Metasploit modules to check, committing. ---"
59+
puts "--- No Metasploit modules to check ---"
3560
else
36-
puts "--- Checking module syntax with tools/msftidy.rb ---"
61+
puts "--- Checking new and changed module syntax with tools/msftidy.rb ---"
3762
files_to_check.each do |fname|
3863
cmd = "ruby ./tools/msftidy.rb #{fname}"
3964
msftidy_output= %x[ #{cmd} ]
@@ -43,12 +68,18 @@
4368
puts line
4469
end
4570
end
46-
puts "-" * 52
71+
puts "-" * 72
4772
end
4873

4974
unless valid
50-
puts "msftidy.rb objected, aborting commit"
51-
puts "To bypass this check use: git commit --no-verify"
52-
puts "-" * 52
53-
exit(1)
75+
if base_caller == :post_merge
76+
puts merge_error_message
77+
exit(0x10)
78+
else
79+
puts "[!] msftidy.rb objected, aborting commit"
80+
puts "[!] To bypass this check use: git commit --no-verify"
81+
puts "-" * 72
82+
exit(0x01)
83+
end
84+
5485
end

tools/msftidy.rb

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44
# Check (recursively) for style compliance violations and other
55
# tree inconsistencies.
66
#
7-
# by jduck and friends
7+
# by jduck, todb, and friends
88
#
99
require 'fileutils'
1010
require 'find'
1111
require 'time'
1212

1313
CHECK_OLD_RUBIES = !!ENV['MSF_CHECK_OLD_RUBIES']
14-
SPOTCHECK_RECENT = !!ENV['MSF_SPOTCHECK_RECENT']
1514

1615
if CHECK_OLD_RUBIES
1716
require 'rvm'
@@ -549,25 +548,12 @@ def run_checks(full_filepath)
549548

550549
dirs = ARGV
551550

552-
if SPOTCHECK_RECENT
553-
msfbase = %x{\\git rev-parse --show-toplevel}.strip
554-
if File.directory? msfbase
555-
Dir.chdir(msfbase)
556-
else
557-
$stderr.puts "You need a git binary in your path to use this functionality."
558-
exit(0x02)
559-
end
560-
last_release = %x{\\git tag -l #{DateTime.now.year}\\*}.split.last
561-
new_modules = %x{\\git diff #{last_release}..HEAD --name-only --diff-filter A modules}
562-
dirs = dirs | new_modules.split
563-
end
551+
@exit_status = 0
564552

565-
# Don't print an error if there's really nothing to check.
566-
unless SPOTCHECK_RECENT
567-
if dirs.length < 1
568-
$stderr.puts "Usage: #{File.basename(__FILE__)} <directory or file>"
569-
exit(0x01)
570-
end
553+
if dirs.length < 1
554+
$stderr.puts "Usage: #{File.basename(__FILE__)} <directory or file>"
555+
@exit_status = 1
556+
exit(@exit_status)
571557
end
572558

573559
dirs.each do |dir|

0 commit comments

Comments
 (0)