class Danger::RequestSources::BitbucketServer

Attributes

dismiss_out_of_range_messages[RW]
pr_json[RW]

Public Class Methods

env_vars() click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 12
def self.env_vars
  [
    "DANGER_BITBUCKETSERVER_USERNAME",
    "DANGER_BITBUCKETSERVER_PASSWORD",
    "DANGER_BITBUCKETSERVER_HOST"
  ]
end
new(ci_source, environment) click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 31
def initialize(ci_source, environment)
  self.ci_source = ci_source
  self.dismiss_out_of_range_messages = environment["DANGER_BITBUCKETSERVER_DISMISS_OUT_OF_RANGE_MESSAGES"] == "true"

  project, slug = ci_source.repo_slug.split("/")
  @api = BitbucketServerAPI.new(project, slug, ci_source.pull_request_id, environment)
  @code_insights = CodeInsightsAPI.new(project, slug, environment)
end
optional_env_vars() click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 20
def self.optional_env_vars
  [
    "DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_KEY",
    "DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_TITLE",
    "DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_DESCRIPTION",
    "DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_LOGO_URL",
    "DANGER_BITBUCKETSERVER_VERIFY_SSL",
    "DANGER_BITBUCKETSERVER_DISMISS_OUT_OF_RANGE_MESSAGES"
  ]
end

Public Instance Methods

added_lines(file) click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 198
def added_lines(file)
  @added_lines ||= {}
  @added_lines[file] ||= file_diff(file)[:hunks].map do |hunk|
    hunk[:segments].select { |segment| segment[:type] == "ADDED" }.map do |segment|
      segment[:lines].map do |line|
        line[:destination]
      end
    end
  end.flatten
end
delete_old_comments(danger_id: "danger") click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 134
def delete_old_comments(danger_id: "danger")
  @api.fetch_last_comments.each do |c|
    @api.delete_comment(c[:id], c[:version]) if c[:text] =~ /generated_by_#{danger_id}/
  end
end
fetch_details() click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 57
def fetch_details
  self.pr_json = @api.fetch_pr_json
end
file_diff(file) click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 194
def file_diff(file)
  self.pr_diff[:diffs].find { |diff| diff[:destination] && diff[:destination][:toString] == file } || { hunks: [] }
end
find_position_in_diff?(file, line) click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 187
def find_position_in_diff?(file, line)
  return nil if file.nil? || line.nil?
  return nil if file.empty?

  added_lines(file).include?(line)
end
host() click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 53
def host
  @host ||= @api.host
end
inline_violations_group(warnings: [], errors: [], messages: [], markdowns: []) click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 159
def inline_violations_group(warnings: [], errors: [], messages: [], markdowns: [])
  cmp = proc do |a, b|
    next -1 unless a.file && a.line
    next 1 unless b.file && b.line

    next a.line <=> b.line if a.file == b.file

    next a.file <=> b.file
  end

  # Sort to group inline comments by file
  {
    warnings: warnings.select(&:inline?).sort(&cmp),
    errors: errors.select(&:inline?).sort(&cmp),
    messages: messages.select(&:inline?).sort(&cmp),
    markdowns: markdowns.select(&:inline?).sort(&cmp)
  }
end
main_violations_group(warnings: [], errors: [], messages: [], markdowns: []) click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 140
def main_violations_group(warnings: [], errors: [], messages: [], markdowns: [])
  if dismiss_out_of_range_messages
    {
      warnings: warnings.reject(&:inline?),
      errors: errors.reject(&:inline?),
      messages: messages.reject(&:inline?),
      markdowns: markdowns.reject(&:inline?)
    }
  else
    in_diff = proc { |a| find_position_in_diff?(a.file, a.line) }
    {
      warnings: warnings.reject(&in_diff),
      errors: errors.reject(&in_diff),
      messages: messages.reject(&in_diff),
      markdowns: markdowns.reject(&in_diff)
    }
  end
end
organisation() click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 85
def organisation
  nil
end
pr_diff() click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 61
def pr_diff
  @pr_diff ||= @api.fetch_pr_diff
