danger-additional-logging 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +93 -0
- data/bin/danger +5 -0
- data/lib/assets/DangerfileTemplate +13 -0
- data/lib/danger/ci_source/appcenter.rb +55 -0
- data/lib/danger/ci_source/appcircle.rb +83 -0
- data/lib/danger/ci_source/appveyor.rb +64 -0
- data/lib/danger/ci_source/azure_pipelines.rb +61 -0
- data/lib/danger/ci_source/bamboo.rb +41 -0
- data/lib/danger/ci_source/bitbucket_pipelines.rb +37 -0
- data/lib/danger/ci_source/bitrise.rb +78 -0
- data/lib/danger/ci_source/buddybuild.rb +62 -0
- data/lib/danger/ci_source/buildkite.rb +51 -0
- data/lib/danger/ci_source/ci_source.rb +37 -0
- data/lib/danger/ci_source/circle.rb +94 -0
- data/lib/danger/ci_source/circle_api.rb +51 -0
- data/lib/danger/ci_source/cirrus.rb +31 -0
- data/lib/danger/ci_source/code_build.rb +71 -0
- data/lib/danger/ci_source/codefresh.rb +47 -0
- data/lib/danger/ci_source/codemagic.rb +58 -0
- data/lib/danger/ci_source/codeship.rb +44 -0
- data/lib/danger/ci_source/concourse.rb +60 -0
- data/lib/danger/ci_source/custom_ci_with_github.rb +49 -0
- data/lib/danger/ci_source/dotci.rb +50 -0
- data/lib/danger/ci_source/drone.rb +71 -0
- data/lib/danger/ci_source/github_actions.rb +44 -0
- data/lib/danger/ci_source/gitlab_ci.rb +89 -0
- data/lib/danger/ci_source/jenkins.rb +148 -0
- data/lib/danger/ci_source/local_git_repo.rb +117 -0
- data/lib/danger/ci_source/local_only_git_repo.rb +44 -0
- data/lib/danger/ci_source/screwdriver.rb +48 -0
- data/lib/danger/ci_source/semaphore.rb +37 -0
- data/lib/danger/ci_source/support/commits.rb +19 -0
- data/lib/danger/ci_source/support/find_repo_info_from_logs.rb +35 -0
- data/lib/danger/ci_source/support/find_repo_info_from_url.rb +43 -0
- data/lib/danger/ci_source/support/local_pull_request.rb +14 -0
- data/lib/danger/ci_source/support/no_pull_request.rb +7 -0
- data/lib/danger/ci_source/support/no_repo_info.rb +5 -0
- data/lib/danger/ci_source/support/pull_request_finder.rb +190 -0
- data/lib/danger/ci_source/support/remote_pull_request.rb +15 -0
- data/lib/danger/ci_source/support/repo_info.rb +10 -0
- data/lib/danger/ci_source/surf.rb +37 -0
- data/lib/danger/ci_source/teamcity.rb +163 -0
- data/lib/danger/ci_source/travis.rb +51 -0
- data/lib/danger/ci_source/xcode_cloud.rb +38 -0
- data/lib/danger/ci_source/xcode_server.rb +48 -0
- data/lib/danger/clients/rubygems_client.rb +14 -0
- data/lib/danger/commands/dangerfile/gem.rb +43 -0
- data/lib/danger/commands/dangerfile/init.rb +30 -0
- data/lib/danger/commands/dry_run.rb +54 -0
- data/lib/danger/commands/init.rb +297 -0
- data/lib/danger/commands/init_helpers/interviewer.rb +92 -0
- data/lib/danger/commands/local.rb +83 -0
- data/lib/danger/commands/local_helpers/http_cache.rb +38 -0
- data/lib/danger/commands/local_helpers/local_setup.rb +48 -0
- data/lib/danger/commands/local_helpers/pry_setup.rb +32 -0
- data/lib/danger/commands/plugins/plugin_json.rb +44 -0
- data/lib/danger/commands/plugins/plugin_lint.rb +52 -0
- data/lib/danger/commands/plugins/plugin_readme.rb +42 -0
- data/lib/danger/commands/pr.rb +93 -0
- data/lib/danger/commands/runner.rb +94 -0
- data/lib/danger/commands/staging.rb +53 -0
- data/lib/danger/commands/systems.rb +41 -0
- data/lib/danger/comment_generators/bitbucket_server.md.erb +20 -0
- data/lib/danger/comment_generators/bitbucket_server_inline.md.erb +15 -0
- data/lib/danger/comment_generators/bitbucket_server_message_group.md.erb +12 -0
- data/lib/danger/comment_generators/github.md.erb +55 -0
- data/lib/danger/comment_generators/github_inline.md.erb +26 -0
- data/lib/danger/comment_generators/gitlab.md.erb +40 -0
- data/lib/danger/comment_generators/gitlab_inline.md.erb +21 -0
- data/lib/danger/comment_generators/vsts.md.erb +20 -0
- data/lib/danger/comment_generators/vsts_inline.md.erb +17 -0
- data/lib/danger/core_ext/file_list.rb +18 -0
- data/lib/danger/core_ext/string.rb +20 -0
- data/lib/danger/danger_core/dangerfile.rb +348 -0
- data/lib/danger/danger_core/dangerfile_dsl.rb +29 -0
- data/lib/danger/danger_core/dangerfile_generator.rb +11 -0
- data/lib/danger/danger_core/environment_manager.rb +126 -0
- data/lib/danger/danger_core/executor.rb +91 -0
- data/lib/danger/danger_core/message_aggregator.rb +50 -0
- data/lib/danger/danger_core/message_group.rb +68 -0
- data/lib/danger/danger_core/messages/base.rb +57 -0
- data/lib/danger/danger_core/messages/markdown.rb +41 -0
- data/lib/danger/danger_core/messages/violation.rb +53 -0
- data/lib/danger/danger_core/plugins/dangerfile_bitbucket_cloud_plugin.rb +142 -0
- data/lib/danger/danger_core/plugins/dangerfile_bitbucket_server_plugin.rb +211 -0
- data/lib/danger/danger_core/plugins/dangerfile_danger_plugin.rb +274 -0
- data/lib/danger/danger_core/plugins/dangerfile_git_plugin.rb +159 -0
- data/lib/danger/danger_core/plugins/dangerfile_github_plugin.rb +264 -0
- data/lib/danger/danger_core/plugins/dangerfile_gitlab_plugin.rb +275 -0
- data/lib/danger/danger_core/plugins/dangerfile_local_only_plugin.rb +43 -0
- data/lib/danger/danger_core/plugins/dangerfile_messaging_plugin.rb +220 -0
- data/lib/danger/danger_core/plugins/dangerfile_vsts_plugin.rb +191 -0
- data/lib/danger/danger_core/standard_error.rb +142 -0
- data/lib/danger/helpers/array_subclass.rb +61 -0
- data/lib/danger/helpers/comment.rb +32 -0
- data/lib/danger/helpers/comments_helper.rb +179 -0
- data/lib/danger/helpers/comments_parsing_helper.rb +71 -0
- data/lib/danger/helpers/emoji_mapper.rb +41 -0
- data/lib/danger/helpers/find_max_num_violations.rb +31 -0
- data/lib/danger/helpers/message_groups_array_helper.rb +31 -0
- data/lib/danger/plugin_support/gems_resolver.rb +77 -0
- data/lib/danger/plugin_support/plugin.rb +52 -0
- data/lib/danger/plugin_support/plugin_file_resolver.rb +30 -0
- data/lib/danger/plugin_support/plugin_linter.rb +162 -0
- data/lib/danger/plugin_support/plugin_parser.rb +199 -0
- data/lib/danger/plugin_support/templates/readme_table.html.erb +26 -0
- data/lib/danger/request_sources/bitbucket_cloud.rb +169 -0
- data/lib/danger/request_sources/bitbucket_cloud_api.rb +181 -0
- data/lib/danger/request_sources/bitbucket_server.rb +210 -0
- data/lib/danger/request_sources/bitbucket_server_api.rb +129 -0
- data/lib/danger/request_sources/code_insights_api.rb +142 -0
- data/lib/danger/request_sources/github/github.rb +535 -0
- data/lib/danger/request_sources/github/github_review.rb +127 -0
- data/lib/danger/request_sources/github/github_review_resolver.rb +17 -0
- data/lib/danger/request_sources/github/github_review_unsupported.rb +23 -0
- data/lib/danger/request_sources/gitlab.rb +557 -0
- data/lib/danger/request_sources/local_only.rb +50 -0
- data/lib/danger/request_sources/request_source.rb +97 -0
- data/lib/danger/request_sources/support/get_ignored_violation.rb +17 -0
- data/lib/danger/request_sources/vsts.rb +278 -0
- data/lib/danger/request_sources/vsts_api.rb +172 -0
- data/lib/danger/scm_source/git_repo.rb +198 -0
- data/lib/danger/version.rb +4 -0
- data/lib/danger.rb +45 -0
- metadata +351 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "danger/danger_core/message_group"
|
|
4
|
+
require "danger/helpers/message_groups_array_helper"
|
|
5
|
+
|
|
6
|
+
module Danger
|
|
7
|
+
class MessageAggregator
|
|
8
|
+
def self.aggregate(*args)
|
|
9
|
+
new(*args).aggregate
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize(warnings: [],
|
|
13
|
+
errors: [],
|
|
14
|
+
messages: [],
|
|
15
|
+
markdowns: [],
|
|
16
|
+
danger_id: "danger")
|
|
17
|
+
@messages = warnings + errors + messages + markdowns
|
|
18
|
+
@danger_id = danger_id
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# aggregates the messages into an array of MessageGroups
|
|
22
|
+
# @return [[MessageGroup]]
|
|
23
|
+
def aggregate
|
|
24
|
+
# oookay I took some shortcuts with this one.
|
|
25
|
+
# first, sort messages by file and line
|
|
26
|
+
@messages.sort! { |a, b| a.compare_by_file_and_line(b) }
|
|
27
|
+
|
|
28
|
+
# now create an initial empty message group
|
|
29
|
+
first_group = MessageGroup.new(file: nil,
|
|
30
|
+
line: nil)
|
|
31
|
+
@message_groups = @messages.reduce([first_group]) do |groups, msg|
|
|
32
|
+
# We get to take a shortcut because we sorted the messages earlier - only
|
|
33
|
+
# have to see if we can append msg to the last group in the list
|
|
34
|
+
if groups.last << msg
|
|
35
|
+
# we appended it, so return groups unchanged
|
|
36
|
+
groups
|
|
37
|
+
else
|
|
38
|
+
# have to create a new group since msg wasn't appended to the other
|
|
39
|
+
# group
|
|
40
|
+
new_group = MessageGroup.new(file: msg.file,
|
|
41
|
+
line: msg.line)
|
|
42
|
+
new_group << msg
|
|
43
|
+
groups << new_group
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
@message_groups.extend(Helpers::MessageGroupsArrayHelper)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Danger
|
|
4
|
+
class MessageGroup
|
|
5
|
+
def initialize(file: nil, line: nil)
|
|
6
|
+
@file = file
|
|
7
|
+
@line = line
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Returns whether this `MessageGroup` is for the same line of code as
|
|
11
|
+
# `other`, taking which file they are in to account.
|
|
12
|
+
# @param other [MessageGroup, Markdown, Violation]
|
|
13
|
+
# @return [Boolean] whether this `MessageGroup` is for the same line of code
|
|
14
|
+
def same_line?(other)
|
|
15
|
+
other.file == file && other.line == line
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Merges two `MessageGroup`s that represent the same line of code
|
|
19
|
+
# In future, perhaps `MessageGroup` will be able to represent a group of
|
|
20
|
+
# messages for multiple lines.
|
|
21
|
+
def merge(other)
|
|
22
|
+
raise ArgumentError, "Cannot merge with MessageGroup for a different line" unless same_line?(other)
|
|
23
|
+
|
|
24
|
+
@messages = (messages + other.messages).uniq
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Adds a message to the group.
|
|
28
|
+
# @param message [Markdown, Violation] the message to add
|
|
29
|
+
def <<(message)
|
|
30
|
+
# TODO: insertion sort
|
|
31
|
+
return nil unless same_line?(message)
|
|
32
|
+
|
|
33
|
+
inserted = false
|
|
34
|
+
messages.each.with_index do |other, idx|
|
|
35
|
+
if (message <=> other) == -1
|
|
36
|
+
inserted = true
|
|
37
|
+
messages.insert(idx, message)
|
|
38
|
+
break
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
messages << message unless inserted
|
|
42
|
+
messages
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# The list of messages in this group. This list will be sorted in decreasing
|
|
46
|
+
# order of severity (error, warning, message, markdown)
|
|
47
|
+
def messages
|
|
48
|
+
@messages ||= []
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
attr_reader :file, :line
|
|
52
|
+
|
|
53
|
+
# @return a hash of statistics. Currently only :warnings_count and
|
|
54
|
+
# :errors_count
|
|
55
|
+
def stats
|
|
56
|
+
stats = { warnings_count: 0, errors_count: 0 }
|
|
57
|
+
messages.each do |msg|
|
|
58
|
+
stats[:warnings_count] += 1 if msg.type == :warning
|
|
59
|
+
stats[:errors_count] += 1 if msg.type == :error
|
|
60
|
+
end
|
|
61
|
+
stats
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def markdowns
|
|
65
|
+
messages.select { |x| x.type == :markdown }
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Danger
|
|
2
|
+
class BaseMessage
|
|
3
|
+
attr_accessor :message, :file, :line, :type
|
|
4
|
+
|
|
5
|
+
def initialize(type:, message:, file: nil, line: nil)
|
|
6
|
+
@type = type
|
|
7
|
+
@message = message
|
|
8
|
+
@file = file
|
|
9
|
+
@line = line
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def compare_by_file_and_line(other)
|
|
13
|
+
order = cmp_nils(file, other.file)
|
|
14
|
+
return order unless order.nil?
|
|
15
|
+
|
|
16
|
+
order = file <=> other.file
|
|
17
|
+
return order unless order.zero?
|
|
18
|
+
|
|
19
|
+
order = cmp_nils(line, other.line)
|
|
20
|
+
return order unless order.nil?
|
|
21
|
+
|
|
22
|
+
line <=> other.line
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# compares a and b based entirely on whether one or the other is nil
|
|
26
|
+
# arguments are in the same order as `a <=> b`
|
|
27
|
+
# nil is sorted earlier - so cmp_nils(nil, 1) => -1
|
|
28
|
+
#
|
|
29
|
+
# If neither are nil, rather than returning `a <=> b` which would seem
|
|
30
|
+
# like the obvious shortcut, `nil` is returned.
|
|
31
|
+
# This allows us to distinguish between cmp_nils returning 0 for a
|
|
32
|
+
# comparison of filenames, which means "a comparison on the lines is
|
|
33
|
+
# meaningless - you cannot have a line number for a nil file - so they
|
|
34
|
+
# should be sorted the same", and a <=> b returning 0, which means "the
|
|
35
|
+
# files are the same, so compare on the lines"
|
|
36
|
+
#
|
|
37
|
+
# @return 0, 1, -1, or nil
|
|
38
|
+
def cmp_nils(a, b)
|
|
39
|
+
if a.nil? && b.nil?
|
|
40
|
+
0
|
|
41
|
+
elsif a.nil?
|
|
42
|
+
-1
|
|
43
|
+
elsif b.nil?
|
|
44
|
+
1
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def eql?(other)
|
|
49
|
+
return self == other
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @return [Boolean] returns true if is a file or line, false otherwise
|
|
53
|
+
def inline?
|
|
54
|
+
file || line
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "danger/danger_core/messages/base"
|
|
4
|
+
|
|
5
|
+
module Danger
|
|
6
|
+
class Markdown < BaseMessage
|
|
7
|
+
def initialize(message, file = nil, line = nil)
|
|
8
|
+
super(type: :markdown, message: message, file: file, line: line)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def ==(other)
|
|
12
|
+
return false if other.nil?
|
|
13
|
+
return false unless other.kind_of? self.class
|
|
14
|
+
|
|
15
|
+
other.message == message &&
|
|
16
|
+
other.file == file &&
|
|
17
|
+
other.line == line
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def hash
|
|
21
|
+
h = 1
|
|
22
|
+
h = h * 31 + message.hash
|
|
23
|
+
h = h * 17 + file.hash
|
|
24
|
+
h * 17 + line.hash
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def to_s
|
|
28
|
+
extra = []
|
|
29
|
+
extra << "file: #{file}" unless file
|
|
30
|
+
extra << "line: #{line}" unless line
|
|
31
|
+
|
|
32
|
+
"Markdown #{message} { #{extra.join ', '} }"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def <=>(other)
|
|
36
|
+
return 1 if other.type != :markdown
|
|
37
|
+
|
|
38
|
+
compare_by_file_and_line(other)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "danger/danger_core/messages/base"
|
|
4
|
+
|
|
5
|
+
module Danger
|
|
6
|
+
class Violation < BaseMessage
|
|
7
|
+
VALID_TYPES = %I[error warning message].freeze
|
|
8
|
+
attr_accessor :sticky
|
|
9
|
+
|
|
10
|
+
def initialize(message, sticky, file = nil, line = nil, type: :warning)
|
|
11
|
+
raise ArgumentError unless VALID_TYPES.include?(type)
|
|
12
|
+
|
|
13
|
+
super(type: type, message: message, file: file, line: line)
|
|
14
|
+
self.sticky = sticky
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def ==(other)
|
|
18
|
+
return false if other.nil?
|
|
19
|
+
return false unless other.kind_of? self.class
|
|
20
|
+
|
|
21
|
+
other.message == message &&
|
|
22
|
+
other.sticky == sticky &&
|
|
23
|
+
other.file == file &&
|
|
24
|
+
other.line == line
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def hash
|
|
28
|
+
h = 1
|
|
29
|
+
h = h * 31 + message.hash
|
|
30
|
+
h = h * 13 + sticky.hash
|
|
31
|
+
h = h * 17 + file.hash
|
|
32
|
+
h * 17 + line.hash
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def <=>(other)
|
|
36
|
+
types = VALID_TYPES + [:markdown]
|
|
37
|
+
order = types.index(type) <=> types.index(other.type)
|
|
38
|
+
return order unless order.zero?
|
|
39
|
+
|
|
40
|
+
compare_by_file_and_line(other)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def to_s
|
|
44
|
+
extra = []
|
|
45
|
+
extra << "sticky: #{sticky}"
|
|
46
|
+
extra << "file: #{file}" if file
|
|
47
|
+
extra << "line: #{line}" if line
|
|
48
|
+
extra << "type: #{type}"
|
|
49
|
+
|
|
50
|
+
"Violation #{message} { #{extra.join ', '} }"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
require "danger/plugin_support/plugin"
|
|
2
|
+
|
|
3
|
+
module Danger
|
|
4
|
+
# Handles interacting with Bitbucket Cloud inside a Dangerfile. Provides a few functions which wrap `pr_json` and also
|
|
5
|
+
# through a few standard functions to simplify your code.
|
|
6
|
+
#
|
|
7
|
+
# @example Warn when a PR is classed as work in progress
|
|
8
|
+
#
|
|
9
|
+
# warn "PR is classed as Work in Progress" if bitbucket_cloud.pr_title.include? "[WIP]"
|
|
10
|
+
#
|
|
11
|
+
# @example Declare a PR to be simple to avoid specific Danger rules
|
|
12
|
+
#
|
|
13
|
+
# declared_trivial = (bitbucket_cloud.pr_title + bitbucket_cloud.pr_body).include?("#trivial")
|
|
14
|
+
#
|
|
15
|
+
# @example Ensure that labels have been used on the PR
|
|
16
|
+
#
|
|
17
|
+
# failure "Please add labels to this PR" if bitbucket_cloud.pr_labels.empty?
|
|
18
|
+
#
|
|
19
|
+
# @example Ensure there is a summary for a PR
|
|
20
|
+
#
|
|
21
|
+
# failure "Please provide a summary in the Pull Request description" if bitbucket_cloud.pr_body.length < 5
|
|
22
|
+
#
|
|
23
|
+
# @example Only accept PRs to the develop branch
|
|
24
|
+
#
|
|
25
|
+
# failure "Please re-submit this PR to develop, we may have already fixed your issue." if bitbucket_cloud.branch_for_base != "develop"
|
|
26
|
+
#
|
|
27
|
+
# @example Highlight when a celebrity makes a pull request
|
|
28
|
+
#
|
|
29
|
+
# message "Welcome, Danger." if bitbucket_cloud.pr_author == "dangermcshane"
|
|
30
|
+
#
|
|
31
|
+
# @example Ensure that all PRs have an assignee
|
|
32
|
+
#
|
|
33
|
+
# warn "This PR does not have any assignees yet." if bitbucket_cloud.pr_json[:reviewers].length == 0
|
|
34
|
+
#
|
|
35
|
+
# @example Send a message with links to a collection of specific files
|
|
36
|
+
#
|
|
37
|
+
# if git.modified_files.include? "config/*.js"
|
|
38
|
+
# config_files = git.modified_files.select { |path| path.include? "config/" }
|
|
39
|
+
# message "This PR changes #{ bitbucket_cloud.html_link(config_files) }"
|
|
40
|
+
# end
|
|
41
|
+
#
|
|
42
|
+
# @example Highlight with a clickable link if a Package.json is changed
|
|
43
|
+
#
|
|
44
|
+
# warn "#{bitbucket_cloud.html_link("Package.json")} was edited." if git.modified_files.include? "Package.json"
|
|
45
|
+
#
|
|
46
|
+
# @see danger/danger
|
|
47
|
+
# @tags core, bitbucket_cloud
|
|
48
|
+
#
|
|
49
|
+
class DangerfileBitbucketCloudPlugin < Plugin
|
|
50
|
+
# So that this init can fail.
|
|
51
|
+
def self.new(dangerfile)
|
|
52
|
+
return nil if dangerfile.env.request_source.class != Danger::RequestSources::BitbucketCloud
|
|
53
|
+
|
|
54
|
+
super
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# The instance name used in the Dangerfile
|
|
58
|
+
# @return [String]
|
|
59
|
+
#
|
|
60
|
+
def self.instance_name
|
|
61
|
+
"bitbucket_cloud"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def initialize(dangerfile)
|
|
65
|
+
super(dangerfile)
|
|
66
|
+
@bs = dangerfile.env.request_source
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @!group Bitbucket Cloud Misc
|
|
70
|
+
# The hash that represents the PR's JSON. For an example of what this looks like
|
|
71
|
+
# see the [Danger Fixture'd one](https://raw.githubusercontent.com/danger/danger/master/spec/fixtures/bitbucket_cloud_api/pr_response.json).
|
|
72
|
+
# @return [Hash]
|
|
73
|
+
def pr_json
|
|
74
|
+
@bs.pr_json
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @!group PR Metadata
|
|
78
|
+
# The title of the Pull Request.
|
|
79
|
+
# @return [String]
|
|
80
|
+
#
|
|
81
|
+
def pr_title
|
|
82
|
+
@bs.pr_json[:title].to_s
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# @!group PR Metadata
|
|
86
|
+
# The body text of the Pull Request.
|
|
87
|
+
# @return [String]
|
|
88
|
+
#
|
|
89
|
+
def pr_description
|
|
90
|
+
@bs.pr_json[:description].to_s
|
|
91
|
+
end
|
|
92
|
+
alias pr_body pr_description
|
|
93
|
+
|
|
94
|
+
# @!group PR Metadata
|
|
95
|
+
# The username of the author of the Pull Request.
|
|
96
|
+
# @return [String]
|
|
97
|
+
#
|
|
98
|
+
def pr_author
|
|
99
|
+
@bs.pr_json[:author][:nickname]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# @!group PR Commit Metadata
|
|
103
|
+
# The branch to which the PR is going to be merged into.
|
|
104
|
+
# @return [String]
|
|
105
|
+
#
|
|
106
|
+
def branch_for_base
|
|
107
|
+
@bs.pr_json[:destination][:branch][:name]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# @!group PR Commit Metadata
|
|
111
|
+
# A href that represents the current PR
|
|
112
|
+
# @return [String]
|
|
113
|
+
#
|
|
114
|
+
def pr_link
|
|
115
|
+
@bs.pr_json[:links][:self][:href]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# @!group PR Commit Metadata
|
|
119
|
+
# The branch to which the PR is going to be merged from.
|
|
120
|
+
# @return [String]
|
|
121
|
+
#
|
|
122
|
+
def branch_for_head
|
|
123
|
+
@bs.pr_json[:source][:branch][:name]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# @!group PR Commit Metadata
|
|
127
|
+
# The base commit to which the PR is going to be merged as a parent.
|
|
128
|
+
# @return [String]
|
|
129
|
+
#
|
|
130
|
+
def base_commit
|
|
131
|
+
@bs.pr_json[:destination][:commit][:hash]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# @!group PR Commit Metadata
|
|
135
|
+
# The head commit to which the PR is requesting to be merged from.
|
|
136
|
+
# @return [String]
|
|
137
|
+
#
|
|
138
|
+
def head_commit
|
|
139
|
+
@bs.pr_json[:source][:commit][:hash]
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
require "danger/plugin_support/plugin"
|
|
2
|
+
|
|
3
|
+
module Danger
|
|
4
|
+
# Handles interacting with Bitbucket Server inside a Dangerfile. Provides a few functions which wrap `pr_json` and also
|
|
5
|
+
# through a few standard functions to simplify your code.
|
|
6
|
+
#
|
|
7
|
+
# @example Warn when a PR is classed as work in progress
|
|
8
|
+
#
|
|
9
|
+
# warn "PR is classed as Work in Progress" if bitbucket_server.pr_title.include? "[WIP]"
|
|
10
|
+
#
|
|
11
|
+
# @example Declare a PR to be simple to avoid specific Danger rules
|
|
12
|
+
#
|
|
13
|
+
# declared_trivial = (bitbucket_server.pr_title + bitbucket_server.pr_body).include?("#trivial")
|
|
14
|
+
#
|
|
15
|
+
# @example Ensure that labels have been used on the PR
|
|
16
|
+
#
|
|
17
|
+
# failure "Please add labels to this PR" if bitbucket_server.pr_labels.empty?
|
|
18
|
+
#
|
|
19
|
+
# @example Ensure there is a summary for a PR
|
|
20
|
+
#
|
|
21
|
+
# failure "Please provide a summary in the Pull Request description" if bitbucket_server.pr_body.length < 5
|
|
22
|
+
#
|
|
23
|
+
# @example Only accept PRs to the develop branch
|
|
24
|
+
#
|
|
25
|
+
# failure "Please re-submit this PR to develop, we may have already fixed your issue." if bitbucket_server.branch_for_base != "develop"
|
|
26
|
+
#
|
|
27
|
+
# @example Highlight when a celebrity makes a pull request
|
|
28
|
+
#
|
|
29
|
+
# message "Welcome, Danger." if bitbucket_server.pr_author == "dangermcshane"
|
|
30
|
+
#
|
|
31
|
+
# @example Ensure that all PRs have an assignee
|
|
32
|
+
#
|
|
33
|
+
# warn "This PR does not have any assignees yet." if bitbucket_server.pr_json[:reviewers].length == 0
|
|
34
|
+
#
|
|
35
|
+
# @example Send a message with links to a collection of specific files
|
|
36
|
+
#
|
|
37
|
+
# if git.modified_files.include? "config/*.js"
|
|
38
|
+
# config_files = git.modified_files.select { |path| path.include? "config/" }
|
|
39
|
+
# message "This PR changes #{ bitbucket_server.html_link(config_files) }"
|
|
40
|
+
# end
|
|
41
|
+
#
|
|
42
|
+
# @example Highlight with a clickable link if a Package.json is changed
|
|
43
|
+
#
|
|
44
|
+
# warn "#{bitbucket_server.html_link("Package.json")} was edited." if git.modified_files.include? "Package.json"
|
|
45
|
+
#
|
|
46
|
+
# @see danger/danger
|
|
47
|
+
# @tags core, bitbucket_server
|
|
48
|
+
#
|
|
49
|
+
class DangerfileBitbucketServerPlugin < Plugin
|
|
50
|
+
# So that this init can fail.
|
|
51
|
+
def self.new(dangerfile)
|
|
52
|
+
return nil if dangerfile.env.request_source.class != Danger::RequestSources::BitbucketServer
|
|
53
|
+
|
|
54
|
+
super
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# The instance name used in the Dangerfile
|
|
58
|
+
# @return [String]
|
|
59
|
+
#
|
|
60
|
+
def self.instance_name
|
|
61
|
+
"bitbucket_server"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def initialize(dangerfile)
|
|
65
|
+
super(dangerfile)
|
|
66
|
+
@bs = dangerfile.env.request_source
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @!group Bitbucket Server Misc
|
|
70
|
+
# The hash that represents the PR's JSON. For an example of what this looks like
|
|
71
|
+
# see the [Danger Fixture'd one](https://raw.githubusercontent.com/danger/danger/master/spec/fixtures/bitbucket_server_api/pr_response.json).
|
|
72
|
+
# @return [Hash]
|
|
73
|
+
def pr_json
|
|
74
|
+
@bs.pr_json
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @!group PR Metadata
|
|
78
|
+
# The title of the Pull Request.
|
|
79
|
+
# @return [String]
|
|
80
|
+
#
|
|
81
|
+
def pr_title
|
|
82
|
+
@bs.pr_json[:title].to_s
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# @!group PR Metadata
|
|
86
|
+
# The body text of the Pull Request.
|
|
87
|
+
# @return [String]
|
|
88
|
+
#
|
|
89
|
+
def pr_description
|
|
90
|
+
@bs.pr_json[:description].to_s
|
|
91
|
+
end
|
|
92
|
+
alias pr_body pr_description
|
|
93
|
+
|
|
94
|
+
# @!group PR Metadata
|
|
95
|
+
# The username of the author of the Pull Request.
|
|
96
|
+
# @return [String]
|
|
97
|
+
#
|
|
98
|
+
def pr_author
|
|
99
|
+
@bs.pr_json[:author][:user][:slug].to_s
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# @!group PR Commit Metadata
|
|
103
|
+
# The branch to which the PR is going to be merged into.
|
|
104
|
+
# @return [String]
|
|
105
|
+
#
|
|
106
|
+
def branch_for_base
|
|
107
|
+
@bs.pr_json[:toRef][:displayId].to_s
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# @!group PR Commit Metadata
|
|
111
|
+
# A href that represents the current PR
|
|
112
|
+
# @return [String]
|
|
113
|
+
#
|
|
114
|
+
def pr_link
|
|
115
|
+
@bs.pr_json[:links][:self].flat_map { |l| l[:href] }.first.to_s
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# @!group PR Commit Metadata
|
|
119
|
+
# The branch to which the PR is going to be merged from.
|
|
120
|
+
# @return [String]
|
|
121
|
+
#
|
|
122
|
+
def branch_for_head
|
|
123
|
+
@bs.pr_json[:fromRef][:displayId].to_s
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# @!group PR Commit Metadata
|
|
127
|
+
# The base commit to which the PR is going to be merged as a parent.
|
|
128
|
+
# @return [String]
|
|
129
|
+
#
|
|
130
|
+
def base_commit
|
|
131
|
+
@bs.pr_json[:toRef][:latestCommit].to_s
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# @!group PR Commit Metadata
|
|
135
|
+
# The head commit to which the PR is requesting to be merged from.
|
|
136
|
+
# @return [String]
|
|
137
|
+
#
|
|
138
|
+
def head_commit
|
|
139
|
+
@bs.pr_json[:fromRef][:latestCommit].to_s
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# @!group Bitbucket Server Misc
|
|
143
|
+
# Returns a list of Markdown links for a file, or files in the head repository.
|
|
144
|
+
# It returns a string of multiple anchors if passed an array.
|
|
145
|
+
# @note Atlassian [disabled inline HTML support](https://jira.atlassian.com/browse/BSERV-7147).
|
|
146
|
+
# This method method left for backward compatibility.
|
|
147
|
+
# @param [String or Array<String>] paths
|
|
148
|
+
# A list of strings to convert to github anchors
|
|
149
|
+
# @param [Bool] full_path
|
|
150
|
+
# Shows the full path as the link's text, defaults to `true`.
|
|
151
|
+
#
|
|
152
|
+
# @return [String]
|
|
153
|
+
#
|
|
154
|
+
def html_link(paths, full_path: true)
|
|
155
|
+
markdown_link(paths, full_path: full_path)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# @!group Bitbucket Server Misc
|
|
159
|
+
# Returns a list of Markdown links for a file, or files in the head repository.
|
|
160
|
+
# It returns a string of multiple links if passed an array.
|
|
161
|
+
# @param [String or Array<String>] paths
|
|
162
|
+
# A list of strings to convert to Markdown links
|
|
163
|
+
# @param [Bool] full_path
|
|
164
|
+
# Shows the full path as the link's text, defaults to `true`.
|
|
165
|
+
#
|
|
166
|
+
# @return [String]
|
|
167
|
+
#
|
|
168
|
+
def markdown_link(paths, full_path: true)
|
|
169
|
+
create_link(paths, full_path) { |href, text| create_markdown_link(href, text) }
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# @!group Bitbucket Server Misc
|
|
173
|
+
# Updates the PR with build status and build server job link.
|
|
174
|
+
# @param [String] status
|
|
175
|
+
# SUCCESSFUL, FAILED and INPROGRESS
|
|
176
|
+
# @param [String] build_job_link
|
|
177
|
+
# Build server job link
|
|
178
|
+
# @param [String] description
|
|
179
|
+
# Build status description
|
|
180
|
+
# @return [String]
|
|
181
|
+
#
|
|
182
|
+
def update_pr_build_status(status, build_job_link, description)
|
|
183
|
+
@bs.update_pr_build_status(status, build_job_link, description)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
private
|
|
187
|
+
|
|
188
|
+
def create_link(paths, full_path)
|
|
189
|
+
paths = [paths] unless paths.kind_of?(Array)
|
|
190
|
+
commit = head_commit
|
|
191
|
+
repo = pr_json[:fromRef][:repository][:links][:self].flat_map { |l| l[:href] }.first
|
|
192
|
+
|
|
193
|
+
paths = paths.map do |path|
|
|
194
|
+
path, line = path.split("#")
|
|
195
|
+
url_path = path.start_with?("/") ? path : "/#{path}"
|
|
196
|
+
text = full_path ? path : File.basename(path)
|
|
197
|
+
url_path.gsub!(" ", "%20")
|
|
198
|
+
line_ref = line ? "##{line}" : ""
|
|
199
|
+
yield("#{repo}#{url_path}?at=#{commit}#{line_ref}", text)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
return paths.first if paths.count < 2
|
|
203
|
+
|
|
204
|
+
paths.first(paths.count - 1).join(", ") + " & " + paths.last
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def create_markdown_link(href, text)
|
|
208
|
+
"[#{text}](#{href})"
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|