Class: Xlint

Inherits:
Object
  • Object
show all
Defined in:
lib/xlint.rb,
lib/xlint/version.rb

Constant Summary collapse

VERSION =
'0.0.6'.freeze

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.commentsObject

Returns the value of attribute comments.



10
11
12
# File 'lib/xlint.rb', line 10

def comments
  @comments
end

.diff_fileObject

Returns the value of attribute diff_file.



10
11
12
# File 'lib/xlint.rb', line 10

def diff_file
  @diff_file
end

.draftObject

Returns the value of attribute draft.



10
11
12
# File 'lib/xlint.rb', line 10

def draft
  @draft
end

Class Method Details

.build_draftObject



30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/xlint.rb', line 30

def build_draft
  @comments = []
  # GitDiffParser::Patches.parse(cp932 text) raises ArgumentError: invalid byte sequence in UTF-8
  # https://github.com/packsaddle/ruby-git_diff_parser/issues/91
  diff_data = File.read(diff_file)
  diff_data.encode!('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
  diff = Xlint.parse_git(diff_data)
  diff.files.each do |file|
    patch = diff.find_patch_by_file(file)
    changes = Xlint.patch_body_changes(patch.body, file)
    @comments.concat(Xlint.find_offenses(changes))
  end
end

.build_labelObject



51
52
53
54
55
56
57
# File 'lib/xlint.rb', line 51

def build_label
  return unless ENV['GERGICH_REVIEW_LABEL']
  score = comments.empty? ? 1 : -1
  message = comments.empty? ? 'Xlint didn\'t find anything to complain about' : 'Xlint is worried about your commit'
  draft.add_message(message)
  draft.add_label(ENV['GERGICH_REVIEW_LABEL'], score)
end

.check_argsObject

Raises:

  • (ArgumentError)


18
19
20
21
22
23
# File 'lib/xlint.rb', line 18

def check_args
  # reads git diff from file, file name in ARGV[0]
  raise ArgumentError, 'usage: xlint path/to/some.diff' unless ARGV.size == 1
  @diff_file = ARGV.first
  raise "File does not exist: #{diff_file}" unless File.exist?(diff_file)
end

.check_deployment_target(change) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/xlint.rb', line 109

def check_deployment_target(change)
  offenses = []
  if change[:file] =~ /(.pbxproj)/ && change[:line] =~ /(DEPLOYMENT_TARGET =)/
    offense = {
      path: change[:file],
      position: change[:line_number],
      message: 'Deployment target changes should be approved by the team lead.',
      severity: 'error'
    }
    offenses.push(offense)
  end
  offenses
end

.check_envObject



25
26
27
28
# File 'lib/xlint.rb', line 25

def check_env
  raise 'ENV[GERGICH_KEY] not defined' unless ENV['GERGICH_KEY']
  raise 'ENV[GERRIT_PROJECT] not defined' unless ENV['GERRIT_PROJECT']
end

.clearObject



12
13
14
15
16
# File 'lib/xlint.rb', line 12

def clear
  @diff_file = nil
  @draft.reset! if draft
  @comments = []
end

.find_offenses(changes) ⇒ Object

only checks for deployment target changes, we can add more rules in the future here



100
101
102
103
104
105
106
107
# File 'lib/xlint.rb', line 100

def find_offenses(changes)
  offenses = []
  changes.each do |change|
    warnings = check_deployment_target(change)
    offenses.concat(warnings) unless warnings.empty?
  end
  offenses
end

.parse_git(diff) ⇒ Object



72
73
74
# File 'lib/xlint.rb', line 72

def parse_git(diff)
  GitDiffParser::Patches.parse(diff)
end

.patch_body_changes(body, file) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/xlint.rb', line 76

def patch_body_changes(body, file)
  result = []
  line_number = 0
  body.split("\n").each do |line|
    if valid_git_header?(line)
      line_number = starting_line_number(line)
      next
    end
    next if line.start_with?('-')
    result.push(file: file, line: line, line_number: line_number) if line.start_with?('+')
    line_number += 1
  end
  result
end

.publishObject



63
64
65
66
67
68
69
70
# File 'lib/xlint.rb', line 63

def publish
  check_args
  check_env
  build_draft
  save_draft
  build_label
  publish_draft
end

.publish_draftObject



59
60
61
# File 'lib/xlint.rb', line 59

def publish_draft
  Gergich::Review.new.publish!
end

.save_draftObject



44
45
46
47
48
49
# File 'lib/xlint.rb', line 44

def save_draft
  @draft = Gergich::Draft.new
  comments.each do |comment|
    draft.add_comment(comment[:path], comment[:position], comment[:message], comment[:severity])
  end
end

.starting_line_number(header) ⇒ Object

expects git header in the form of: @@ -215,13 +215,7 @@



92
93
94
95
96
# File 'lib/xlint.rb', line 92

def starting_line_number(header)
  str = header.split(' ')[2].split(',')[0]
  str.slice!('-')
  str.to_i
end

.valid_git_header?(line) ⇒ Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/xlint.rb', line 123

def valid_git_header?(line)
  line =~ /^(@{2})\s([-]{1}[0-9]*(,[0-9]*)?)\s([+][0-9]*(,[0-9]*)?)\s(@{2})$/
end