Class: GitHooksHelper::Hook

Inherits:
Object
  • Object
show all
Defined in:
lib/git-hooks-helper/hook.rb

Constant Summary collapse

RB_REGEXP =
/\.(rb|rake|task|prawn|[Rr]akefile|task)\z/.freeze
ERB_REGEXP =
/\.erb\z/.freeze
JS_REGEXP =
/\.js\z/.freeze
HAML_REGEXP =
/\.haml\z/.freeze
COFFEE_REGEXP =
/\.coffee\z/.freeze
SLIM_REGEXP =
/\.slim\z/.freeze
FILETYPES =
{
  rb:     RB_REGEXP,
  erb:    ERB_REGEXP,
  js:     JS_REGEXP,
  haml:   HAML_REGEXP,
  coffee: COFFEE_REGEXP,
  slim:   SLIM_REGEXP
}.freeze
RB_WARNING_REGEXP =
/[0-9]+:\s+warning:/.freeze
HAML_INVALID_REGEXP =
/error/.freeze
ERB_INVALID_REGEXP =
/invalid\z/.freeze
SLIM_INVALID_REGEXP =
/invalid1\z/.freeze
COLOR_REGEXP =
/\e\[(\d+)m/.freeze

Instance Method Summary collapse

Constructor Details

#initialize(&block) ⇒ Hook

Set this to true if you want warnings to stop your commit



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/git-hooks-helper/hook.rb', line 34

def initialize(&block)
  @ruby = GitHooksHelper::Ruby.new
  @debug = false

  @result = GitHooksHelper::Result.new(false)
  @changed_files = GitHooksHelper::Git.in_index
  debug("changed files")
  debug @changed_files
  instance_eval(&block) if block

  if @result.errors?
    status = 1
    puts "ERRORS:".red
    puts @result.errors.join("\n")
    puts "--------\n".red
  end

  if @result.warnings?
    if @result.stop_on_warnings
      puts "WARNINGS:".yellow
    else
      puts "Warnings:".yellow
    end
    puts @result.warnings.join("\n")
    puts "--------\n".yellow
  end

  if @result.perfect_commit?
    puts "Perfect commit!".green
  end

  if @result.continue?
    # all good
    puts("COMMIT OK:".green)
    exit 0
  else
    puts("COMMIT FAILED".red)
    exit 1
  end
end

Instance Method Details

#changed_files(filetypes = [:all]) ⇒ Object



115
116
117
118
# File 'lib/git-hooks-helper/hook.rb', line 115

def changed_files(filetypes = [:all])
  filetypes = Array(filetypes)
   @changed_files.select{ |file| file_matches_filetypes?(file, filetypes) and File.readable?(file) }
end

#check_best_practicesObject



176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/git-hooks-helper/hook.rb', line 176

def check_best_practices
  Open3.popen3("pwd") do |stdin, stdout, stderr|
    puts stdout.read
  end
  each_changed_file([:rb, :erb, :haml]) do |file|
    Open3.popen3("rails_best_practices --spec --test #{file}") do |stdin, stdout, stderr|
      @result.warn(stdout.read.split("\n").map do |line|
        if line =~ /#{file}/
          line.gsub(COLOR_REGEXP, '').strip
        end
      end.compact)
    end
  end
end

#check_erbObject



136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/git-hooks-helper/hook.rb', line 136

def check_erb
  each_changed_file([:erb]) do |file|
    Open3.popen3("rails-erb-check #{file}") do |stdin, stdout, stderr|
      lines = stdout.read.split("\n")
      errors = lines.map do |line|
        if line.gsub(COLOR_REGEXP, '') =~ ERB_INVALID_REGEXP
          "#{file} => invalid ERB syntax"
        end
      end.compact
      @result.errors.concat errors
    end
  end
end

#check_hamlObject



162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/git-hooks-helper/hook.rb', line 162

def check_haml
  each_changed_file([:haml]) do |file|
    Open3.popen3("haml --check #{file}") do |stdin, stdout, stderr|
      lines = stderr.read.split("\n")
      errors = lines.map do |line|
        if line.gsub(COLOR_REGEXP, '') =~ HAML_INVALID_REGEXP
          "#{file} => invalid HAML syntax\n  #{line}"
        end
      end.compact
      @result.errors.concat errors
    end
  end
end

#check_ruby_syntaxObject



126
127
128
129
130
131
132
133
134
# File 'lib/git-hooks-helper/hook.rb', line 126

def check_ruby_syntax
  each_changed_file([:rb]) do |file|
    Open3.popen3(GitHooksHelper::Ruby.check_syntax(file)) do |stdin, stdout, stderr|
      stderr.read.split("\n").each do |line|
        line =~ RB_WARNING_REGEXP ? @result.warnings << line : @result.errors << line
      end
    end
  end
end

#check_slimObject



150
151
152
153
154
155
156
157
158
159
160
# File 'lib/git-hooks-helper/hook.rb', line 150

def check_slim
  each_changed_file([:slim]) do |file|
    Open3.popen3("slimrb -c #{file}") do |stdin, stdout, stderr|
      lines = stderr.read.split("\n")
      errors = if lines.size > 0
        # skip last 2 lines from output. There is only trace info.
        @result.errors << "#{file} => invalid SLIM syntax\n  " + lines[0..-3].join("\n  ")
      end
    end
  end
end

#debug(msg) ⇒ Object



238
239
240
# File 'lib/git-hooks-helper/hook.rb', line 238

def debug(msg)
  puts msg if @debug
end

#do_not_stop_on_warningsObject



87
88
89
# File 'lib/git-hooks-helper/hook.rb', line 87

def do_not_stop_on_warnings
  @result.stop_on_warnings = false
end

#each_changed_file(filetypes = [:all]) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/git-hooks-helper/hook.rb', line 103

def each_changed_file(filetypes = [:all])
  filetypes = Array(filetypes)
  if @result.continue?
    debug("Can continue")
    changed_files(filetypes).each do |file|
      yield file
    end
  else
    debug("Cannot continue")
  end
end

#file_matches_filetypes?(file, filetypes) ⇒ Boolean

Returns:

  • (Boolean)


120
121
122
123
124
# File 'lib/git-hooks-helper/hook.rb', line 120

def file_matches_filetypes?(file, filetypes)
  filetypes.any? do |type|
    file =~ FILETYPES[type] || type == :all
  end
end

#flog_methods(threshold = 20) ⇒ Object



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/git-hooks-helper/hook.rb', line 191

def flog_methods(threshold = 20)
  files = changed_files(:rb).join(' ')
  if files != ''
    Open3.popen3("flog -m #{files}") do |stdin, stdout, stderr|
      punishment = stdout.read.split("\n")[3..-1]
      punishment.each do |line|
        line   = line.split(" ")
        score  = line[0].to_f
        method = line[1].strip
        path   = line[2].strip
        if score >= threshold
          @result.warn("Flog for #{method} in #{path} returned #{score}")
        else
          break
        end
      end
    end
  end
end

#info(text) ⇒ Object



226
227
228
# File 'lib/git-hooks-helper/hook.rb', line 226

def info(text)
  puts(text.green)
end

#list_files(filetypes = [:all]) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/git-hooks-helper/hook.rb', line 95

def list_files(filetypes = [:all])
  puts "--- Listing files of type: #{filetypes}"
  each_changed_file(filetypes) do |file|
    puts file
  end
  puts "--- End of list"
end

#never_stopObject



91
92
93
# File 'lib/git-hooks-helper/hook.rb', line 91

def never_stop
  @result.never_stop = true
end

#notice(text) ⇒ Object



230
231
232
# File 'lib/git-hooks-helper/hook.rb', line 230

def notice(text)
  puts(text.yellow)
end

#start_debugObject



75
76
77
# File 'lib/git-hooks-helper/hook.rb', line 75

def start_debug
  @debug = true
end

#stop_debugObject



79
80
81
# File 'lib/git-hooks-helper/hook.rb', line 79

def stop_debug
  @debug = false
end

#stop_on_warningsObject



83
84
85
# File 'lib/git-hooks-helper/hook.rb', line 83

def stop_on_warnings
  @result.stop_on_warnings = true
end

#warn(text) ⇒ Object



234
235
236
# File 'lib/git-hooks-helper/hook.rb', line 234

def warn(text)
  puts(text.red)
end

#warning_on(*args) ⇒ Object

Maybe need options for different file types :rb :erb :js



212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/git-hooks-helper/hook.rb', line 212

def warning_on(*args)
  options = (args[-1].kind_of?(Hash) ? args.pop : {})
  each_changed_file(options[:in] || [:all]) do |file|
    Open3.popen3("fgrep -nH \"#{args.join("\n")}\" #{file}") do |stdin, stdout, stderr|
      err = stdout.read
      err.split("\n").each do |msg|
        args.each do |string|
          @result.warn("#{msg.split(" ").first} contains #{string}") if msg =~ /#{string}/
        end
      end
    end
  end
end