danger 8.0.4
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 +94 -0
- data/bin/danger +5 -0
- data/lib/assets/DangerfileTemplate +13 -0
- data/lib/danger.rb +44 -0
- data/lib/danger/ci_source/appcenter.rb +55 -0
- data/lib/danger/ci_source/appveyor.rb +60 -0
- data/lib/danger/ci_source/azure_pipelines.rb +44 -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 +65 -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 +57 -0
- data/lib/danger/ci_source/codefresh.rb +53 -0
- data/lib/danger/ci_source/codeship.rb +44 -0
- data/lib/danger/ci_source/dotci.rb +52 -0
- data/lib/danger/ci_source/drone.rb +71 -0
- data/lib/danger/ci_source/github_actions.rb +43 -0
- data/lib/danger/ci_source/gitlab_ci.rb +86 -0
- data/lib/danger/ci_source/jenkins.rb +149 -0
- data/lib/danger/ci_source/local_git_repo.rb +119 -0
- data/lib/danger/ci_source/local_only_git_repo.rb +47 -0
- data/lib/danger/ci_source/screwdriver.rb +47 -0
- data/lib/danger/ci_source/semaphore.rb +37 -0
- data/lib/danger/ci_source/support/commits.rb +17 -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 +42 -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 +179 -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 +161 -0
- data/lib/danger/ci_source/travis.rb +51 -0
- data/lib/danger/ci_source/vsts.rb +73 -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 +36 -0
- data/lib/danger/commands/local_helpers/local_setup.rb +46 -0
- data/lib/danger/commands/local_helpers/pry_setup.rb +31 -0
- data/lib/danger/commands/plugins/plugin_json.rb +46 -0
- data/lib/danger/commands/plugins/plugin_lint.rb +54 -0
- data/lib/danger/commands/plugins/plugin_readme.rb +45 -0
- data/lib/danger/commands/pr.rb +92 -0
- data/lib/danger/commands/runner.rb +94 -0
- data/lib/danger/commands/staging.rb +53 -0
- data/lib/danger/commands/systems.rb +43 -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 +26 -0
- data/lib/danger/comment_generators/vsts.md.erb +20 -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 +341 -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 +123 -0
- data/lib/danger/danger_core/executor.rb +92 -0
- data/lib/danger/danger_core/message_aggregator.rb +49 -0
- data/lib/danger/danger_core/message_group.rb +68 -0
- data/lib/danger/danger_core/messages/base.rb +56 -0
- data/lib/danger/danger_core/messages/markdown.rb +42 -0
- data/lib/danger/danger_core/messages/violation.rb +54 -0
- data/lib/danger/danger_core/plugins/dangerfile_bitbucket_cloud_plugin.rb +144 -0
- data/lib/danger/danger_core/plugins/dangerfile_bitbucket_server_plugin.rb +211 -0
- data/lib/danger/danger_core/plugins/dangerfile_danger_plugin.rb +248 -0
- data/lib/danger/danger_core/plugins/dangerfile_git_plugin.rb +158 -0
- data/lib/danger/danger_core/plugins/dangerfile_github_plugin.rb +254 -0
- data/lib/danger/danger_core/plugins/dangerfile_gitlab_plugin.rb +240 -0
- data/lib/danger/danger_core/plugins/dangerfile_local_only_plugin.rb +42 -0
- data/lib/danger/danger_core/plugins/dangerfile_messaging_plugin.rb +218 -0
- data/lib/danger/danger_core/plugins/dangerfile_vsts_plugin.rb +191 -0
- data/lib/danger/danger_core/standard_error.rb +143 -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 +178 -0
- data/lib/danger/helpers/comments_parsing_helper.rb +70 -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 +49 -0
- data/lib/danger/plugin_support/plugin_file_resolver.rb +30 -0
- data/lib/danger/plugin_support/plugin_linter.rb +161 -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 +171 -0
- data/lib/danger/request_sources/bitbucket_cloud_api.rb +181 -0
- data/lib/danger/request_sources/bitbucket_server.rb +105 -0
- data/lib/danger/request_sources/bitbucket_server_api.rb +117 -0
- data/lib/danger/request_sources/github/github.rb +530 -0
- data/lib/danger/request_sources/github/github_review.rb +126 -0
- data/lib/danger/request_sources/github/github_review_resolver.rb +19 -0
- data/lib/danger/request_sources/github/github_review_unsupported.rb +25 -0
- data/lib/danger/request_sources/gitlab.rb +525 -0
- data/lib/danger/request_sources/local_only.rb +53 -0
- data/lib/danger/request_sources/request_source.rb +85 -0
- data/lib/danger/request_sources/support/get_ignored_violation.rb +17 -0
- data/lib/danger/request_sources/vsts.rb +118 -0
- data/lib/danger/request_sources/vsts_api.rb +138 -0
- data/lib/danger/scm_source/git_repo.rb +181 -0
- data/lib/danger/version.rb +4 -0
- metadata +339 -0
@@ -0,0 +1,54 @@
|
|
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 = h * 17 + line.hash
|
33
|
+
h
|
34
|
+
end
|
35
|
+
|
36
|
+
def <=>(other)
|
37
|
+
types = VALID_TYPES + [:markdown]
|
38
|
+
order = types.index(type) <=> types.index(other.type)
|
39
|
+
return order unless order.zero?
|
40
|
+
|
41
|
+
compare_by_file_and_line(other)
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_s
|
45
|
+
extra = []
|
46
|
+
extra << "sticky: #{sticky}"
|
47
|
+
extra << "file: #{file}" if file
|
48
|
+
extra << "line: #{line}" if line
|
49
|
+
extra << "type: #{type}"
|
50
|
+
|
51
|
+
"Violation #{message} { #{extra.join ', '} }"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "danger/plugin_support/plugin"
|
4
|
+
|
5
|
+
module Danger
|
6
|
+
# Handles interacting with Bitbucket Cloud inside a Dangerfile. Provides a few functions which wrap `pr_json` and also
|
7
|
+
# through a few standard functions to simplify your code.
|
8
|
+
#
|
9
|
+
# @example Warn when a PR is classed as work in progress
|
10
|
+
#
|
11
|
+
# warn "PR is classed as Work in Progress" if bitbucket_cloud.pr_title.include? "[WIP]"
|
12
|
+
#
|
13
|
+
# @example Declare a PR to be simple to avoid specific Danger rules
|
14
|
+
#
|
15
|
+
# declared_trivial = (bitbucket_cloud.pr_title + bitbucket_cloud.pr_body).include?("#trivial")
|
16
|
+
#
|
17
|
+
# @example Ensure that labels have been used on the PR
|
18
|
+
#
|
19
|
+
# failure "Please add labels to this PR" if bitbucket_cloud.pr_labels.empty?
|
20
|
+
#
|
21
|
+
# @example Ensure there is a summary for a PR
|
22
|
+
#
|
23
|
+
# failure "Please provide a summary in the Pull Request description" if bitbucket_cloud.pr_body.length < 5
|
24
|
+
#
|
25
|
+
# @example Only accept PRs to the develop branch
|
26
|
+
#
|
27
|
+
# failure "Please re-submit this PR to develop, we may have already fixed your issue." if bitbucket_cloud.branch_for_base != "develop"
|
28
|
+
#
|
29
|
+
# @example Highlight when a celebrity makes a pull request
|
30
|
+
#
|
31
|
+
# message "Welcome, Danger." if bitbucket_cloud.pr_author == "dangermcshane"
|
32
|
+
#
|
33
|
+
# @example Ensure that all PRs have an assignee
|
34
|
+
#
|
35
|
+
# warn "This PR does not have any assignees yet." if bitbucket_cloud.pr_json[:reviewers].length == 0
|
36
|
+
#
|
37
|
+
# @example Send a message with links to a collection of specific files
|
38
|
+
#
|
39
|
+
# if git.modified_files.include? "config/*.js"
|
40
|
+
# config_files = git.modified_files.select { |path| path.include? "config/" }
|
41
|
+
# message "This PR changes #{ bitbucket_cloud.html_link(config_files) }"
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# @example Highlight with a clickable link if a Package.json is changed
|
45
|
+
#
|
46
|
+
# warn "#{bitbucket_cloud.html_link("Package.json")} was edited." if git.modified_files.include? "Package.json"
|
47
|
+
#
|
48
|
+
# @see danger/danger
|
49
|
+
# @tags core, bitbucket_cloud
|
50
|
+
#
|
51
|
+
class DangerfileBitbucketCloudPlugin < Plugin
|
52
|
+
# So that this init can fail.
|
53
|
+
def self.new(dangerfile)
|
54
|
+
return nil if dangerfile.env.request_source.class != Danger::RequestSources::BitbucketCloud
|
55
|
+
super
|
56
|
+
end
|
57
|
+
|
58
|
+
# The instance name used in the Dangerfile
|
59
|
+
# @return [String]
|
60
|
+
#
|
61
|
+
def self.instance_name
|
62
|
+
"bitbucket_cloud"
|
63
|
+
end
|
64
|
+
|
65
|
+
def initialize(dangerfile)
|
66
|
+
super(dangerfile)
|
67
|
+
@bs = dangerfile.env.request_source
|
68
|
+
end
|
69
|
+
|
70
|
+
# @!group Bitbucket Cloud Misc
|
71
|
+
# The hash that represents the PR's JSON. For an example of what this looks like
|
72
|
+
# see the [Danger Fixture'd one](https://raw.githubusercontent.com/danger/danger/master/spec/fixtures/bitbucket_cloud_api/pr_response.json).
|
73
|
+
# @return [Hash]
|
74
|
+
def pr_json
|
75
|
+
@bs.pr_json
|
76
|
+
end
|
77
|
+
|
78
|
+
# @!group PR Metadata
|
79
|
+
# The title of the Pull Request.
|
80
|
+
# @return [String]
|
81
|
+
#
|
82
|
+
def pr_title
|
83
|
+
@bs.pr_json[:title].to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
# @!group PR Metadata
|
87
|
+
# The body text of the Pull Request.
|
88
|
+
# @return [String]
|
89
|
+
#
|
90
|
+
def pr_description
|
91
|
+
@bs.pr_json[:description].to_s
|
92
|
+
end
|
93
|
+
alias pr_body pr_description
|
94
|
+
|
95
|
+
# @!group PR Metadata
|
96
|
+
# The username of the author of the Pull Request.
|
97
|
+
# @return [String]
|
98
|
+
#
|
99
|
+
def pr_author
|
100
|
+
@bs.pr_json[:author][:username]
|
101
|
+
end
|
102
|
+
|
103
|
+
# @!group PR Commit Metadata
|
104
|
+
# The branch to which the PR is going to be merged into.
|
105
|
+
# @return [String]
|
106
|
+
#
|
107
|
+
def branch_for_base
|
108
|
+
@bs.pr_json[:destination][:branch][:name]
|
109
|
+
end
|
110
|
+
|
111
|
+
# @!group PR Commit Metadata
|
112
|
+
# A href that represents the current PR
|
113
|
+
# @return [String]
|
114
|
+
#
|
115
|
+
def pr_link
|
116
|
+
@bs.pr_json[:links][:self][:href]
|
117
|
+
end
|
118
|
+
|
119
|
+
# @!group PR Commit Metadata
|
120
|
+
# The branch to which the PR is going to be merged from.
|
121
|
+
# @return [String]
|
122
|
+
#
|
123
|
+
def branch_for_head
|
124
|
+
@bs.pr_json[:source][:branch][:name]
|
125
|
+
end
|
126
|
+
|
127
|
+
# @!group PR Commit Metadata
|
128
|
+
# The base commit to which the PR is going to be merged as a parent.
|
129
|
+
# @return [String]
|
130
|
+
#
|
131
|
+
def base_commit
|
132
|
+
@bs.pr_json[:destination][:commit][:hash]
|
133
|
+
end
|
134
|
+
|
135
|
+
# @!group PR Commit Metadata
|
136
|
+
# The head commit to which the PR is requesting to be merged from.
|
137
|
+
# @return [String]
|
138
|
+
#
|
139
|
+
def head_commit
|
140
|
+
@bs.pr_json[:source][:commit][:hash]
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "danger/plugin_support/plugin"
|
4
|
+
|
5
|
+
module Danger
|
6
|
+
# Handles interacting with Bitbucket Server inside a Dangerfile. Provides a few functions which wrap `pr_json` and also
|
7
|
+
# through a few standard functions to simplify your code.
|
8
|
+
#
|
9
|
+
# @example Warn when a PR is classed as work in progress
|
10
|
+
#
|
11
|
+
# warn "PR is classed as Work in Progress" if bitbucket_server.pr_title.include? "[WIP]"
|
12
|
+
#
|
13
|
+
# @example Declare a PR to be simple to avoid specific Danger rules
|
14
|
+
#
|
15
|
+
# declared_trivial = (bitbucket_server.pr_title + bitbucket_server.pr_body).include?("#trivial")
|
16
|
+
#
|
17
|
+
# @example Ensure that labels have been used on the PR
|
18
|
+
#
|
19
|
+
# failure "Please add labels to this PR" if bitbucket_server.pr_labels.empty?
|
20
|
+
#
|
21
|
+
# @example Ensure there is a summary for a PR
|
22
|
+
#
|
23
|
+
# failure "Please provide a summary in the Pull Request description" if bitbucket_server.pr_body.length < 5
|
24
|
+
#
|
25
|
+
# @example Only accept PRs to the develop branch
|
26
|
+
#
|
27
|
+
# failure "Please re-submit this PR to develop, we may have already fixed your issue." if bitbucket_server.branch_for_base != "develop"
|
28
|
+
#
|
29
|
+
# @example Highlight when a celebrity makes a pull request
|
30
|
+
#
|
31
|
+
# message "Welcome, Danger." if bitbucket_server.pr_author == "dangermcshane"
|
32
|
+
#
|
33
|
+
# @example Ensure that all PRs have an assignee
|
34
|
+
#
|
35
|
+
# warn "This PR does not have any assignees yet." if bitbucket_server.pr_json[:reviewers].length == 0
|
36
|
+
#
|
37
|
+
# @example Send a message with links to a collection of specific files
|
38
|
+
#
|
39
|
+
# if git.modified_files.include? "config/*.js"
|
40
|
+
# config_files = git.modified_files.select { |path| path.include? "config/" }
|
41
|
+
# message "This PR changes #{ bitbucket_server.html_link(config_files) }"
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# @example Highlight with a clickable link if a Package.json is changed
|
45
|
+
#
|
46
|
+
# warn "#{bitbucket_server.html_link("Package.json")} was edited." if git.modified_files.include? "Package.json"
|
47
|
+
#
|
48
|
+
# @see danger/danger
|
49
|
+
# @tags core, bitbucket_server
|
50
|
+
#
|
51
|
+
class DangerfileBitbucketServerPlugin < Plugin
|
52
|
+
# So that this init can fail.
|
53
|
+
def self.new(dangerfile)
|
54
|
+
return nil if dangerfile.env.request_source.class != Danger::RequestSources::BitbucketServer
|
55
|
+
super
|
56
|
+
end
|
57
|
+
|
58
|
+
# The instance name used in the Dangerfile
|
59
|
+
# @return [String]
|
60
|
+
#
|
61
|
+
def self.instance_name
|
62
|
+
"bitbucket_server"
|
63
|
+
end
|
64
|
+
|
65
|
+
def initialize(dangerfile)
|
66
|
+
super(dangerfile)
|
67
|
+
@bs = dangerfile.env.request_source
|
68
|
+
end
|
69
|
+
|
70
|
+
# @!group Bitbucket Server Misc
|
71
|
+
# The hash that represents the PR's JSON. For an example of what this looks like
|
72
|
+
# see the [Danger Fixture'd one](https://raw.githubusercontent.com/danger/danger/master/spec/fixtures/bitbucket_server_api/pr_response.json).
|
73
|
+
# @return [Hash]
|
74
|
+
def pr_json
|
75
|
+
@bs.pr_json
|
76
|
+
end
|
77
|
+
|
78
|
+
# @!group PR Metadata
|
79
|
+
# The title of the Pull Request.
|
80
|
+
# @return [String]
|
81
|
+
#
|
82
|
+
def pr_title
|
83
|
+
@bs.pr_json[:title].to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
# @!group PR Metadata
|
87
|
+
# The body text of the Pull Request.
|
88
|
+
# @return [String]
|
89
|
+
#
|
90
|
+
def pr_description
|
91
|
+
@bs.pr_json[:description].to_s
|
92
|
+
end
|
93
|
+
alias pr_body pr_description
|
94
|
+
|
95
|
+
# @!group PR Metadata
|
96
|
+
# The username of the author of the Pull Request.
|
97
|
+
# @return [String]
|
98
|
+
#
|
99
|
+
def pr_author
|
100
|
+
@bs.pr_json[:author][:user][:slug].to_s
|
101
|
+
end
|
102
|
+
|
103
|
+
# @!group PR Commit Metadata
|
104
|
+
# The branch to which the PR is going to be merged into.
|
105
|
+
# @return [String]
|
106
|
+
#
|
107
|
+
def branch_for_base
|
108
|
+
@bs.pr_json[:toRef][:displayId].to_s
|
109
|
+
end
|
110
|
+
|
111
|
+
# @!group PR Commit Metadata
|
112
|
+
# A href that represents the current PR
|
113
|
+
# @return [String]
|
114
|
+
#
|
115
|
+
def pr_link
|
116
|
+
@bs.pr_json[:links][:self].flat_map { |l| l[:href] }.first.to_s
|
117
|
+
end
|
118
|
+
|
119
|
+
# @!group PR Commit Metadata
|
120
|
+
# The branch to which the PR is going to be merged from.
|
121
|
+
# @return [String]
|
122
|
+
#
|
123
|
+
def branch_for_head
|
124
|
+
@bs.pr_json[:fromRef][:displayId].to_s
|
125
|
+
end
|
126
|
+
|
127
|
+
# @!group PR Commit Metadata
|
128
|
+
# The base commit to which the PR is going to be merged as a parent.
|
129
|
+
# @return [String]
|
130
|
+
#
|
131
|
+
def base_commit
|
132
|
+
@bs.pr_json[:toRef][:latestCommit].to_s
|
133
|
+
end
|
134
|
+
|
135
|
+
# @!group PR Commit Metadata
|
136
|
+
# The head commit to which the PR is requesting to be merged from.
|
137
|
+
# @return [String]
|
138
|
+
#
|
139
|
+
def head_commit
|
140
|
+
@bs.pr_json[:fromRef][:latestCommit].to_s
|
141
|
+
end
|
142
|
+
|
143
|
+
# @!group Bitbucket Server Misc
|
144
|
+
# Returns a list of Markdown links for a file, or files in the head repository.
|
145
|
+
# It returns a string of multiple anchors if passed an array.
|
146
|
+
# @note Atlassian [disabled inline HTML support](https://jira.atlassian.com/browse/BSERV-7147).
|
147
|
+
# This method method left for backward compatibility.
|
148
|
+
# @param [String or Array<String>] paths
|
149
|
+
# A list of strings to convert to github anchors
|
150
|
+
# @param [Bool] full_path
|
151
|
+
# Shows the full path as the link's text, defaults to `true`.
|
152
|
+
#
|
153
|
+
# @return [String]
|
154
|
+
#
|
155
|
+
def html_link(paths, full_path: true)
|
156
|
+
markdown_link(paths, full_path: full_path)
|
157
|
+
end
|
158
|
+
|
159
|
+
# @!group Bitbucket Server Misc
|
160
|
+
# Returns a list of Markdown links for a file, or files in the head repository.
|
161
|
+
# It returns a string of multiple links if passed an array.
|
162
|
+
# @param [String or Array<String>] paths
|
163
|
+
# A list of strings to convert to Markdown links
|
164
|
+
# @param [Bool] full_path
|
165
|
+
# Shows the full path as the link's text, defaults to `true`.
|
166
|
+
#
|
167
|
+
# @return [String]
|
168
|
+
#
|
169
|
+
def markdown_link(paths, full_path: true)
|
170
|
+
create_link(paths, full_path) { |href, text| create_markdown_link(href, text) }
|
171
|
+
end
|
172
|
+
|
173
|
+
# @!group Bitbucket Server Misc
|
174
|
+
# Updates the PR with build status and build server job link.
|
175
|
+
# @param [String] status
|
176
|
+
# SUCCESSFUL, FAILED and INPROGRESS
|
177
|
+
# @param [String] build_job_link
|
178
|
+
# Build server job link
|
179
|
+
# @param [String] description
|
180
|
+
# Build status description
|
181
|
+
# @return [String]
|
182
|
+
#
|
183
|
+
def update_pr_build_status(status, build_job_link, description)
|
184
|
+
@bs.update_pr_build_status(status, build_job_link, description)
|
185
|
+
end
|
186
|
+
|
187
|
+
private
|
188
|
+
|
189
|
+
def create_link(paths, full_path)
|
190
|
+
paths = [paths] unless paths.kind_of?(Array)
|
191
|
+
commit = head_commit
|
192
|
+
repo = pr_json[:fromRef][:repository][:links][:self].flat_map { |l| l[:href] }.first
|
193
|
+
|
194
|
+
paths = paths.map do |path|
|
195
|
+
path, line = path.split("#")
|
196
|
+
url_path = path.start_with?("/") ? path : "/#{path}"
|
197
|
+
text = full_path ? path : File.basename(path)
|
198
|
+
url_path.gsub!(" ", "%20")
|
199
|
+
line_ref = line ? "##{line}" : ""
|
200
|
+
yield("#{repo}#{url_path}?at=#{commit}#{line_ref}", text)
|
201
|
+
end
|
202
|
+
|
203
|
+
return paths.first if paths.count < 2
|
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
|
@@ -0,0 +1,248 @@
|
|
1
|
+
require "danger/plugin_support/plugin"
|
2
|
+
|
3
|
+
module Danger
|
4
|
+
# A way to interact with Danger herself. Offering APIs to import plugins,
|
5
|
+
# and Dangerfiles from multiple sources.
|
6
|
+
#
|
7
|
+
# @example Import a plugin available over HTTP
|
8
|
+
#
|
9
|
+
# device_grid = "https://raw.githubusercontent.com/fastlane/fastlane/master/danger-device_grid/lib/device_grid/plugin.rb"
|
10
|
+
# danger.import_plugin(device_grid)
|
11
|
+
#
|
12
|
+
# @example Import from a local file reference
|
13
|
+
#
|
14
|
+
# danger.import_plugin("danger/plugins/watch_plugin.rb")
|
15
|
+
#
|
16
|
+
# @example Import all files inside a folder
|
17
|
+
#
|
18
|
+
# danger.import_plugin("danger/plugins/*.rb")
|
19
|
+
#
|
20
|
+
# @example Run a Dangerfile from inside a sub-folder
|
21
|
+
#
|
22
|
+
# danger.import_dangerfile(path: "path/to/Dangerfile")
|
23
|
+
#
|
24
|
+
# @example Run a Dangerfile from inside a gem
|
25
|
+
#
|
26
|
+
# danger.import_dangerfile(gem: "ruby-grape-danger")
|
27
|
+
#
|
28
|
+
# @example Run a Dangerfile from inside a repo
|
29
|
+
#
|
30
|
+
# danger.import_dangerfile(gitlab_project_id: 1345)
|
31
|
+
#
|
32
|
+
# @example Run a Dangerfile from inside a repo branch and path
|
33
|
+
#
|
34
|
+
# danger.import_dangerfile(github: "ruby-grape/danger", branch: "custom", path: "path/to/Dangerfile")
|
35
|
+
#
|
36
|
+
# @see danger/danger
|
37
|
+
# @tags core, plugins
|
38
|
+
|
39
|
+
class DangerfileDangerPlugin < Plugin
|
40
|
+
# The instance name used in the Dangerfile
|
41
|
+
# @return [String]
|
42
|
+
#
|
43
|
+
def self.instance_name
|
44
|
+
"danger"
|
45
|
+
end
|
46
|
+
|
47
|
+
# @!group Danger
|
48
|
+
# Download a local or remote plugin and make it usable inside the Dangerfile.
|
49
|
+
#
|
50
|
+
# @param [String] path_or_url
|
51
|
+
# a local path or a https URL to the Ruby file to import
|
52
|
+
# a danger plugin from.
|
53
|
+
# @return [void]
|
54
|
+
#
|
55
|
+
def import_plugin(path_or_url)
|
56
|
+
raise "`import_plugin` requires a string" unless path_or_url.kind_of?(String)
|
57
|
+
|
58
|
+
if path_or_url.start_with?("http")
|
59
|
+
import_url(path_or_url)
|
60
|
+
else
|
61
|
+
import_local(path_or_url)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# @!group Danger
|
66
|
+
# Import a Dangerfile.
|
67
|
+
#
|
68
|
+
# @param [Hash] opts
|
69
|
+
# @option opts [String] :github GitHub repo
|
70
|
+
# @option opts [String] :gitlab GitLab repo
|
71
|
+
# @option opts [String] :gem Gem name
|
72
|
+
# @option opts [String] :path Path to Dangerfile
|
73
|
+
# @return [void]
|
74
|
+
def import_dangerfile(opts)
|
75
|
+
if opts.kind_of?(String)
|
76
|
+
warn "Use `import_dangerfile(github: '#{opts}')` instead of `import_dangerfile '#{opts}'`."
|
77
|
+
import_dangerfile_from_github(opts)
|
78
|
+
elsif opts.kind_of?(Hash)
|
79
|
+
if opts.key?(:github)
|
80
|
+
import_dangerfile_from_github(opts[:github], opts[:branch], opts[:path])
|
81
|
+
elsif opts.key?(:gitlab)
|
82
|
+
import_dangerfile_from_gitlab(opts[:gitlab], opts[:branch], opts[:path])
|
83
|
+
elsif opts.key?(:path)
|
84
|
+
import_dangerfile_from_path(opts[:path])
|
85
|
+
elsif opts.key?(:gem)
|
86
|
+
import_dangerfile_from_gem(opts[:gem])
|
87
|
+
else
|
88
|
+
raise "`import` requires a Hash with either :github, :gitlab, :gem, or :path"
|
89
|
+
end
|
90
|
+
else
|
91
|
+
raise "`import` requires a Hash"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# @!group Danger
|
96
|
+
# Returns the name of the current SCM Provider being used.
|
97
|
+
# @return [Symbol] The name of the SCM Provider used for the active repository.
|
98
|
+
def scm_provider
|
99
|
+
return :unknown unless env.request_source
|
100
|
+
|
101
|
+
case env.request_source
|
102
|
+
when Danger::RequestSources::GitHub
|
103
|
+
:github
|
104
|
+
when Danger::RequestSources::GitLab
|
105
|
+
:gitlab
|
106
|
+
when Danger::RequestSources::BitbucketServer
|
107
|
+
:bitbucket_server
|
108
|
+
when Danger::RequestSources::BitbucketCloud
|
109
|
+
:bitbucket_cloud
|
110
|
+
when Danger::RequestSources::VSTS
|
111
|
+
:vsts
|
112
|
+
else
|
113
|
+
:unknown
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
# @!group Danger
|
120
|
+
# Read and execute a local Dangerfile.
|
121
|
+
#
|
122
|
+
# @param [String] path
|
123
|
+
# A path to a Dangerfile.
|
124
|
+
# @return [void]
|
125
|
+
#
|
126
|
+
def import_dangerfile_from_path(path)
|
127
|
+
raise "`import_dangerfile_from_path` requires a string" unless path.kind_of?(String)
|
128
|
+
local_path = File.join(path, "Dangerfile")
|
129
|
+
@dangerfile.parse(Pathname.new(local_path))
|
130
|
+
end
|
131
|
+
|
132
|
+
# @!group Danger
|
133
|
+
# Read and execute a Dangerfile from a gem.
|
134
|
+
#
|
135
|
+
# @param [String] name
|
136
|
+
# The name of the gem that contains a Dangerfile.
|
137
|
+
# @return [void]
|
138
|
+
#
|
139
|
+
def import_dangerfile_from_gem(name)
|
140
|
+
raise "`import_dangerfile_from_gem` requires a string" unless name.kind_of?(String)
|
141
|
+
spec = Gem::Specification.find_by_name(name)
|
142
|
+
import_dangerfile_from_path(spec.gem_dir)
|
143
|
+
rescue Gem::MissingSpecError
|
144
|
+
raise "`import_dangerfile_from_gem` tried to load `#{name}` and failed, did you forget to include it in your Gemfile?"
|
145
|
+
end
|
146
|
+
|
147
|
+
# @!group Danger
|
148
|
+
# Download and execute a remote Dangerfile.
|
149
|
+
#
|
150
|
+
# @param [String] slug
|
151
|
+
# A slug that represents the repo where the Dangerfile is.
|
152
|
+
# @param [String] branch
|
153
|
+
# A branch from repo where the Dangerfile is.
|
154
|
+
# @param [String] path
|
155
|
+
# The path at the repo where Dangerfile is.
|
156
|
+
# @return [void]
|
157
|
+
#
|
158
|
+
def import_dangerfile_from_github(slug, branch = nil, path = nil)
|
159
|
+
raise "`import_dangerfile_from_github` requires a string" unless slug.kind_of?(String)
|
160
|
+
org, repo = slug.split("/")
|
161
|
+
download_url = env.request_source.file_url(organisation: org, repository: repo, branch: branch, path: path || "Dangerfile")
|
162
|
+
local_path = download(download_url)
|
163
|
+
@dangerfile.parse(Pathname.new(local_path))
|
164
|
+
end
|
165
|
+
|
166
|
+
# @!group Danger
|
167
|
+
# Download and execute a remote Dangerfile.
|
168
|
+
#
|
169
|
+
# @param [Int] slug_or_project_id
|
170
|
+
# The slug or id of the repo where the Dangerfile is.
|
171
|
+
# @param [String] branch
|
172
|
+
# A branch from repo where the Dangerfile is.
|
173
|
+
# @param [String] path
|
174
|
+
# The path at the repo where Dangerfile is.
|
175
|
+
# @return [void]
|
176
|
+
#
|
177
|
+
def import_dangerfile_from_gitlab(slug_or_project_id, branch = nil, path = nil)
|
178
|
+
download_url = env.request_source.file_url(repository: slug_or_project_id, branch: branch, path: path || "Dangerfile")
|
179
|
+
local_path = download(download_url)
|
180
|
+
@dangerfile.parse(Pathname.new(local_path))
|
181
|
+
end
|
182
|
+
|
183
|
+
# @!group Plugins
|
184
|
+
# Download a local or remote plugin or Dangerfile.
|
185
|
+
# This method will not import the file for you, use plugin.import instead
|
186
|
+
#
|
187
|
+
# @param [String] path_or_url
|
188
|
+
# a local path or a https URL to the Ruby file to import
|
189
|
+
# a danger plugin from.
|
190
|
+
# @return [String] The path to the downloaded Ruby file
|
191
|
+
#
|
192
|
+
def download(path_or_url)
|
193
|
+
raise "`download` requires a string" unless path_or_url.kind_of?(String)
|
194
|
+
raise "URL is not https, for security reasons `danger` only supports encrypted requests" if URI.parse(path_or_url).scheme != "https"
|
195
|
+
|
196
|
+
require "tmpdir"
|
197
|
+
require "faraday"
|
198
|
+
|
199
|
+
@http_client ||= Faraday.new do |b|
|
200
|
+
b.adapter :net_http
|
201
|
+
end
|
202
|
+
content = @http_client.get(path_or_url)
|
203
|
+
|
204
|
+
path = File.join(Dir.mktmpdir, "temporary_danger.rb")
|
205
|
+
File.write(path, content.body)
|
206
|
+
return path
|
207
|
+
end
|
208
|
+
|
209
|
+
# @!group Plugins
|
210
|
+
# Download a remote plugin and use it locally.
|
211
|
+
#
|
212
|
+
# @param [String] url
|
213
|
+
# https URL to the Ruby file to use
|
214
|
+
# @return [void]
|
215
|
+
def import_url(url)
|
216
|
+
path = download(url)
|
217
|
+
import_local(path)
|
218
|
+
end
|
219
|
+
|
220
|
+
# @!group Plugins
|
221
|
+
# Import one or more local plugins.
|
222
|
+
#
|
223
|
+
# @param [String] path
|
224
|
+
# The path to the file to import
|
225
|
+
# Can also be a pattern (./**/*plugin.rb)
|
226
|
+
# @return [void]
|
227
|
+
def import_local(path)
|
228
|
+
Dir[path].each do |file|
|
229
|
+
validate_file_contains_plugin!(file) do
|
230
|
+
# Without the expand_path it would fail if the path doesn't start with ./
|
231
|
+
require File.expand_path(file)
|
232
|
+
end
|
233
|
+
|
234
|
+
refresh_plugins
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
# Raises an error when the given block does not register a plugin.
|
239
|
+
def validate_file_contains_plugin!(file)
|
240
|
+
plugin_count_was = Danger::Plugin.all_plugins.length
|
241
|
+
yield
|
242
|
+
|
243
|
+
if Danger::Plugin.all_plugins.length == plugin_count_was
|
244
|
+
raise("#{file} doesn't contain any valid danger plugins.")
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|