Class: Pronto::Flay

Inherits:
Runner
  • Object
show all
Defined in:
lib/pronto/flay.rb

Constant Summary collapse

DEFAULT_SEVERITY_LEVELS =
{
  identical: :error,
  similar: :warning,
}.freeze

Instance Method Summary collapse

Instance Method Details

#custom_severity_levels_configObject



74
75
76
# File 'lib/pronto/flay.rb', line 74

def custom_severity_levels_config
  Pronto::ConfigFile.new.to_h.dig('flay', 'severity_levels') || {}
end

#filesObject



32
33
34
# File 'lib/pronto/flay.rb', line 32

def files
  @files ||= ruby_patches.map(&:new_file_full_path)
end

#flayObject

The current Flay (2.8.0) takes care of filtering files by looking at .flayignore. Saving the returned Flay object at @flay so we can inspect it and build the messages Array.



24
25
26
# File 'lib/pronto/flay.rb', line 24

def flay
  @flay ||= ::Flay.run(params)
end

#level(hash) ⇒ Object



60
61
62
# File 'lib/pronto/flay.rb', line 60

def level(hash)
  same?(hash) ? severity_levels_config[:identical] : severity_levels_config[:similar]
end

#mass_thresholdObject



103
104
105
# File 'lib/pronto/flay.rb', line 103

def mass_threshold
  @mass_threshold ||= ENV['PRONTO_FLAY_MASS_THRESHOLD'] || Pronto::ConfigFile.new.to_h.dig('flay', 'mass_threshold') || ::Flay.default_options[:mass].to_s
end

#massesObject



99
100
101
# File 'lib/pronto/flay.rb', line 99

def masses
  flay.masses
end

#message(hash) ⇒ Object



78
79
80
81
82
83
84
85
# File 'lib/pronto/flay.rb', line 78

def message(hash)
  match = same?(hash) ? 'Identical' : 'Similar'
  location = nodes_for(hash).map do |node|
    "#{File.basename(node.file)}:#{node.line}"
  end

  "#{match} code found in #{location.join(', ')} (mass = #{masses[hash]})"
end

#messagesObject



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/pronto/flay.rb', line 36

def messages
  nodes.map do |node|
    patch = patch_for_node(node)

    line = patch.added_lines.find do |added_line|
      added_line.new_lineno == node.line
    end

    new_message(line, node) if line
  end.flatten.compact
end

#new_message(line, node) ⇒ Object



54
55
56
57
58
# File 'lib/pronto/flay.rb', line 54

def new_message(line, node)
  path = line.patch.delta.new_file[:path]
  hash = node.structural_hash
  Message.new(path, line, level(hash), message(hash), nil, self.class)
end

#nodesObject



91
92
93
94
95
96
97
# File 'lib/pronto/flay.rb', line 91

def nodes
  result = []
  masses.keys.each do |hash|
    nodes_for(hash).each { |node| result << node }
  end
  result
end

#nodes_for(hash) ⇒ Object



87
88
89
# File 'lib/pronto/flay.rb', line 87

def nodes_for(hash)
  flay.hashes[hash]
end

#paramsObject



28
29
30
# File 'lib/pronto/flay.rb', line 28

def params
  [*files, '-m', mass_threshold]
end

#patch_for_node(node) ⇒ Object



48
49
50
51
52
# File 'lib/pronto/flay.rb', line 48

def patch_for_node(node)
  ruby_patches.find do |patch|
    patch.new_file_full_path == node.file
  end
end

#runObject



11
12
13
14
15
16
17
18
# File 'lib/pronto/flay.rb', line 11

def run
  if files.any?
    flay.analyze
    messages
  else
    []
  end
end

#same?(hash) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/pronto/flay.rb', line 64

def same?(hash)
  flay.identical[hash]
end

#severity_levels_configObject



68
69
70
71
72
# File 'lib/pronto/flay.rb', line 68

def severity_levels_config
  @severity_levels_config ||= DEFAULT_SEVERITY_LEVELS.merge(custom_severity_levels_config)
    .map { |k, v| [k.to_sym, v.to_sym] }
    .to_h
end