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.
Files changed (121) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +94 -0
  4. data/bin/danger +5 -0
  5. data/lib/assets/DangerfileTemplate +13 -0
  6. data/lib/danger.rb +44 -0
  7. data/lib/danger/ci_source/appcenter.rb +55 -0
  8. data/lib/danger/ci_source/appveyor.rb +60 -0
  9. data/lib/danger/ci_source/azure_pipelines.rb +44 -0
  10. data/lib/danger/ci_source/bamboo.rb +41 -0
  11. data/lib/danger/ci_source/bitbucket_pipelines.rb +37 -0
  12. data/lib/danger/ci_source/bitrise.rb +65 -0
  13. data/lib/danger/ci_source/buddybuild.rb +62 -0
  14. data/lib/danger/ci_source/buildkite.rb +51 -0
  15. data/lib/danger/ci_source/ci_source.rb +37 -0
  16. data/lib/danger/ci_source/circle.rb +94 -0
  17. data/lib/danger/ci_source/circle_api.rb +51 -0
  18. data/lib/danger/ci_source/cirrus.rb +31 -0
  19. data/lib/danger/ci_source/code_build.rb +57 -0
  20. data/lib/danger/ci_source/codefresh.rb +53 -0
  21. data/lib/danger/ci_source/codeship.rb +44 -0
  22. data/lib/danger/ci_source/dotci.rb +52 -0
  23. data/lib/danger/ci_source/drone.rb +71 -0
  24. data/lib/danger/ci_source/github_actions.rb +43 -0
  25. data/lib/danger/ci_source/gitlab_ci.rb +86 -0
  26. data/lib/danger/ci_source/jenkins.rb +149 -0
  27. data/lib/danger/ci_source/local_git_repo.rb +119 -0
  28. data/lib/danger/ci_source/local_only_git_repo.rb +47 -0
  29. data/lib/danger/ci_source/screwdriver.rb +47 -0
  30. data/lib/danger/ci_source/semaphore.rb +37 -0
  31. data/lib/danger/ci_source/support/commits.rb +17 -0
  32. data/lib/danger/ci_source/support/find_repo_info_from_logs.rb +35 -0
  33. data/lib/danger/ci_source/support/find_repo_info_from_url.rb +42 -0
  34. data/lib/danger/ci_source/support/local_pull_request.rb +14 -0
  35. data/lib/danger/ci_source/support/no_pull_request.rb +7 -0
  36. data/lib/danger/ci_source/support/no_repo_info.rb +5 -0
  37. data/lib/danger/ci_source/support/pull_request_finder.rb +179 -0
  38. data/lib/danger/ci_source/support/remote_pull_request.rb +15 -0
  39. data/lib/danger/ci_source/support/repo_info.rb +10 -0
  40. data/lib/danger/ci_source/surf.rb +37 -0
  41. data/lib/danger/ci_source/teamcity.rb +161 -0
  42. data/lib/danger/ci_source/travis.rb +51 -0
  43. data/lib/danger/ci_source/vsts.rb +73 -0
  44. data/lib/danger/ci_source/xcode_server.rb +48 -0
  45. data/lib/danger/clients/rubygems_client.rb +14 -0
  46. data/lib/danger/commands/dangerfile/gem.rb +43 -0
  47. data/lib/danger/commands/dangerfile/init.rb +30 -0
  48. data/lib/danger/commands/dry_run.rb +54 -0
  49. data/lib/danger/commands/init.rb +297 -0
  50. data/lib/danger/commands/init_helpers/interviewer.rb +92 -0
  51. data/lib/danger/commands/local.rb +83 -0
  52. data/lib/danger/commands/local_helpers/http_cache.rb +36 -0
  53. data/lib/danger/commands/local_helpers/local_setup.rb +46 -0
  54. data/lib/danger/commands/local_helpers/pry_setup.rb +31 -0
  55. data/lib/danger/commands/plugins/plugin_json.rb +46 -0
  56. data/lib/danger/commands/plugins/plugin_lint.rb +54 -0
  57. data/lib/danger/commands/plugins/plugin_readme.rb +45 -0
  58. data/lib/danger/commands/pr.rb +92 -0
  59. data/lib/danger/commands/runner.rb +94 -0
  60. data/lib/danger/commands/staging.rb +53 -0
  61. data/lib/danger/commands/systems.rb +43 -0
  62. data/lib/danger/comment_generators/bitbucket_server.md.erb +20 -0
  63. data/lib/danger/comment_generators/bitbucket_server_inline.md.erb +15 -0
  64. data/lib/danger/comment_generators/bitbucket_server_message_group.md.erb +12 -0
  65. data/lib/danger/comment_generators/github.md.erb +55 -0
  66. data/lib/danger/comment_generators/github_inline.md.erb +26 -0
  67. data/lib/danger/comment_generators/gitlab.md.erb +40 -0
  68. data/lib/danger/comment_generators/gitlab_inline.md.erb +26 -0
  69. data/lib/danger/comment_generators/vsts.md.erb +20 -0
  70. data/lib/danger/core_ext/file_list.rb +18 -0
  71. data/lib/danger/core_ext/string.rb +20 -0
  72. data/lib/danger/danger_core/dangerfile.rb +341 -0
  73. data/lib/danger/danger_core/dangerfile_dsl.rb +29 -0
  74. data/lib/danger/danger_core/dangerfile_generator.rb +11 -0
  75. data/lib/danger/danger_core/environment_manager.rb +123 -0
  76. data/lib/danger/danger_core/executor.rb +92 -0
  77. data/lib/danger/danger_core/message_aggregator.rb +49 -0
  78. data/lib/danger/danger_core/message_group.rb +68 -0
  79. data/lib/danger/danger_core/messages/base.rb +56 -0
  80. data/lib/danger/danger_core/messages/markdown.rb +42 -0
  81. data/lib/danger/danger_core/messages/violation.rb +54 -0
  82. data/lib/danger/danger_core/plugins/dangerfile_bitbucket_cloud_plugin.rb +144 -0
  83. data/lib/danger/danger_core/plugins/dangerfile_bitbucket_server_plugin.rb +211 -0
  84. data/lib/danger/danger_core/plugins/dangerfile_danger_plugin.rb +248 -0
  85. data/lib/danger/danger_core/plugins/dangerfile_git_plugin.rb +158 -0
  86. data/lib/danger/danger_core/plugins/dangerfile_github_plugin.rb +254 -0
  87. data/lib/danger/danger_core/plugins/dangerfile_gitlab_plugin.rb +240 -0
  88. data/lib/danger/danger_core/plugins/dangerfile_local_only_plugin.rb +42 -0
  89. data/lib/danger/danger_core/plugins/dangerfile_messaging_plugin.rb +218 -0
  90. data/lib/danger/danger_core/plugins/dangerfile_vsts_plugin.rb +191 -0
  91. data/lib/danger/danger_core/standard_error.rb +143 -0
  92. data/lib/danger/helpers/array_subclass.rb +61 -0
  93. data/lib/danger/helpers/comment.rb +32 -0
  94. data/lib/danger/helpers/comments_helper.rb +178 -0
  95. data/lib/danger/helpers/comments_parsing_helper.rb +70 -0
  96. data/lib/danger/helpers/emoji_mapper.rb +41 -0
  97. data/lib/danger/helpers/find_max_num_violations.rb +31 -0
  98. data/lib/danger/helpers/message_groups_array_helper.rb +31 -0
  99. data/lib/danger/plugin_support/gems_resolver.rb +77 -0
  100. data/lib/danger/plugin_support/plugin.rb +49 -0
  101. data/lib/danger/plugin_support/plugin_file_resolver.rb +30 -0
  102. data/lib/danger/plugin_support/plugin_linter.rb +161 -0
  103. data/lib/danger/plugin_support/plugin_parser.rb +199 -0
  104. data/lib/danger/plugin_support/templates/readme_table.html.erb +26 -0
  105. data/lib/danger/request_sources/bitbucket_cloud.rb +171 -0
  106. data/lib/danger/request_sources/bitbucket_cloud_api.rb +181 -0
  107. data/lib/danger/request_sources/bitbucket_server.rb +105 -0
  108. data/lib/danger/request_sources/bitbucket_server_api.rb +117 -0
  109. data/lib/danger/request_sources/github/github.rb +530 -0
  110. data/lib/danger/request_sources/github/github_review.rb +126 -0
  111. data/lib/danger/request_sources/github/github_review_resolver.rb +19 -0
  112. data/lib/danger/request_sources/github/github_review_unsupported.rb +25 -0
  113. data/lib/danger/request_sources/gitlab.rb +525 -0
  114. data/lib/danger/request_sources/local_only.rb +53 -0
  115. data/lib/danger/request_sources/request_source.rb +85 -0
  116. data/lib/danger/request_sources/support/get_ignored_violation.rb +17 -0
  117. data/lib/danger/request_sources/vsts.rb +118 -0
  118. data/lib/danger/request_sources/vsts_api.rb +138 -0
  119. data/lib/danger/scm_source/git_repo.rb +181 -0
  120. data/lib/danger/version.rb +4 -0
  121. metadata +339 -0
