CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/tools/dev/pre-commit-hook.rb
Views: 1904
1
#!/usr/bin/env ruby
2
3
require "open3"
4
5
#
6
# Check that modules actually pass msftidy checks before committing
7
# or after merging.
8
#
9
# Simply symlink this script to your local .git/hooks/pre-commit script
10
# and your .git/hooks/post-merge scripts. Note the lack of a trailing
11
# .rb
12
#
13
# If you are in the top-level dir, the symlink commands would be:
14
#
15
# ln -sf ../../tools/dev/pre-commit-hook.rb .git/hooks/pre-commit
16
# ln -sf ../../tools/dev/pre-commit-hook.rb .git/hooks/post-merge
17
#
18
# That way, you will track changes to this script when it updates
19
# (rarely). If you'd prefer to copy it directly, that's okay, too (mark
20
# it +x and don't name it filename.rb, just filename).
21
#
22
23
def run(command, exception: true)
24
puts command
25
stdout, status = ::Open3.capture2(command)
26
if !status.success? && exception
27
raise "Command failed with status (#{status.exitstatus}): #{command}"
28
end
29
30
stdout
31
end
32
33
def merge_error_message
34
msg = []
35
msg << "[*] This merge contains modules failing msftidy.rb"
36
msg << "[*] Please fix this if you intend to publish these"
37
msg << "[*] modules to a popular metasploit-framework repo"
38
puts "-" * 72
39
puts msg.join("\n")
40
puts "-" * 72
41
end
42
43
valid = true # Presume validity
44
files_to_check = []
45
46
# Who called us? If it's a post-merge check things operate a little
47
# differently.
48
puts "[*] Running msftidy.rb in #{$0} mode"
49
50
case $0
51
when /post-merge/
52
base_caller = :post_merge
53
when /pre-commit/
54
base_caller = :pre_commit
55
else
56
base_caller = :msftidy
57
end
58
59
if base_caller == :post_merge
60
changed_files = run('git diff --name-only HEAD^ HEAD')
61
else
62
changed_files = run('git diff --cached --name-only')
63
end
64
65
changed_files.each_line do |fname|
66
fname.strip!
67
next unless File.exist?(fname)
68
next unless File.file?(fname)
69
next unless fname =~ /^modules.+\.rb/
70
files_to_check << fname
71
end
72
73
if files_to_check.empty?
74
puts "--- No Metasploit modules to check ---"
75
else
76
puts "--- Checking new and changed module syntax with tools/dev/msftidy.rb ---"
77
files_to_check.each do |fname|
78
command = "bundle exec ruby ./tools/dev/msftidy.rb #{fname}"
79
msftidy_output, status = ::Open3.capture2(command)
80
valid = false unless status.success?
81
puts "#{fname} - msftidy check passed" if msftidy_output.empty?
82
msftidy_output.each_line do |line|
83
puts line
84
end
85
end
86
puts "-" * 72
87
end
88
89
unless valid
90
if base_caller == :post_merge
91
puts merge_error_message
92
exit(0x10)
93
else
94
puts "[!] msftidy.rb objected, aborting commit"
95
puts "[!] To bypass this check use: git commit --no-verify"
96
puts "-" * 72
97
exit(0x01)
98
end
99
100
end
101
102