end
scm() click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 49
def scm
  @scm ||= GitRepo.new
end
setup_danger_branches() click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 65
def setup_danger_branches
  base_branch = self.pr_json[:toRef][:id].sub("refs/heads/", "")
  base_commit = self.pr_json[:toRef][:latestCommit]
  # Support for older versions of Bitbucket Server
  base_commit = self.pr_json[:toRef][:latestChangeset] if self.pr_json[:fromRef].key? :latestChangeset
  head_branch = self.pr_json[:fromRef][:id].sub("refs/heads/", "")
  head_commit = self.pr_json[:fromRef][:latestCommit]
  # Support for older versions of Bitbucket Server
  head_commit = self.pr_json[:fromRef][:latestChangeset] if self.pr_json[:fromRef].key? :latestChangeset

  # Next, we want to ensure that we have a version of the current branch at a known location
  scm.ensure_commitish_exists_on_branch! base_branch, base_commit
  self.scm.exec "branch #{EnvironmentManager.danger_base_branch} #{base_commit}"

  # OK, so we want to ensure that we have a known head branch, this will always represent
  # the head of the PR ( e.g. the most recent commit that will be merged. )
  scm.ensure_commitish_exists_on_branch! head_branch, head_commit
  self.scm.exec "branch #{EnvironmentManager.danger_head_branch} #{head_commit}"
end
update_pr_build_status(status, build_job_link, description) click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 178
def update_pr_build_status(status, build_job_link, description)
  changeset = self.pr_json[:fromRef][:latestCommit]
  # Support for older versions of Bitbucket Server
  changeset = self.pr_json[:fromRef][:latestChangeset] if self.pr_json[:fromRef].key? :latestChangeset
  puts "Changeset: " + changeset
  puts self.pr_json.to_json
  @api.update_pr_build_status(status, changeset, build_job_link, description)
end
update_pull_request!(warnings: [], errors: [], messages: [], markdowns: [], danger_id: "danger", new_comment: false, remove_previous_comments: false) click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 89
def update_pull_request!(warnings: [], errors: [], messages: [], markdowns: [], danger_id: "danger", new_comment: false, remove_previous_comments: false)
  delete_old_comments(danger_id: danger_id) if !new_comment || remove_previous_comments

  # If configured, send a Code Insights API to provide the PR with a quality report
  # which includes inline code violations found by Danger as Annotations.
  # If no inline violations occurred, an empty, successful (green) report will be sent.
  if @code_insights.ready?
    inline_violations = inline_violations_group(warnings: warnings, errors: errors, messages: messages)
    inline_warnings = inline_violations[:warnings] || []
    inline_errors = inline_violations[:errors] || []
    inline_messages = inline_violations[:messages] || []

    head_commit = self.pr_json[:fromRef][:latestCommit]
    @code_insights.send_report(head_commit,
                               inline_warnings,
                               inline_errors,
                               inline_messages)
  end

  # If we're sending inline comments separately via Code Insights,
  # the main body comment should contain only generic, non-file specific messages.
  if @code_insights.ready?
    main_violations = main_violations_group(warnings: warnings, errors: errors, messages: messages)
    warnings = main_violations[:warnings] || []
    errors = main_violations[:errors] || []
    messages = main_violations[:messages] || []
    markdowns = main_violations[:markdowns] || []
  end

  has_comments = warnings.count > 0 || errors.count > 0 || messages.count > 0 || markdowns.count > 0
  if has_comments
    comment = generate_description(warnings: warnings,
                                   errors: errors)
    comment += "\n\n"
    comment += generate_comment(warnings: warnings,
                                errors: errors,
                                messages: messages,
                                markdowns: markdowns,
                                previous_violations: {},
                                danger_id: danger_id,
                                template: "bitbucket_server")
    @api.post_comment(comment)
  end
end
validates_as_api_source?() click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 45
def validates_as_api_source?
  @api.credentials_given?
end
validates_as_ci?() click to toggle source
# File lib/danger/request_sources/bitbucket_server.rb, line 40
def validates_as_ci?
  # TODO: ???
  true
end