@@ -0,0 +1,52 @@
1
+ require "danger/request_sources/github/github"
2
+
3
+ module Danger
4
+ # https://groupon.github.io/DotCi
5
+
6
+ # ### CI Setup
7
+ # DotCi is a layer on top of jenkins. So, if you're using DotCi, you're hosting your own environment.
8
+ #
9
+ # ### Token Setup
10
+ #
11
+ # #### GitHub
12
+ # As you own the machine, it's up to you to add the environment variable for the `DANGER_GITHUB_API_TOKEN`.
13
+ #
14
+ class DotCi < CI
15
+ def self.validates_as_ci?(env)
16
+ env.key? "DOTCI"
17
+ end
18
+
19
+ def self.validates_as_pr?(env)
20
+ !env["DOTCI_PULL_REQUEST"].nil? && !env["DOTCI_PULL_REQUEST"].match(/^[0-9]+$/).nil?
21
+ end
22
+
23
+ def supported_request_sources
24
+ @supported_request_sources ||= begin
25
+ [
26
+ Danger::RequestSources::GitHub
27
+ ]
28
+ end
29
+ end
30
+
31
+ def initialize(env)
32
+ self.repo_url = self.class.repo_url(env)
33
+ self.pull_request_id = self.class.pull_request_id(env)
34
+ repo_matches = self.repo_url.match(%r{([\/:])([^\/]+\/[^\/]+)$})
35
+ self.repo_slug = repo_matches[2].gsub(/\.git$/, "") unless repo_matches.nil?
36
+ end
37
+
38
+ def self.pull_request_id(env)
39
+ env["DOTCI_PULL_REQUEST"]
40
+ end
41
+
42
+ def self.repo_url(env)
43
+ if env["DOTCI_INSTALL_PACKAGES_GIT_CLONE_URL"]
44
+ env["DOTCI_INSTALL_PACKAGES_GIT_CLONE_URL"]
45
+ elsif env["DOTCI_DOCKER_COMPOSE_GIT_CLONE_URL"]
46
+ env["DOTCI_DOCKER_COMPOSE_GIT_CLONE_URL"]
47
+ else
48
+ env["GIT_URL"]
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,71 @@
1
+ # http://readme.drone.io/usage/variables/
2
+ require "danger/request_sources/github/github"
3
+ require "danger/request_sources/gitlab"
4
+
5
+ module Danger
6
+ # ### CI Setup
7
+ #
8
+ # With Drone you run the docker images yourself, so you will want to add `bundle exec danger` at the end of
9
+ # your `.drone.yml`.
10
+ #
11
+ # ``` shell
12
+ # build:
13
+ # image: golang
14
+ # commands:
15
+ # - ...
16
+ # - bundle exec danger
17
+ # ```
18
+ #
19
+ # ### Token Setup
20
+ #
21
+ # As this is self-hosted, you will need to expose the `DANGER_GITHUB_API_TOKEN` as a secret to your
22
+ # builds:
23
+ #
24
+ # Drone secrets: http://readme.drone.io/usage/secret-guide/
25
+ # NOTE: This is a new syntax in DroneCI 0.6+
26
+ #
27
+ # ```
28
+ # build:
29
+ # image: golang
30
+ # secrets:
31
+ # - DANGER_GITHUB_API_TOKEN
32
+ # commands:
33
+ # - ...
34
+ # - bundle exec danger
35
+ # ```
36
+ class Drone < CI
37
+ def self.validates_as_ci?(env)
38
+ validates_as_ci_post_06?(env) or validates_as_ci_pre_06?(env)
39
+ end
40
+
41
+ def self.validates_as_pr?(env)
42
+ env["DRONE_PULL_REQUEST"].to_i > 0
43
+ end
44
+
45
+ def supported_request_sources
46
+ @supported_request_sources ||= [Danger::RequestSources::GitHub, Danger::RequestSources::GitLab]
47
+ end
48
+
49
+ def initialize(env)
50
+ if self.class.validates_as_ci_post_06?(env)
51
+ self.repo_slug = "#{env['DRONE_REPO_OWNER']}/#{env['DRONE_REPO_NAME']}"
52
+ self.repo_url = env["DRONE_REPO_LINK"] if self.class.validates_as_ci_post_06?(env)
53
+ elsif self.class.validates_as_ci_pre_06?(env)
54
+ self.repo_slug = env["DRONE_REPO"]
55
+ self.repo_url = GitRepo.new.origins
56
+ end
57
+
58
+ self.pull_request_id = env["DRONE_PULL_REQUEST"]
59
+ end
60
+
61
+ # Check if this build is valid for CI with drone 0.6 or later
62
+ def self.validates_as_ci_post_06?(env)
63
+ env.key? "DRONE_REPO_OWNER" and env.key? "DRONE_REPO_NAME"
64
+ end
65
+
66
+ # Checks if this build is valid for CI with drone 0.5 or earlier
67
+ def self.validates_as_ci_pre_06?(env)
68
+ env.key? "DRONE_REPO"
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,43 @@
1
+ require "danger/request_sources/github/github"
2
+
3
+ module Danger
4
+ # ### CI Setup
5
+ #
6
+ # You can use `danger/danger` Action in your `.github/workflows/xxx.yml`.
7
+ # And so, you can use GITHUB_TOKEN secret as `DANGER_GITHUB_API_TOKEN` environment variable.
8
+ #
9
+ # ```
10
+ # ...
11
+ # steps:
12
+ # - uses: actions/checkout@v1
13
+ # - uses: danger/danger@master
14
+ # env:
15
+ # DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16
+ # ```
17
+ #
18
+ class GitHubActions < CI
19
+ def self.validates_as_ci?(env)
20
+ env.key? "GITHUB_ACTION"
21
+ end
22
+
23
+ def self.validates_as_pr?(env)
24
+ env["GITHUB_EVENT_NAME"] == "pull_request"
25
+ end
26
+
27
+ def supported_request_sources
28
+ @supported_request_sources ||= [Danger::RequestSources::GitHub]
29
+ end
30
+
31
+ def initialize(env)
32
+ self.repo_slug = env["GITHUB_REPOSITORY"]
33
+ pull_request_event = JSON.parse(File.read(env["GITHUB_EVENT_PATH"]))
34
+ self.pull_request_id = pull_request_event['number']
35
+ self.repo_url = pull_request_event['repository']['clone_url']
36
+
37
+ # if environment variable DANGER_GITHUB_API_TOKEN is not set, use env GITHUB_TOKEN
38
+ if (env.key? "GITHUB_ACTION") && (!env.key? 'DANGER_GITHUB_API_TOKEN')
39
+ env['DANGER_GITHUB_API_TOKEN'] = env['GITHUB_TOKEN']
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,86 @@
1
+ # http://docs.gitlab.com/ce/ci/variables/README.html
2
+ require "uri"
3
+ require "danger/request_sources/github/github"
4
+ require "danger/request_sources/gitlab"
5
+
6
+ module Danger
7
+ # ### CI Setup
8
+ #
9
+ # Install dependencies and add a danger step to your .gitlab-ci.yml:
10
+ # ```yml
11
+ # before_script:
12
+ # - bundle install
13
+ # danger:
14
+ # script:
15
+ # - bundle exec danger
16
+ # ```
17
+ # ### Token Setup
18
+ #
19
+ # Add the `DANGER_GITLAB_API_TOKEN` to your pipeline env variables if you
20
+ # are hosting your code on GitLab. If you are using GitLab as a mirror
21
+ # for the purpose of CI/CD, while hosting your repo on GitHub, set the
22
+ # `DANGER_GITHUB_API_TOKEN` as well as the project repo URL to
23
+ # `DANGER_PROJECT_REPO_URL`.
24
+
25
+ class GitLabCI < CI
26
+ def self.validates_as_ci?(env)
27
+ env.key? "GITLAB_CI"
28
+ end
29
+
30
+ def self.validates_as_pr?(env)
31
+ exists = [
32
+ "GITLAB_CI", "CI_PROJECT_PATH"
33
+ ].all? { |x| env[x] }
34
+
35
+ exists && determine_pull_or_merge_request_id(env).to_i > 0
36
+ end
37
+
38
+ def self.determine_pull_or_merge_request_id(env)
39
+ return env["CI_MERGE_REQUEST_IID"] if env["CI_MERGE_REQUEST_IID"]
40
+ return env["CI_EXTERNAL_PULL_REQUEST_IID"] if env["CI_EXTERNAL_PULL_REQUEST_IID"]
41
+ return 0 unless env["CI_COMMIT_SHA"]
42
+
43
+ project_path = env["CI_MERGE_REQUEST_PROJECT_PATH"] || env["CI_PROJECT_PATH"]
44
+ base_commit = env["CI_COMMIT_SHA"]
45
+ client = RequestSources::GitLab.new(nil, env).client
46
+
47
+ if (Gem::Version.new(client.version.version) >= Gem::Version.new("10.7"))
48
+ #Use the 'list merge requests associated with a commit' API, for speeed
49
+ # (GET /projects/:id/repository/commits/:sha/merge_requests) available for GitLab >= 10.7
50
+ merge_request = client.commit_merge_requests(project_path, base_commit, state: :opened).first
51
+ else
52
+ merge_requests = client.merge_requests(project_path, state: :opened)
53
+ merge_request = merge_requests.auto_paginate.find do |mr|
54
+ mr.sha == base_commit
55
+ end
56
+ end
57
+ merge_request.nil? ? 0 : merge_request.iid
58
+ end
59
+
60
+ def initialize(env)
61
+ @env = env
62
+ @repo_slug = slug_from(env)
63
+ end
64
+
65
+ def supported_request_sources
66
+ @supported_request_sources ||= [
67
+ Danger::RequestSources::GitHub,
68
+ Danger::RequestSources::GitLab
69
+ ]
70
+ end
71
+
72
+ def pull_request_id
73
+ @pull_request_id ||= self.class.determine_pull_or_merge_request_id(@env)
74
+ end
75
+
76
+ private
77
+
78
+ def slug_from(env)
79
+ if env["DANGER_PROJECT_REPO_URL"]
80
+ env["DANGER_PROJECT_REPO_URL"].split('/').last(2).join('/')
81
+ else
82
+ env["CI_MERGE_REQUEST_PROJECT_PATH"] || env["CI_PROJECT_PATH"]
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,149 @@
1
+ # https://wiki.jenkins-ci.org/display/JENKINS/Building+a+software+project#Buildingasoftwareproject-JenkinsSetEnvironmentVariables
2
+ # https://wiki.jenkins-ci.org/display/JENKINS/GitHub+pull+request+builder+plugin
3
+ require "danger/request_sources/github/github"
4
+ require "danger/request_sources/gitlab"
5
+ require "danger/request_sources/bitbucket_server"
6
+ require "danger/request_sources/bitbucket_cloud"
7
+
8
+ module Danger
9
+ # https://jenkins-ci.org
10
+
11
+ # ### CI Setup
12
+ # Ah Jenkins, so many memories. So, if you're using Jenkins, you're hosting your own environment.
13
+ #
14
+ # #### GitHub
15
+ # You will want to be using the [GitHub pull request builder plugin](https://wiki.jenkins-ci.org/display/JENKINS/GitHub+pull+request+builder+plugin)
16
+ # in order to ensure that you have the build environment set up for PR integration.
17
+ #
18
+ # With that set up, you can edit your job to add `bundle exec danger` at the build action.
19
+ #
20
+ # ##### Pipeline
21
+ # If your're using [pipelines](https://jenkins.io/solutions/pipeline/) you should be using the [GitHub branch source plugin](https://wiki.jenkins-ci.org/display/JENKINS/GitHub+Branch+Source+Plugin)
22
+ # for easy setup and handling of PRs.
23
+ #
24
+ # After you've set up the plugin, add a `sh 'bundle exec danger'` line in your pipeline script and make sure that build PRs is enabled.
25
+ #
26
+ # #### GitLab
27
+ # You will want to be using the [GitLab Plugin](https://github.com/jenkinsci/gitlab-plugin)
28
+ # in order to ensure that you have the build environment set up for MR integration.
29
+ #
30
+ # With that set up, you can edit your job to add `bundle exec danger` at the build action.
31
+ #
32
+ # #### General
33
+ #
34
+ # People occasionally see issues with Danger not classing your CI runs as a PR, to give you visibilty
35
+ # the Jenkins side of Danger expects to see one of these env vars:
36
+ # - ghprbPullId
37
+ # - CHANGE_ID
38
+ # - gitlabMergeRequestIid
39
+ # - gitlabMergeRequestId
40
+ #
41
+ # ### Token Setup
42
+ #
43
+ # #### GitHub
44
+ # As you own the machine, it's up to you to add the environment variable for the `DANGER_GITHUB_API_TOKEN`.
45
+ #
46
+ # #### GitLab
47
+ # As you own the machine, it's up to you to add the environment variable for the `DANGER_GITLAB_API_TOKEN`.
48
+ #
49
+ class Jenkins < CI
50
+ attr_accessor :project_url
51
+ class EnvNotFound < StandardError
52
+ def initialize
53
+ super("ENV not found, please check your Jenkins. Related: https://stackoverflow.com/search?q=jenkins+env+null")
54
+ end
55
+ end
56
+
57
+ def self.validates_as_ci?(env)
58
+ env.key? "JENKINS_URL"
59
+ end
60
+
61
+ def self.validates_as_pr?(env)
62
+ id = pull_request_id(env)
63
+ !id.nil? && !id.empty? && !!id.match(%r{^\d+$})
64
+ end
65
+
66
+ def supported_request_sources
67
+ @supported_request_sources ||= begin
68
+ [
69
+ Danger::RequestSources::GitHub,
70
+ Danger::RequestSources::GitLab,
71
+ Danger::RequestSources::BitbucketServer,
72
+ Danger::RequestSources::BitbucketCloud
73
+ ]
74
+ end
75
+ end
76
+
77
+ def initialize(env)
78
+ raise EnvNotFound.new if env.nil? || env.empty?
79
+
80
+ self.repo_url = self.class.repo_url(env)
81
+ self.pull_request_id = self.class.pull_request_id(env)
82
+ self.repo_slug = self.class.repo_slug(self.repo_url)
83
+ self.project_url = env["CI_MERGE_REQUEST_PROJECT_URL"] || env["CI_PROJECT_URL"]
84
+ end
85
+
86
+ def self.repo_slug(repo_url)
87
+ slug = self.slug_ssh(repo_url)
88
+ slug = self.slug_http(repo_url) unless slug
89
+ slug = self.slug_bitbucket(repo_url) unless slug
90
+ slug = self.slug_fallback(repo_url) unless slug
91
+ return slug.gsub(/\.git$/, "") unless slug.nil?
92
+ end
93
+
94
+ def self.slug_bitbucket(repo_url)
95
+ repo_matches = repo_url.match(%r{(?:[\/:])projects\/([^\/.]+)\/repos\/([^\/.]+)})
96
+ return "#{repo_matches[1]}/#{repo_matches[2]}" if repo_matches
97
+ end
98
+
99
+ def self.slug_ssh(repo_url)
100
+ repo_matches = repo_url.match(%r{^git@.+:(.+)})
101
+ return repo_matches[1] if repo_matches
102
+ end
103
+
104
+ def self.slug_http(repo_url)
105
+ repo_matches = repo_url.match(%r{^https?.+(?>\.\w*\d*\/)(.+.git$)})
106
+ return repo_matches[1] if repo_matches
107
+ end
108
+
109
+ def self.slug_fallback(repo_url)
110
+ repo_matches = repo_url.match(%r{([\/:])([^\/]+\/[^\/]+)$})
111
+ return repo_matches[2]
112
+ end
113
+
114
+ def self.pull_request_id(env)
115
+ if env["ghprbPullId"]
116
+ env["ghprbPullId"]
117
+ elsif env["CHANGE_ID"]
118
+ env["CHANGE_ID"]
119
+ elsif env["gitlabMergeRequestIid"]
120
+ env["gitlabMergeRequestIid"]
121
+ else
122
+ env["gitlabMergeRequestId"]
123
+ end
124
+ end
125
+
126
+ def self.repo_url(env)
127
+ if env["GIT_URL_1"]
128
+ env["GIT_URL_1"]
129
+ elsif env["CHANGE_URL"]
130
+ change_url = env["CHANGE_URL"]
131
+ case change_url
132
+ when %r{\/pull\/} # GitHub
133
+ matches = change_url.match(%r{(.+)\/pull\/[0-9]+})
134
+ matches[1] unless matches.nil?
135
+ when %r{\/merge_requests\/} # GitLab
136
+ matches = change_url.match(%r{(.+)\/merge_requests\/[0-9]+})
137
+ matches[1] unless matches.nil?
138
+ when %r{\/pull-requests\/} # Bitbucket
139
+ matches = change_url.match(%r{(.+)\/pull-requests\/[0-9]+})
140
+ matches[1] unless matches.nil?
141
+ else
142
+ change_url
143
+ end
144
+ else
145
+ env["GIT_URL"]
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,119 @@
1
+ # For more info see: https://github.com/schacon/ruby-git
2
+
3
+ require "git"
4
+ require "uri"
5
+
6
+ require "danger/request_sources/github/github"
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
+
14
+ module Danger
15
+ # ignore
16
+ class LocalGitRepo < CI
17
+ attr_accessor :base_commit, :head_commit
18
+
19
+ def self.validates_as_ci?(env)
20
+ env.key? "DANGER_USE_LOCAL_GIT"
21
+ end
22
+
23
+ def self.validates_as_pr?(_env)
24
+ false
25
+ end
26
+
27
+ def git
28
+ @git ||= GitRepo.new
29
+ end
30
+
31
+ def run_git(command)
32
+ git.exec(command).encode("UTF-8", "binary", invalid: :replace, undef: :replace, replace: "")
33
+ end
34
+
35
+ def supported_request_sources
36
+ @supported_request_sources ||= [Danger::RequestSources::GitHub, Danger::RequestSources::BitbucketServer, Danger::RequestSources::BitbucketCloud]
37
+ end
38
+
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
54
+ end
55
+
56
+ private
57
+
58
+ attr_reader :env
59
+
60
+ def raise_error_for_missing_remote
61
+ raise missing_remote_error_message
62
+ end
63
+
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
+ remote_url: env["LOCAL_GIT_PR_URL"],
94
+ env: env
95
+ ).call
96
+ else
97
+ PullRequestFinder.new(
98
+ env.fetch("LOCAL_GIT_PR_ID") { "".freeze },
99
+ remote_info.slug,
100
+ remote: false,
101
+ git_logs: run_git("log --oneline -1000000".freeze)
102
+ ).call
103
+ end
104
+ end
105
+ end
106
+
107
+ def given_pull_request_url?
108
+ env["LOCAL_GIT_PR_URL"] && !env["LOCAL_GIT_PR_URL"].empty?
109
+ end
110
+
111
+ def sha
112
+ @_sha ||= found_pull_request.sha
113
+ end
114
+
115
+ def commits
116
+ @_commits ||= Commits.new(run_git("rev-list --parents -n 1 #{sha}"))
117
+ end
118
+ end
119
+ end