Improve Emoji detection in commit messages

This changes our Danger integration so that it is smarter about
detecting GitLab emoji in commit messages. This is done using a two step
process:

1. We use the old regular expression to determine if a commit message
   _might_ include an emoji.

2. If this regular expression matches, we then check for all existing
   emoji names in the commit message. This might be a wee bit expensive,
   but because we couple it with the previous step it should be rarely
   executed.

This ensures we don't trigger an error when a commit message includes
text such as `:foo:bar:`, which is not a valid Emoji.

Fixes https://gitlab.com/gitlab-org/release/framework/issues/15
This commit is contained in:
Yorick Peterse 2018-09-18 16:14:38 +02:00
parent a2a00a5e6d
commit 4ef1dd09dd
No known key found for this signature in database
GPG Key ID: EDD30D2BEB691AC9
1 changed files with 28 additions and 1 deletions

View File

@ -1,5 +1,7 @@
# frozen_string_literal: true
require 'json'
# rubocop: disable Style/SignalException
# rubocop: disable Metrics/CyclomaticComplexity
# rubocop: disable Metrics/PerceivedComplexity
@ -8,6 +10,30 @@
# https://github.com/jonallured/danger-commit_lint because its output is not
# very helpful, and it doesn't offer the means of ignoring merge commits.
class EmojiChecker
DIGESTS = File.expand_path('../../fixtures/emojis/digests.json', __dir__)
ALIASES = File.expand_path('../../fixtures/emojis/aliases.json', __dir__)
# A regex that indicates a piece of text _might_ include an Emoji. The regex
# alone is not enough, as we'd match `:foo:bar:baz`. Instead, we use this
# regex to save us from having to check for all possible emoji names when we
# know one definitely is not included.
LIKELY_EMOJI = /:[\+a-z0-9_\-]+:/
def initialize
names = JSON.parse(File.read(DIGESTS)).keys +
JSON.parse(File.read(ALIASES)).keys
@emoji = names.map { |name| ":#{name}:" }
end
def includes_emoji?(text)
return false unless text.match?(LIKELY_EMOJI)
@emoji.any? { |emoji| text.include?(emoji) }
end
end
def fail_commit(commit, message)
fail("#{commit.sha}: #{message}")
end
@ -33,6 +59,7 @@ end
def lint_commits(commits)
failures = false
emoji_checker = EmojiChecker.new
unicode_emoji_regex = %r((
[\u{1F300}-\u{1F5FF}] |
@ -117,7 +144,7 @@ def lint_commits(commits)
failures = true
end
if commit.message.match?(/:[\+a-z0-9_\-]+:/)
if emoji_checker.includes_emoji?(commit.message)
fail_commit(
commit,
'Avoid the use of Markdown Emoji such as `:+1:`. ' \