diff options
Diffstat (limited to 'lib/gitlab/danger/helper.rb')
-rw-r--r-- | lib/gitlab/danger/helper.rb | 67 |
1 files changed, 53 insertions, 14 deletions
diff --git a/lib/gitlab/danger/helper.rb b/lib/gitlab/danger/helper.rb index 327418ad100..db799c094b2 100644 --- a/lib/gitlab/danger/helper.rb +++ b/lib/gitlab/danger/helper.rb @@ -6,6 +6,7 @@ module Gitlab module Danger module Helper RELEASE_TOOLS_BOT = 'gitlab-release-tools-bot' + DRAFT_REGEX = /\A*#{Regexp.union(/(?i)(\[WIP\]\s*|WIP:\s*|WIP$)/, /(?i)(\[draft\]|\(draft\)|draft:|draft\s\-\s|draft$)/)}+\s*/i.freeze # Returns a list of all files that have been added, modified or renamed. # `git.modified_files` might contain paths that already have been renamed, @@ -34,6 +35,18 @@ module Gitlab .sort end + # Returns a string containing changed lines as git diff + # + # Considering changing a line in lib/gitlab/usage_data.rb it will return: + # + # [ "--- a/lib/gitlab/usage_data.rb", + # "+++ b/lib/gitlab/usage_data.rb", + # "+ # Test change", + # "- # Old change" ] + def changed_lines(changed_file) + git.diff_for_file(changed_file).patch.split("\n").select { |line| %r{^[+-]}.match?(line) } + end + def all_ee_changes all_changed_files.grep(%r{\Aee/}) end @@ -73,16 +86,25 @@ module Gitlab # @return [Hash<String,Array<String>>] def changes_by_category all_changed_files.each_with_object(Hash.new { |h, k| h[k] = [] }) do |file, hash| - hash[category_for_file(file)] << file + categories_for_file(file).each { |category| hash[category] << file } end end - # Determines the category a file is in, e.g., `:frontend` or `:backend` - # @return[Symbol] - def category_for_file(file) - _, category = CATEGORIES.find { |regexp, _| regexp.match?(file) } + # Determines the categories a file is in, e.g., `[:frontend]`, `[:backend]`, or `%i[frontend engineering_productivity]` + # using filename regex and specific change regex if given. + # + # @return Array<Symbol> + def categories_for_file(file) + _, categories = CATEGORIES.find do |key, _| + filename_regex, changes_regex = Array(key) + + found = filename_regex.match?(file) + found &&= changed_lines(file).any? { |changed_line| changes_regex.match?(changed_line) } if changes_regex - category || :unknown + found + end + + Array(categories || :unknown) end # Returns the GFM for a category label, making its best guess if it's not @@ -102,8 +124,10 @@ module Gitlab }.freeze # First-match win, so be sure to put more specific regex at the top... CATEGORIES = { - %r{\Adoc/} => :none, # To reinstate roulette for documentation, set to `:docs`. - %r{\A(CONTRIBUTING|LICENSE|MAINTENANCE|PHILOSOPHY|PROCESS|README)(\.md)?\z} => :none, # To reinstate roulette for documentation, set to `:docs`. + [%r{usage_data}, %r{^(\+|-).*(count|distinct_count)\(.*\)(.*)$}] => [:database, :backend], + + %r{\Adoc/.*(\.(md|png|gif|jpg))\z} => :docs, + %r{\A(CONTRIBUTING|LICENSE|MAINTENANCE|PHILOSOPHY|PROCESS|README)(\.md)?\z} => :docs, %r{\A(ee/)?app/(assets|views)/} => :frontend, %r{\A(ee/)?public/} => :frontend, @@ -125,10 +149,13 @@ module Gitlab jest\.config\.js | package\.json | yarn\.lock | - config/.+\.js | - \.gitlab/ci/frontend\.gitlab-ci\.yml + config/.+\.js )\z}x => :frontend, + %r{(\A|/)( + \.gitlab/ci/frontend\.gitlab-ci\.yml + )\z}x => %i[frontend engineering_productivity], + %r{\A(ee/)?db/(?!fixtures)[^/]+} => :database, %r{\A(ee/)?lib/gitlab/(database|background_migration|sql|github_import)(/|\.rb)} => :database, %r{\A(app/models/project_authorization|app/services/users/refresh_authorized_projects_service)(/|\.rb)} => :database, @@ -136,13 +163,13 @@ module Gitlab %r{\Arubocop/cop/migration(/|\.rb)} => :database, %r{\A(\.gitlab-ci\.yml\z|\.gitlab\/ci)} => :engineering_productivity, + %r{\A\.codeclimate\.yml\z} => :engineering_productivity, %r{\A\.overcommit\.yml\.example\z} => :engineering_productivity, - %r{\Atooling/overcommit/} => :engineering_productivity, - %r{\A.editorconfig\z} => :engineering_productivity, + %r{\A\.editorconfig\z} => :engineering_productivity, %r{Dangerfile\z} => :engineering_productivity, %r{\A(ee/)?(danger/|lib/gitlab/danger/)} => :engineering_productivity, %r{\A(ee/)?scripts/} => :engineering_productivity, - %r{\A\.codeclimate\.yml\z} => :engineering_productivity, + %r{\Atooling/} => :engineering_productivity, %r{\A(ee/)?app/(?!assets|views)[^/]+} => :backend, %r{\A(ee/)?(bin|config|generator_templates|lib|rubocop)/} => :backend, @@ -184,7 +211,7 @@ module Gitlab end def sanitize_mr_title(title) - title.gsub(/^WIP: */, '').gsub(/`/, '\\\`') + title.gsub(DRAFT_REGEX, '').gsub(/`/, '\\\`') end def security_mr? @@ -193,6 +220,18 @@ module Gitlab gitlab_helper.mr_json['web_url'].include?('/gitlab-org/security/') end + def cherry_pick_mr? + return false unless gitlab_helper + + /cherry[\s-]*pick/i.match?(gitlab_helper.mr_json['title']) + end + + def stable_branch? + return false unless gitlab_helper + + /\A\d+-\d+-stable-ee/i.match?(gitlab_helper.mr_json['target_branch']) + end + def mr_has_labels?(*labels) return false unless gitlab_helper |