danger 3.4.2 → 3.5.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 +4 -4
- data/lib/danger/ci_source/local_git_repo.rb +79 -21
- 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 +27 -0
- data/lib/danger/ci_source/support/local_pull_request.rb +20 -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/{merged_pull_request_finder.rb → pull_request_finder.rb} +71 -44
- 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/commands/dangerfile/gem.rb +43 -0
- data/lib/danger/commands/dangerfile/init.rb +30 -0
- data/lib/danger/commands/init.rb +2 -2
- data/lib/danger/commands/pr.rb +116 -0
- data/lib/danger/commands/runner.rb +4 -0
- data/lib/danger/commands/systems.rb +6 -4
- data/lib/danger/danger_core/dangerfile_generator.rb +11 -0
- data/lib/danger/request_sources/github.rb +4 -2
- data/lib/danger/request_sources/gitlab.rb +8 -4
- data/lib/danger/version.rb +1 -1
- metadata +20 -10
- data/lib/assets/PluginTemplate.rb.template +0 -20
- data/lib/danger/ci_source/support/remote_finder.rb +0 -26
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 37784ac6404c19b342dc3a50d908829d1b8e36dc
|
|
4
|
+
data.tar.gz: 476f09de2a6458bd6becf741a69879fab68187e0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dfc58b28a778b604f9a54a739d56ab6eb3d3f1a2c54073a6dc5a877a2b6a0936bef78dfdc11c541f353d9bc81f76492bec438a21da115c9401efe8dcd70cd1c2
|
|
7
|
+
data.tar.gz: 2dd2c369fe8cb209b38d9ca9f360906585ac3f9f4b6401e1c6a03ec1c3902bdf088a531862fb69e3aa391638683ff76fc48e86a2fdec4bc9a64317e86763cc09
|
|
@@ -2,10 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
require "git"
|
|
4
4
|
require "uri"
|
|
5
|
-
|
|
6
|
-
require "danger/ci_source/support/merged_pull_request_finder"
|
|
5
|
+
|
|
7
6
|
require "danger/request_sources/github"
|
|
8
7
|
|
|
8
|
+
require "danger/ci_source/support/find_repo_info_from_url"
|
|
9
|
+
require "danger/ci_source/support/find_repo_info_from_logs"
|
|
10
|
+
require "danger/ci_source/support/no_repo_info"
|
|
11
|
+
require "danger/ci_source/support/pull_request_finder"
|
|
12
|
+
require "danger/ci_source/support/commits"
|
|
13
|
+
|
|
9
14
|
module Danger
|
|
10
15
|
# ignore
|
|
11
16
|
class LocalGitRepo < CI
|
|
@@ -31,29 +36,82 @@ module Danger
|
|
|
31
36
|
@supported_request_sources ||= [Danger::RequestSources::GitHub]
|
|
32
37
|
end
|
|
33
38
|
|
|
34
|
-
def
|
|
35
|
-
|
|
39
|
+
def initialize(env = {})
|
|
40
|
+
@env = env
|
|
41
|
+
|
|
42
|
+
self.repo_slug = remote_info.slug
|
|
43
|
+
raise_error_for_missing_remote if remote_info.kind_of?(NoRepoInfo)
|
|
44
|
+
|
|
45
|
+
self.pull_request_id = found_pull_request.pull_request_id
|
|
46
|
+
|
|
47
|
+
if sha
|
|
48
|
+
self.base_commit = commits.base
|
|
49
|
+
self.head_commit = commits.head
|
|
50
|
+
else
|
|
51
|
+
self.base_commit = found_pull_request.base
|
|
52
|
+
self.head_commit = found_pull_request.head
|
|
53
|
+
end
|
|
36
54
|
end
|
|
37
55
|
|
|
38
|
-
|
|
39
|
-
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
attr_reader :env
|
|
59
|
+
|
|
60
|
+
def raise_error_for_missing_remote
|
|
61
|
+
raise missing_remote_error_message
|
|
40
62
|
end
|
|
41
63
|
|
|
42
|
-
def
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
64
|
+
def missing_remote_error_message
|
|
65
|
+
"danger cannot find your git remote, please set a remote. " \
|
|
66
|
+
"And the repository must host on GitHub.com or GitHub Enterprise."
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def remote_info
|
|
70
|
+
@_remote_info ||= begin
|
|
71
|
+
remote_info = begin
|
|
72
|
+
if given_pull_request_url?
|
|
73
|
+
FindRepoInfoFromURL.new(env["LOCAL_GIT_PR_URL"]).call
|
|
74
|
+
else
|
|
75
|
+
FindRepoInfoFromLogs.new(
|
|
76
|
+
env["DANGER_GITHUB_HOST"] || "github.com".freeze,
|
|
77
|
+
run_git("remote show origin -n".freeze)
|
|
78
|
+
).call
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
remote_info || NoRepoInfo.new
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def found_pull_request
|
|
87
|
+
@_found_pull_request ||= begin
|
|
88
|
+
if given_pull_request_url?
|
|
89
|
+
PullRequestFinder.new(
|
|
90
|
+
remote_info.id,
|
|
91
|
+
remote_info.slug,
|
|
92
|
+
remote: true
|
|
93
|
+
).call
|
|
94
|
+
else
|
|
95
|
+
PullRequestFinder.new(
|
|
96
|
+
env.fetch("LOCAL_GIT_PR_ID") { "".freeze },
|
|
97
|
+
remote_info.slug,
|
|
98
|
+
remote: false,
|
|
99
|
+
git_logs: run_git("log --oneline -1000000".freeze)
|
|
100
|
+
).call
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def given_pull_request_url?
|
|
106
|
+
env["LOCAL_GIT_PR_URL"] && !env["LOCAL_GIT_PR_URL"].empty?
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def sha
|
|
110
|
+
@_sha ||= found_pull_request.sha
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def commits
|
|
114
|
+
@_commits ||= Commits.new(run_git("rev-list --parents -n 1 #{sha}"))
|
|
57
115
|
end
|
|
58
116
|
end
|
|
59
117
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require "danger/ci_source/support/repo_info"
|
|
2
|
+
|
|
3
|
+
module Danger
|
|
4
|
+
class FindRepoInfoFromLogs
|
|
5
|
+
def initialize(github_host, remote_logs)
|
|
6
|
+
@github_host = github_host
|
|
7
|
+
@remote_logs = remote_logs
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call
|
|
11
|
+
matched = remote.match(regexp)
|
|
12
|
+
|
|
13
|
+
if matched
|
|
14
|
+
RepoInfo.new(matched["repo_slug"], nil)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
attr_reader :remote_logs, :github_host
|
|
21
|
+
|
|
22
|
+
def remote
|
|
23
|
+
remote_logs.lines.grep(/Fetch URL/)[0].split(": ".freeze, 2)[1]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def regexp
|
|
27
|
+
%r{
|
|
28
|
+
#{Regexp.escape(github_host)}
|
|
29
|
+
(:|/|(:/))
|
|
30
|
+
(?<repo_slug>[^/]+/.+?)
|
|
31
|
+
(?:\.git)?$
|
|
32
|
+
}x
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require "danger/ci_source/support/repo_info"
|
|
2
|
+
|
|
3
|
+
module Danger
|
|
4
|
+
class FindRepoInfoFromURL
|
|
5
|
+
REGEXP = %r{
|
|
6
|
+
(?<slug>[^/]+/[^/]+)
|
|
7
|
+
(/(pull|merge_requests|pull-requests)/)
|
|
8
|
+
(?<id>\d+)
|
|
9
|
+
}x
|
|
10
|
+
|
|
11
|
+
def initialize(url)
|
|
12
|
+
@url = url
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def call
|
|
16
|
+
matched = url.match(REGEXP)
|
|
17
|
+
|
|
18
|
+
if matched
|
|
19
|
+
RepoInfo.new(matched[:slug], matched[:id])
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
attr_reader :url
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Danger
|
|
2
|
+
class LocalPullRequest
|
|
3
|
+
attr_reader :pull_request_id, :sha
|
|
4
|
+
|
|
5
|
+
def initialize(log_line)
|
|
6
|
+
@log_line = log_line
|
|
7
|
+
|
|
8
|
+
@pull_request_id = log_line.match(/#(?<id>[0-9]+)/)[:id]
|
|
9
|
+
@sha = log_line.split(" ".freeze).first
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def valid?
|
|
13
|
+
pull_request_id && sha
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
attr_reader :log_line
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -1,25 +1,82 @@
|
|
|
1
|
+
require "danger/ci_source/support/local_pull_request"
|
|
2
|
+
require "danger/ci_source/support/remote_pull_request"
|
|
3
|
+
require "danger/ci_source/support/no_pull_request"
|
|
4
|
+
|
|
1
5
|
module Danger
|
|
2
|
-
class
|
|
3
|
-
def initialize(specific_pull_request_id, git_logs)
|
|
6
|
+
class PullRequestFinder
|
|
7
|
+
def initialize(specific_pull_request_id, repo_slug = nil, remote: false, git_logs: "")
|
|
4
8
|
@specific_pull_request_id = specific_pull_request_id
|
|
5
9
|
@git_logs = git_logs
|
|
10
|
+
@repo_slug = repo_slug
|
|
11
|
+
@remote = to_boolean(remote)
|
|
6
12
|
end
|
|
7
13
|
|
|
8
14
|
def call
|
|
9
|
-
|
|
15
|
+
check_if_any_pull_request!
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
pull_request
|
|
12
18
|
end
|
|
13
19
|
|
|
14
20
|
private
|
|
15
21
|
|
|
16
|
-
attr_reader :specific_pull_request_id, :git_logs
|
|
22
|
+
attr_reader :specific_pull_request_id, :git_logs, :repo_slug, :remote
|
|
23
|
+
|
|
24
|
+
def to_boolean(maybe_string)
|
|
25
|
+
if ["true", "1", "yes", "y", true].include?(maybe_string)
|
|
26
|
+
true
|
|
27
|
+
else
|
|
28
|
+
false
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def check_if_any_pull_request!
|
|
33
|
+
unless pull_request.valid?
|
|
34
|
+
if !specific_pull_request_id.empty?
|
|
35
|
+
raise "Could not find the Pull Request (#{specific_pull_request_id}) inside the git history for this repo."
|
|
36
|
+
else
|
|
37
|
+
raise "No recent Pull Requests found for this repo, danger requires at least one Pull Request for the local mode.".freeze
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @return [String] Log line of most recent merged Pull Request
|
|
43
|
+
def pull_request
|
|
44
|
+
@pull_request ||= begin
|
|
45
|
+
return if pull_request_ref.empty?
|
|
46
|
+
|
|
47
|
+
if both_present?
|
|
48
|
+
LocalPullRequest.new(pick_the_most_recent_one_from_two_matches)
|
|
49
|
+
elsif only_merged_pull_request_present?
|
|
50
|
+
LocalPullRequest.new(most_recent_merged_pull_request)
|
|
51
|
+
elsif only_squash_and_merged_pull_request_present?
|
|
52
|
+
LocalPullRequest.new(most_recent_squash_and_merged_pull_request)
|
|
53
|
+
elsif remote && remote_pull_request
|
|
54
|
+
RemotePullRequest.new(
|
|
55
|
+
remote_pull_request.number.to_s,
|
|
56
|
+
remote_pull_request.head.sha,
|
|
57
|
+
remote_pull_request.base.sha
|
|
58
|
+
)
|
|
59
|
+
else
|
|
60
|
+
NoPullRequest.new
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
17
64
|
|
|
18
65
|
# @return [String] "#42"
|
|
19
66
|
def pull_request_ref
|
|
20
67
|
!specific_pull_request_id.empty? ? "##{specific_pull_request_id}" : "#\\d+".freeze
|
|
21
68
|
end
|
|
22
69
|
|
|
70
|
+
def remote_pull_request
|
|
71
|
+
@_remote_pull_request ||= begin
|
|
72
|
+
client.pull_request(repo_slug, specific_pull_request_id)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def both_present?
|
|
77
|
+
most_recent_merged_pull_request && most_recent_squash_and_merged_pull_request
|
|
78
|
+
end
|
|
79
|
+
|
|
23
80
|
# @return [String] Log line of format: "Merge pull request #42"
|
|
24
81
|
def most_recent_merged_pull_request
|
|
25
82
|
@most_recent_merged_pull_request ||= begin
|
|
@@ -34,23 +91,17 @@ module Danger
|
|
|
34
91
|
end
|
|
35
92
|
end
|
|
36
93
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
94
|
+
def pick_the_most_recent_one_from_two_matches
|
|
95
|
+
merged_index = git_logs.lines.index(most_recent_merged_pull_request)
|
|
96
|
+
squash_and_merged_index = git_logs.lines.index(most_recent_squash_and_merged_pull_request)
|
|
40
97
|
|
|
41
|
-
if
|
|
42
|
-
pick_the_most_recent_one_from_two_matches
|
|
43
|
-
elsif only_merged_pull_request_present?
|
|
44
|
-
most_recent_merged_pull_request
|
|
45
|
-
elsif only_squash_and_merged_pull_request_present?
|
|
98
|
+
if merged_index > squash_and_merged_index # smaller index is more recent
|
|
46
99
|
most_recent_squash_and_merged_pull_request
|
|
100
|
+
else
|
|
101
|
+
most_recent_merged_pull_request
|
|
47
102
|
end
|
|
48
103
|
end
|
|
49
104
|
|
|
50
|
-
def both_present?
|
|
51
|
-
most_recent_merged_pull_request && most_recent_squash_and_merged_pull_request
|
|
52
|
-
end
|
|
53
|
-
|
|
54
105
|
def only_merged_pull_request_present?
|
|
55
106
|
return false if most_recent_squash_and_merged_pull_request
|
|
56
107
|
|
|
@@ -63,33 +114,9 @@ module Danger
|
|
|
63
114
|
!most_recent_squash_and_merged_pull_request.nil? && !most_recent_squash_and_merged_pull_request.empty?
|
|
64
115
|
end
|
|
65
116
|
|
|
66
|
-
def
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if merged_index > squash_and_merged_index # smaller index is more recent
|
|
71
|
-
most_recent_squash_and_merged_pull_request
|
|
72
|
-
else
|
|
73
|
-
most_recent_merged_pull_request
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def check_if_any_merged_pull_request!
|
|
78
|
-
if merged_pull_request.to_s.empty?
|
|
79
|
-
if !specific_pull_request_id.empty?
|
|
80
|
-
raise "Could not find the Pull Request (#{specific_pull_request_id}) inside the git history for this repo."
|
|
81
|
-
else
|
|
82
|
-
raise "No recent Pull Requests found for this repo, danger requires at least one Pull Request for the local mode.".freeze
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def merged_pull_request_id
|
|
88
|
-
merged_pull_request.match(/#(?<id>[0-9]+)/)[:id]
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def merged_pull_request_sha
|
|
92
|
-
merged_pull_request.split(" ".freeze).first
|
|
117
|
+
def client
|
|
118
|
+
require "octokit"
|
|
119
|
+
Octokit::Client.new(access_token: ENV["DANGER_GITHUB_API_TOKEN"])
|
|
93
120
|
end
|
|
94
121
|
end
|
|
95
122
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Danger
|
|
2
|
+
class RemotePullRequest
|
|
3
|
+
attr_reader :pull_request_id, :sha, :head, :base
|
|
4
|
+
|
|
5
|
+
def initialize(pull_request_id, head, base)
|
|
6
|
+
@pull_request_id = pull_request_id
|
|
7
|
+
@head = head
|
|
8
|
+
@base = base
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def valid?
|
|
12
|
+
pull_request_id && head && base
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require "claide_plugin"
|
|
2
|
+
require "danger/commands/dangerfile/init"
|
|
3
|
+
|
|
4
|
+
module Danger
|
|
5
|
+
class DangerfileGem < DangerfileCommand
|
|
6
|
+
self.summary = "Create a gem-based Dangerfile quickly."
|
|
7
|
+
def self.description
|
|
8
|
+
<<-DESC
|
|
9
|
+
Creates a scaffold for the development of a new gem based Dangerfile
|
|
10
|
+
named `NAME` according to the best practices.
|
|
11
|
+
DESC
|
|
12
|
+
end
|
|
13
|
+
self.command = "gem"
|
|
14
|
+
self.arguments = [
|
|
15
|
+
CLAide::Argument.new("NAME", true)
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
def initialize(argv)
|
|
19
|
+
@name = argv.shift_argument
|
|
20
|
+
prefix = "dangerfile" + "-"
|
|
21
|
+
unless @name.nil? || @name.empty? || @name.start_with?(prefix)
|
|
22
|
+
@name = prefix + @name.dup
|
|
23
|
+
end
|
|
24
|
+
@template_url = argv.shift_argument
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def validate!
|
|
29
|
+
super
|
|
30
|
+
if @name.nil? || @name.empty?
|
|
31
|
+
help! "A name for the plugin is required."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
help! "The plugin name cannot contain spaces." if @name =~ /\s/
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def run
|
|
38
|
+
runner = CLAide::TemplateRunner.new(@name, "https://github.com/danger/dangerfile-gem-template")
|
|
39
|
+
runner.clone_template
|
|
40
|
+
runner.configure_template
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require "danger/danger_core/dangerfile_generator"
|
|
2
|
+
|
|
3
|
+
# Mainly so we can have a nice strucutre for commands
|
|
4
|
+
|
|
5
|
+
module Danger
|
|
6
|
+
class DangerfileCommand < Runner
|
|
7
|
+
self.summary = "Easily create you Dangerfiles."
|
|
8
|
+
self.command = "dangerfile"
|
|
9
|
+
|
|
10
|
+
self.abstract_command = true
|
|
11
|
+
def self.options
|
|
12
|
+
[]
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Just a less verbose way of doing the Dangerfile from `danger init`.
|
|
18
|
+
|
|
19
|
+
module Danger
|
|
20
|
+
class DangerfileInit < DangerfileCommand
|
|
21
|
+
self.summary = "Create an example Dangerfile."
|
|
22
|
+
self.command = "init"
|
|
23
|
+
|
|
24
|
+
def run
|
|
25
|
+
content = DangerfileGenerator.create_dangerfile(".", cork)
|
|
26
|
+
File.write("Dangerfile", content)
|
|
27
|
+
cork.puts "Created" + "./Dangerfile".green
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/danger/commands/init.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require "danger/commands/init_helpers/interviewer"
|
|
2
|
+
require "danger/danger_core/dangerfile_generator"
|
|
2
3
|
require "danger/ci_source/local_git_repo"
|
|
3
4
|
require "yaml"
|
|
4
5
|
|
|
@@ -53,8 +54,7 @@ module Danger
|
|
|
53
54
|
end
|
|
54
55
|
|
|
55
56
|
def setup_dangerfile
|
|
56
|
-
|
|
57
|
-
content = File.read(File.join(dir, "lib", "assets", "DangerfileTemplate"))
|
|
57
|
+
content = DangerfileGenerator.create_dangerfile(".", cork)
|
|
58
58
|
File.write("Dangerfile", content)
|
|
59
59
|
|
|
60
60
|
ui.header "Step 1: Creating a starter Dangerfile"
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
require "danger/commands/local_helpers/http_cache"
|
|
2
|
+
require "faraday/http_cache"
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "octokit"
|
|
5
|
+
require "tmpdir"
|
|
6
|
+
|
|
7
|
+
module Danger
|
|
8
|
+
class PR < Runner
|
|
9
|
+
self.summary = "Run the Dangerfile against Pull Requests (works with forks, too).".freeze
|
|
10
|
+
self.command = "pr".freeze
|
|
11
|
+
|
|
12
|
+
def self.options
|
|
13
|
+
[
|
|
14
|
+
["--use-pr=[#id]", "The URL of the Pull Request for the command to run."],
|
|
15
|
+
["--clear-http-cache", "Clear the local http cache before running Danger locally."],
|
|
16
|
+
["--pry", "Drop into a Pry shell after evaluating the Dangerfile."]
|
|
17
|
+
]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def initialize(argv)
|
|
21
|
+
@pr_url = argv.option("use-pr")
|
|
22
|
+
@clear_http_cache = argv.flag?("clear-http-cache", false)
|
|
23
|
+
|
|
24
|
+
super
|
|
25
|
+
|
|
26
|
+
setup_pry if should_pry?(argv)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def should_pry?(argv)
|
|
30
|
+
argv.flag?("pry", false) && !@dangerfile_path.empty? && validate_pry_available
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def setup_pry
|
|
34
|
+
File.delete "_Dangerfile.tmp" if File.exist? "_Dangerfile.tmp"
|
|
35
|
+
FileUtils.cp @dangerfile_path, "_Dangerfile.tmp"
|
|
36
|
+
File.open("_Dangerfile.tmp", "a") do |f|
|
|
37
|
+
f.write("binding.pry; File.delete(\"_Dangerfile.tmp\")")
|
|
38
|
+
end
|
|
39
|
+
@dangerfile_path = "_Dangerfile.tmp"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def validate_pry_available
|
|
43
|
+
require "pry"
|
|
44
|
+
rescue LoadError
|
|
45
|
+
cork.warn "Pry was not found, and is required for 'danger pr --pry'."
|
|
46
|
+
cork.print_warnings
|
|
47
|
+
abort
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def validate!
|
|
51
|
+
super
|
|
52
|
+
unless @dangerfile_path
|
|
53
|
+
help! "Could not find a Dangerfile."
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def run
|
|
58
|
+
ENV["DANGER_USE_LOCAL_GIT"] = "YES"
|
|
59
|
+
ENV["LOCAL_GIT_PR_URL"] = @pr_url if @pr_url
|
|
60
|
+
|
|
61
|
+
# setup caching for Github calls to hitting the API rate limit too quickly
|
|
62
|
+
cache_file = File.join(ENV["DANGER_TMPDIR"] || Dir.tmpdir, "danger_local_cache")
|
|
63
|
+
cache = HTTPCache.new(cache_file, clear_cache: @clear_http_cache)
|
|
64
|
+
Octokit.middleware = Faraday::RackBuilder.new do |builder|
|
|
65
|
+
builder.use Faraday::HttpCache, store: cache, serializer: Marshal, shared_cache: false
|
|
66
|
+
builder.use Octokit::Response::RaiseError
|
|
67
|
+
builder.adapter Faraday.default_adapter
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
env = EnvironmentManager.new(ENV, cork)
|
|
71
|
+
dm = Dangerfile.new(env, cork)
|
|
72
|
+
dm.init_plugins
|
|
73
|
+
|
|
74
|
+
source = dm.env.ci_source
|
|
75
|
+
if source.nil? or source.repo_slug.empty?
|
|
76
|
+
cork.puts "danger pr failed because it only works with GitHub projects at the moment. Sorry.".red
|
|
77
|
+
exit 0
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
gh = dm.env.request_source
|
|
81
|
+
|
|
82
|
+
cork.puts "Running your Dangerfile against this PR - https://#{gh.host}/#{source.repo_slug}/pull/#{source.pull_request_id}"
|
|
83
|
+
|
|
84
|
+
if verbose != true
|
|
85
|
+
cork.puts "Turning on --verbose"
|
|
86
|
+
dm.verbose = true
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
cork.puts
|
|
90
|
+
|
|
91
|
+
# We can use tokenless here, as it's running on someone's computer
|
|
92
|
+
# and is IP locked, as opposed to on the CI.
|
|
93
|
+
gh.support_tokenless_auth = true
|
|
94
|
+
|
|
95
|
+
begin
|
|
96
|
+
gh.fetch_details
|
|
97
|
+
rescue Octokit::NotFound
|
|
98
|
+
cork.puts "Local repository was not found on GitHub. If you're trying to test a private repository please provide a valid API token through " + "DANGER_GITHUB_API_TOKEN".yellow + " environment variable."
|
|
99
|
+
return
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
dm.env.request_source = gh
|
|
103
|
+
|
|
104
|
+
begin
|
|
105
|
+
dm.env.fill_environment_vars
|
|
106
|
+
dm.env.ensure_danger_branches_are_setup
|
|
107
|
+
dm.env.scm.diff_for_folder(".", from: Danger::EnvironmentManager.danger_base_branch, to: Danger::EnvironmentManager.danger_head_branch)
|
|
108
|
+
|
|
109
|
+
dm.parse(Pathname.new(@dangerfile_path))
|
|
110
|
+
dm.print_results
|
|
111
|
+
ensure
|
|
112
|
+
dm.env.clean_up
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -3,6 +3,7 @@ module Danger
|
|
|
3
3
|
require "danger/commands/init"
|
|
4
4
|
require "danger/commands/local"
|
|
5
5
|
require "danger/commands/systems"
|
|
6
|
+
require "danger/commands/pr"
|
|
6
7
|
|
|
7
8
|
# manually set claide plugins as a subcommand
|
|
8
9
|
require "claide_plugin"
|
|
@@ -19,6 +20,9 @@ module Danger
|
|
|
19
20
|
require "danger/commands/plugins/plugin_json"
|
|
20
21
|
require "danger/commands/plugins/plugin_readme"
|
|
21
22
|
|
|
23
|
+
require "danger/commands/dangerfile/init"
|
|
24
|
+
require "danger/commands/dangerfile/gem"
|
|
25
|
+
|
|
22
26
|
attr_accessor :cork
|
|
23
27
|
|
|
24
28
|
self.summary = "Run the Dangerfile."
|
|
@@ -16,10 +16,12 @@ module Danger
|
|
|
16
16
|
require "yard"
|
|
17
17
|
# Pull out all the Danger::CI subclasses docs
|
|
18
18
|
registry = YARD::Registry.load(ci_source_paths, true)
|
|
19
|
-
ci_sources =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
ci_sources = begin
|
|
20
|
+
registry.all(:class)
|
|
21
|
+
.select { |klass| klass.inheritance_tree.map(&:name).include? :CI }
|
|
22
|
+
.reject { |source| source.name == :CI }
|
|
23
|
+
.reject { |source| source.name == :LocalGitRepo }
|
|
24
|
+
end
|
|
23
25
|
|
|
24
26
|
# Fail if anything is added and not documented
|
|
25
27
|
cis_without_docs = ci_sources.select { |source| source.base_docstring.empty? }
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Danger
|
|
2
|
+
class DangerfileGenerator
|
|
3
|
+
# returns the string for a Dangerfile based on a folder's contents'
|
|
4
|
+
def self.create_dangerfile(_path, _ui)
|
|
5
|
+
# Use this template for now, but this is a really ripe place to
|
|
6
|
+
# improve now!
|
|
7
|
+
dir = Danger.gem_path
|
|
8
|
+
File.read(File.join(dir, "lib", "assets", "DangerfileTemplate"))
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -98,8 +98,10 @@ module Danger
|
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
def issue_comments
|
|
101
|
-
@comments ||=
|
|
102
|
-
|
|
101
|
+
@comments ||= begin
|
|
102
|
+
client.issue_comments(ci_source.repo_slug, ci_source.pull_request_id)
|
|
103
|
+
.map { |comment| Comment.from_github(comment) }
|
|
104
|
+
end
|
|
103
105
|
end
|
|
104
106
|
|
|
105
107
|
# Sending data to GitHub
|
|
@@ -55,13 +55,17 @@ module Danger
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def mr_comments
|
|
58
|
-
@comments ||=
|
|
59
|
-
|
|
58
|
+
@comments ||= begin
|
|
59
|
+
client.merge_request_comments(escaped_ci_slug, ci_source.pull_request_id)
|
|
60
|
+
.map { |comment| Comment.from_gitlab(comment) }
|
|
61
|
+
end
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
def mr_diff
|
|
63
|
-
@mr_diff ||=
|
|
64
|
-
|
|
65
|
+
@mr_diff ||= begin
|
|
66
|
+
client.merge_request_changes(escaped_ci_slug, ci_source.pull_request_id)
|
|
67
|
+
.changes.map { |change| change["diff"] }.join("\n")
|
|
68
|
+
end
|
|
65
69
|
end
|
|
66
70
|
|
|
67
71
|
def escaped_ci_slug
|
data/lib/danger/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: danger
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Orta Therox
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2016-10-
|
|
12
|
+
date: 2016-10-06 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: claide
|
|
@@ -29,16 +29,16 @@ dependencies:
|
|
|
29
29
|
name: claide-plugins
|
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
|
31
31
|
requirements:
|
|
32
|
-
- - "
|
|
32
|
+
- - ">="
|
|
33
33
|
- !ruby/object:Gem::Version
|
|
34
|
-
version: 0.9.
|
|
34
|
+
version: 0.9.2
|
|
35
35
|
type: :runtime
|
|
36
36
|
prerelease: false
|
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
|
38
38
|
requirements:
|
|
39
|
-
- - "
|
|
39
|
+
- - ">="
|
|
40
40
|
- !ruby/object:Gem::Version
|
|
41
|
-
version: 0.9.
|
|
41
|
+
version: 0.9.2
|
|
42
42
|
- !ruby/object:Gem::Dependency
|
|
43
43
|
name: git
|
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -374,7 +374,6 @@ files:
|
|
|
374
374
|
- README.md
|
|
375
375
|
- bin/danger
|
|
376
376
|
- lib/assets/DangerfileTemplate
|
|
377
|
-
- lib/assets/PluginTemplate.rb.template
|
|
378
377
|
- lib/danger.rb
|
|
379
378
|
- lib/danger/ci_source/bitrise.rb
|
|
380
379
|
- lib/danger/ci_source/buildkite.rb
|
|
@@ -386,13 +385,22 @@ files:
|
|
|
386
385
|
- lib/danger/ci_source/jenkins.rb
|
|
387
386
|
- lib/danger/ci_source/local_git_repo.rb
|
|
388
387
|
- lib/danger/ci_source/semaphore.rb
|
|
389
|
-
- lib/danger/ci_source/support/
|
|
390
|
-
- lib/danger/ci_source/support/
|
|
388
|
+
- lib/danger/ci_source/support/commits.rb
|
|
389
|
+
- lib/danger/ci_source/support/find_repo_info_from_logs.rb
|
|
390
|
+
- lib/danger/ci_source/support/find_repo_info_from_url.rb
|
|
391
|
+
- lib/danger/ci_source/support/local_pull_request.rb
|
|
392
|
+
- lib/danger/ci_source/support/no_pull_request.rb
|
|
393
|
+
- lib/danger/ci_source/support/no_repo_info.rb
|
|
394
|
+
- lib/danger/ci_source/support/pull_request_finder.rb
|
|
395
|
+
- lib/danger/ci_source/support/remote_pull_request.rb
|
|
396
|
+
- lib/danger/ci_source/support/repo_info.rb
|
|
391
397
|
- lib/danger/ci_source/surf.rb
|
|
392
398
|
- lib/danger/ci_source/teamcity.rb
|
|
393
399
|
- lib/danger/ci_source/travis.rb
|
|
394
400
|
- lib/danger/ci_source/xcode_server.rb
|
|
395
401
|
- lib/danger/clients/rubygems_client.rb
|
|
402
|
+
- lib/danger/commands/dangerfile/gem.rb
|
|
403
|
+
- lib/danger/commands/dangerfile/init.rb
|
|
396
404
|
- lib/danger/commands/init.rb
|
|
397
405
|
- lib/danger/commands/init_helpers/interviewer.rb
|
|
398
406
|
- lib/danger/commands/local.rb
|
|
@@ -400,6 +408,7 @@ files:
|
|
|
400
408
|
- lib/danger/commands/plugins/plugin_json.rb
|
|
401
409
|
- lib/danger/commands/plugins/plugin_lint.rb
|
|
402
410
|
- lib/danger/commands/plugins/plugin_readme.rb
|
|
411
|
+
- lib/danger/commands/pr.rb
|
|
403
412
|
- lib/danger/commands/runner.rb
|
|
404
413
|
- lib/danger/commands/systems.rb
|
|
405
414
|
- lib/danger/comment_generators/bitbucket_server.md.erb
|
|
@@ -410,6 +419,7 @@ files:
|
|
|
410
419
|
- lib/danger/core_ext/string.rb
|
|
411
420
|
- lib/danger/danger_core/dangerfile.rb
|
|
412
421
|
- lib/danger/danger_core/dangerfile_dsl.rb
|
|
422
|
+
- lib/danger/danger_core/dangerfile_generator.rb
|
|
413
423
|
- lib/danger/danger_core/environment_manager.rb
|
|
414
424
|
- lib/danger/danger_core/executor.rb
|
|
415
425
|
- lib/danger/danger_core/messages/markdown.rb
|
|
@@ -459,7 +469,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
459
469
|
version: '0'
|
|
460
470
|
requirements: []
|
|
461
471
|
rubyforge_project:
|
|
462
|
-
rubygems_version: 2.
|
|
472
|
+
rubygems_version: 2.6.7
|
|
463
473
|
signing_key:
|
|
464
474
|
specification_version: 4
|
|
465
475
|
summary: Like Unit Tests, but for your Team Culture.
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
module Danger
|
|
2
|
-
class Dangerfile
|
|
3
|
-
module DSL
|
|
4
|
-
class [[CLASS_NAME]] < Plugin
|
|
5
|
-
def run(parameter1: nil, parameter2: nil)
|
|
6
|
-
if (pr_body + pr_title).include?("WIP")
|
|
7
|
-
warn "Pull Request is Work in Progress"
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def self.description
|
|
12
|
-
[
|
|
13
|
-
"Describe what this plugin does",
|
|
14
|
-
"and how the user can use it"
|
|
15
|
-
].join(" ")
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
module Danger
|
|
2
|
-
class RemoteFinder
|
|
3
|
-
def initialize(github_host, remote_logs)
|
|
4
|
-
@github_host = github_host
|
|
5
|
-
@remote_logs = remote_logs
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def call
|
|
9
|
-
remote_url_matches && remote_url_matches["repo_slug"]
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
private
|
|
13
|
-
|
|
14
|
-
attr_reader :remote_logs, :github_host
|
|
15
|
-
|
|
16
|
-
# @return [String] The remote URL
|
|
17
|
-
def remote
|
|
18
|
-
@remote ||= remote_logs.lines.grep(/Fetch URL/)[0].split(": ".freeze, 2)[1]
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# @return [nil / MatchData] MatchData object or nil if not matched
|
|
22
|
-
def remote_url_matches
|
|
23
|
-
remote.match(%r{#{Regexp.escape github_host}(:|/)(?<repo_slug>.+/.+?)(?:\.git)?$})
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|