class Gitlab::Dangerfiles::CommitLinter

Constants

MAX_CHANGED_FILES_IN_COMMIT
MAX_CHANGED_LINES_IN_COMMIT
MS_SHORT_REFERENCE_REGEX

Milestone

SHORT_REFERENCE_REGEX

Issue, MR, Epic

SUGGESTIONS_APPLIED_COMMIT_REGEX

Public Class Methods

new(commit) click to toggle source
Calls superclass method Gitlab::Dangerfiles::BaseLinter::new
# File lib/gitlab/dangerfiles/commit_linter.rb, line 34
def initialize(commit)
  super

  @linted = false
end
problems_mapping() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 17
def self.problems_mapping
  super.merge(
    {
      separator_missing: "The commit subject and body must be separated by a blank line",
      details_too_many_changes: "Commits that change #{MAX_CHANGED_LINES_IN_COMMIT} or more lines across " \
      "at least #{MAX_CHANGED_FILES_IN_COMMIT} files should describe these changes in the commit body",
      details_line_too_long: "The commit body should not contain more than #{MAX_LINE_LENGTH} characters per line",
      message_contains_text_emoji: "Avoid the use of Markdown Emoji such as `:+1:`. These add limited value " \
      "to the commit message, and are displayed as plain text outside of GitLab",
      message_contains_unicode_emoji: "Avoid the use of Unicode Emoji. These add no value to the commit " \
      "message, and may not be displayed properly everywhere",
      message_contains_short_reference: "Use full URLs instead of short references (`gitlab-org/gitlab#123` or " \
      "`!123`), as short references are displayed as plain text outside of GitLab",
    }
  )
end

Public Instance Methods

fixup?() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 40
def fixup?
  commit.message.start_with?("fixup!", "squash!")
end
lint() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 60
def lint
  return self if @linted

  @linted = true
  lint_subject
  lint_separator
  lint_details
  lint_message

  self
end
merge?() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 48
def merge?
  commit.message.start_with?("Merge branch")
end
multi_line?() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 56
def multi_line?
  !details.nil? && !details.empty?
end
revert?() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 52
def revert?
  commit.message.start_with?('Revert "')
end
suggestion?() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 44
def suggestion?
  SUGGESTIONS_APPLIED_COMMIT_REGEX.match?(commit.message)
end

Private Instance Methods

details() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 133
def details
  message_parts[2]&.gsub(/^Signed-off-by.*$/, "")
end
emoji_checker() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 150
def emoji_checker
  @emoji_checker ||= Gitlab::Dangerfiles::EmojiChecker.new
end
files_changed() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 117
def files_changed
  commit.diff_parent.stats[:total][:files]
end
lines_changed() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 121
def lines_changed
  commit.diff_parent.stats[:total][:lines]
end
lint_details() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 82
def lint_details
  if !multi_line? && many_changes?
    add_problem(:details_too_many_changes)
  end

  details&.each_line do |line|
    line_without_urls = line.strip.gsub(%r{https?://\S+}, "")

    # If the line includes a URL, we'll allow it to exceed MAX_LINE_LENGTH characters, but
    # only if the line _without_ the URL does not exceed this limit.
    next unless line_too_long?(line_without_urls)

    add_problem(:details_line_too_long)
    break
  end

  self
end
lint_message() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 101
def lint_message
  if message_contains_text_emoji?
    add_problem(:message_contains_text_emoji)
  end

  if message_contains_unicode_emoji?
    add_problem(:message_contains_unicode_emoji)
  end

  if message_contains_short_reference?
    add_problem(:message_contains_short_reference)
  end

  self
end
lint_separator() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 74
def lint_separator
  return self unless separator && !separator.empty?

  add_problem(:separator_missing)

  self
end
many_changes?() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 125
def many_changes?
  files_changed > MAX_CHANGED_FILES_IN_COMMIT && lines_changed > MAX_CHANGED_LINES_IN_COMMIT
end
message_contains_short_reference?() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 145
def message_contains_short_reference?
  commit.message.match?(SHORT_REFERENCE_REGEX) ||
    commit.message.match?(MS_SHORT_REFERENCE_REGEX)
end
message_contains_text_emoji?() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 137
def message_contains_text_emoji?
  emoji_checker.includes_text_emoji?(commit.message)
end
message_contains_unicode_emoji?() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 141
def message_contains_unicode_emoji?
  emoji_checker.includes_unicode_emoji?(commit.message)
end
separator() click to toggle source
# File lib/gitlab/dangerfiles/commit_linter.rb, line 129
def separator
  message_parts[1]
end