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,54 @@
1
+ require "danger/commands/local_helpers/pry_setup"
2
+ require "fileutils"
3
+
4
+ module Danger
5
+ class DryRun < Runner
6
+ self.summary = "Dry-Run the Dangerfile locally, so you could check some violations before sending real PR/MR."
7
+ self.command = "dry_run"
8
+
9
+ def self.options
10
+ [
11
+ ["--pry", "Drop into a Pry shell after evaluating the Dangerfile."]
12
+ ]
13
+ end
14
+
15
+ def initialize(argv)
16
+ show_help = true if argv.arguments == ["-h"]
17
+
18
+ # Currently CLAide doesn't support short option like -h https://github.com/CocoaPods/CLAide/pull/60
19
+ # when user pass in -h, mimic the behavior of passing in --help.
20
+ argv = CLAide::ARGV.new ["--help"] if show_help
21
+
22
+ super
23
+
24
+ if argv.flag?("pry", false)
25
+ @dangerfile_path = PrySetup.new(cork).setup_pry(@dangerfile_path)
26
+ end
27
+ end
28
+
29
+ def validate!
30
+ super
31
+ unless @dangerfile_path
32
+ help! "Could not find a Dangerfile."
33
+ end
34
+ end
35
+
36
+ def run
37
+ ENV["DANGER_USE_LOCAL_ONLY_GIT"] = "YES"
38
+ ENV["DANGER_LOCAL_HEAD"] = @head if @head
39
+ ENV["DANGER_LOCAL_BASE"] = @base if @base
40
+
41
+ env = EnvironmentManager.new(ENV, cork)
42
+ dm = Dangerfile.new(env, cork)
43
+
44
+ exit 1 if dm.run(
45
+ Danger::EnvironmentManager.danger_base_branch,
46
+ Danger::EnvironmentManager.danger_head_branch,
47
+ @dangerfile_path,
48
+ nil,
49
+ nil,
50
+ nil
51
+ )
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,297 @@
1
+ require "danger/commands/init_helpers/interviewer"
2
+ require "danger/danger_core/dangerfile_generator"
3
+ require "danger/ci_source/local_git_repo"
4
+ require "yaml"
5
+
6
+ module Danger
7
+ class Init < Runner
8
+ self.summary = "Helps you set up Danger."
9
+ self.command = "init"
10
+
11
+ attr_accessor :ui
12
+
13
+ def self.options
14
+ [
15
+ ["--impatient", "'I've not got all day here. Don't add any thematic delays please.'"],
16
+ ["--mousey", "'Don't make me press return to continue the adventure.'"]
17
+ ].concat(super)
18
+ end
19
+
20
+ def initialize(argv)
21
+ @bot_name = File.basename(Dir.getwd).split(".").first.capitalize + "Bot"
22
+ super
23
+ @ui = Interviewer.new(cork)
24
+ ui.no_delay = argv.flag?("impatient", false)
25
+ ui.no_waiting = argv.flag?("mousey", false)
26
+ end
27
+
28
+ def run
29
+ ui.say "\nOK, thanks #{ENV['LOGNAME']}, have a seat and we'll get you started.\n".yellow
30
+ ui.pause 1
31
+
32
+ show_todo_state
33
+ ui.pause 1.4
34
+
35
+ setup_dangerfile
36
+ setup_github_account
37
+ setup_access_token
38
+ setup_danger_ci
39
+
40
+ info
41
+ thanks
42
+ end
43
+
44
+ def show_todo_state
45
+ ui.say "We need to do the following:\n"
46
+ ui.pause 0.6
47
+ ui.say " - [ ] Create a Dangerfile and add a few simple rules."
48
+ ui.pause 0.6
49
+ ui.say " - [#{@account_created ? 'x' : ' '}] Create a GitHub account for Danger to use, for messaging."
50
+ ui.pause 0.6
51
+ ui.say " - [ ] Set up an access token for Danger."
52
+ ui.pause 0.6
53
+ ui.say " - [ ] Set up Danger to run on your CI.\n\n"
54
+ end
55
+
56
+ def setup_dangerfile
57
+ content = DangerfileGenerator.create_dangerfile(".", cork)
58
+ File.write("Dangerfile", content)
59
+
60
+ ui.header "Step 1: Creating a starter Dangerfile"
61
+ ui.say "I've set up an example Dangerfile for you in this folder.\n"
62
+ ui.pause 1
63
+
64
+ ui.say "cat #{Dir.pwd}/Dangerfile\n".blue
65
+ content.lines.each do |l|
66
+ ui.say " " + l.chomp.green
67
+ end
68
+ ui.say ""
69
+ ui.pause 2
70
+
71
+ ui.say "There's a collection of small, simple ideas in here, but Danger is about being able to easily"
72
+ ui.say "iterate. The power comes from you having the ability to codify fixes for some of the problems"
73
+ ui.say "that come up in day to day programming. It can be difficult to try and see those from day 1."
74
+
75
+ ui.say "\nIf you'd like to investigate the file, and make some changes - I'll wait here,"
76
+ ui.say "press return when you're ready to move on..."
77
+ ui.wait_for_return
78
+ end
79
+
80
+ def setup_github_account
81
+ ui.header "Step 2: Creating a GitHub account"
82
+
83
+ ui.say "In order to get the most out of Danger, I'd recommend giving her the ability to post in"
84
+ ui.say "the code-review comment section.\n\n"
85
+ ui.pause 1
86
+
87
+ ui.say "IMO, it's best to do this by using the private mode of your browser. Create an account like"
88
+ ui.say "#{@bot_name}, and don't forget a cool robot avatar.\n\n"
89
+ ui.pause 1
90
+ ui.say "Here are great resources for creative commons images of robots:"
91
+ ui.link "https://www.flickr.com/search/?text=robot&license=2%2C3%2C4%2C5%2C6%2C9"
92
+ ui.link "https://www.google.com/search?q=robot&tbs=sur:fmc&tbm=isch&tbo=u&source=univ&sa=X&ved=0ahUKEwjgy8-f95jLAhWI7hoKHV_UD00QsAQIMQ&biw=1265&bih=1359"
93
+ ui.pause 1
94
+
95
+ if considered_an_oss_repo?
96
+ ui.say "#{@bot_name} does not need privileged access to your repo or org. This is because Danger will only"
97
+ ui.say "be writing comments, and you do not need special access for that."
98
+ else
99
+ ui.say "#{@bot_name} will need access to your repo. Simply because the code is not available for the public"
100
+ ui.say "to read and comment on."
101
+ end
102
+
103
+ ui.say ""
104
+ note_about_clicking_links
105
+ ui.pause 1
106
+ ui.say "\nCool, please press return when you have your account ready (and you've verified the email...)"
107
+ ui.wait_for_return
108
+ end
109
+
110
+ def setup_access_token
111
+ ui.header "Step 3: Configuring a GitHub Personal Access Token"
112
+
113
+ ui.say "Here's the link, you should open this in the private session where you just created the new GitHub account"
114
+ ui.link "https://github.com/settings/tokens/new"
115
+ ui.pause 1
116
+
117
+ @is_open_source = ui.ask_with_answers("For token access rights, I need to know if this is for an Open Source or Closed Source project\n", ["Open", "Closed"])
118
+
119
+ if considered_an_oss_repo?
120
+ ui.say "For Open Source projects, I'd recommend giving the token the smallest scope possible."
121
+ ui.say "This means only providing access to " + "public_repo".yellow + " in the token.\n\n"
122
+ ui.pause 1
123
+ ui.say "This token limits Danger's abilities to just writing comments on OSS projects. I recommend"
124
+ ui.say "this because the token can quite easily be extracted from the environment via pull requests."
125
+
126
+ ui.say "\nIt is important that you do not store this token in your repository, as GitHub will automatically revoke it when pushed.\n"
127
+ elsif @is_open_source == "closed"
128
+ ui.say "For Closed Source projects, I'd recommend giving the token access to the whole repo scope."
129
+ ui.say "This means only providing access to " + "repo".yellow + ", and its children in the token.\n\n"
130
+ ui.pause 1
131
+ ui.say "It's worth noting that you " + "should not".bold.white + " re-use this token for OSS repos."
132
+ ui.say "Make a new one for those repos with just " + "public_repo".yellow + "."
133
+ ui.pause 1
134
+ ui.say "Additionally, don't forget to add your new GitHub account as a collaborator to your Closed Source project."
135
+ end
136
+
137
+ ui.say "\n👍, please press return when you have your token set up..."
138
+ ui.wait_for_return
139
+ end
140
+
141
+ def considered_an_oss_repo?
142
+ @is_open_source == "open"
143
+ end
144
+
145
+ def current_repo_slug
146
+ git = GitRepo.new
147
+
148
+ author_repo_regexp = %r{(?:[\/:])([^\/]+\/[^\/]+)(?:.git)?$}
149
+ last_git_regexp = /.git$/
150
+
151
+ matches = git.origins.match(author_repo_regexp)
152
+
153
+ matches ? matches[1].gsub(last_git_regexp, "").strip : "[Your/Repo]"
154
+ end
155
+
156
+ def setup_danger_ci
157
+ ui.header "Step 4: Add Danger for your CI"
158
+
159
+ uses_travis if File.exist? ".travis.yml"
160
+ uses_circle if File.exist? "circle.yml"
161
+ unsure_ci unless File.exist?(".travis.yml") || File.exist?(".circle.yml")
162
+
163
+ ui.say "\nOK, I'll give you a moment to do this..."
164
+ ui.wait_for_return
165
+
166
+ ui.header "Final step: exposing the GitHub token as an environment build variable."
167
+ ui.pause 0.4
168
+ if considered_an_oss_repo?
169
+ ui.say "As you have an Open Source repo, this token should be considered public, otherwise you cannot"
170
+ ui.say "run Danger on pull requests from forks, limiting its use.\n"
171
+ ui.pause 1
172
+ end
173
+
174
+ travis_token if File.exist? ".travis.yml"
175
+ circle_token if File.exist? "circle.yml"
176
+ unsure_token unless File.exist?(".travis.yml") || File.exist?(".circle.yml")
177
+
178
+ ui.pause 0.6
179
+ ui.say "This is the last step, I can give you a second..."
180
+ ui.wait_for_return
181
+ end
182
+
183
+ def uses_travis
184
+ danger = "bundle exec danger".yellow
185
+ config = YAML.load(File.read(".travis.yml"))
186
+ if config.kind_of?(Hash) && config["script"]
187
+ ui.say "Add " + "- ".yellow + danger + " as a new step in the " + "script".yellow + " section of your .travis.yml file."
188
+ else
189
+ ui.say "I'd recommend adding " + "before_script: ".yellow + danger + " to the script section of your .travis.yml file."
190
+ end
191
+
192
+ ui.pause 1
193
+ ui.say "You shouldn't use " + "after_success, after_failure, after_script".red + " as they cannot fail your builds."
194
+ end
195
+
196
+ def uses_circle
197
+ danger = "- bundle exec danger".yellow
198
+ config = YAML.load(File.read("circle.yml"))
199
+
200
+ if config.kind_of?(Hash) && config["test"]
201
+ if config["test"]["post"]
202
+ ui.say "Add " + danger + " as a new step in the " + "test:post:".yellow + " section of your circle.yml file."
203
+ else
204
+ ui.say "Add " + danger + " as a new step in the " + "test:override:".yellow + " section of your circle.yml file."
205
+ end
206
+ else
207
+ ui.say "Add this to the bottom of your circle.yml file:"
208
+ ui.say "test:".green
209
+ ui.say " post:".green
210
+ ui.say " #{danger}".green
211
+ end
212
+ end
213
+
214
+ def unsure_ci
215
+ danger = "bundle exec danger".yellow
216
+ ui.say "As I'm not sure what CI you want to run Danger on based on the files in your repo, I'll just offer some generic"
217
+ ui.say "advice. You want to run " + danger + " after your tests have finished running, it should still be during the testing"
218
+ ui.say "process so the build can fail."
219
+ end
220
+
221
+ def travis_token
222
+ # https://travis-ci.org/artsy/eigen/settings
223
+ ui.say "In order to add an environment variable, go to:"
224
+ ui.link "https://travis-ci.org/#{current_repo_slug}/settings"
225
+ ui.say "\nThe name is " + "DANGER_GITHUB_API_TOKEN".yellow + " and the value is the GitHub Personal Access Token."
226
+ if @is_open_source
227
+ ui.say 'Make sure to have "Display value in build log" enabled.'
228
+ end
229
+ end
230
+
231
+ def circle_token
232
+ # https://circleci.com/gh/artsy/eigen/edit#env-vars
233
+ if considered_an_oss_repo?
234
+ ui.say "Before we start, it's important to be up-front. CircleCI only really has one option to support running Danger"
235
+ ui.say "for forks on OSS repos. It is quite a drastic option, and I want to let you know the best place to understand"
236
+ ui.say "the ramifications of turning on a setting I'm about to advise.\n"
237
+ ui.link "https://circleci.com/docs/fork-pr-builds"
238
+ ui.say "TLDR: If you have anything other than Danger config settings in CircleCI, then you should not turn on the setting."
239
+ ui.say "I'll give you a minute to read it..."
240
+ ui.wait_for_return
241
+
242
+ ui.say "On danger/danger we turn on " + "Permissive building of fork pull requests".yellow + " this exposes the token to Danger"
243
+ ui.say "You can find this setting at:"
244
+ ui.link "https://circleci.com/gh/#{current_repo_slug}/edit#advanced-settings\n"
245
+ ui.say "I'll hold..."
246
+ ui.wait_for_return
247
+ end
248
+
249
+ ui.say "In order to expose an environment variable, go to:"
250
+ ui.link "https://circleci.com/gh/#{current_repo_slug}/edit#env-vars"
251
+ ui.say "The name is " + "DANGER_GITHUB_API_TOKEN".yellow + " and the value is the GitHub Personal Access Token."
252
+ end
253
+
254
+ def unsure_token
255
+ ui.say "You need to expose a token called " + "DANGER_GITHUB_API_TOKEN".yellow + " and the value is the GitHub Personal Access Token."
256
+ ui.say "Depending on the CI system, this may need to be done on the machine (in the " + "~/.bashprofile".yellow + ") or in a web UI somewhere."
257
+ ui.say "We have a guide for all supported CI systems on danger.systems:"
258
+ ui.link "https://danger.systems/guides/getting_started.html#setting-up-danger-to-run-on-your-ci"
259
+ end
260
+
261
+ def note_about_clicking_links
262
+ modifier_key = "ctrl"
263
+ clicks = "clicking"
264
+
265
+ modifier_key = "cmd ( ⌘ )" if darwin?
266
+ clicks = "double clicking" if darwin? && !ENV["ITERM_SESSION_ID"]
267
+
268
+ ui.say "Note: Holding #{modifier_key} and #{clicks} a link will open it in your browser."
269
+ end
270
+
271
+ def info
272
+ ui.header "Useful info"
273
+ ui.say "- One of the best ways to test out new rules locally is via " + "bundle exec danger pr".yellow + "."
274
+ ui.pause 0.6
275
+ ui.say "- You can have Danger output all of her variables to the console via the " + "--verbose".yellow + " option."
276
+ ui.pause 0.6
277
+ ui.say "- You can look at the following Dangerfiles to get some more ideas:"
278
+ ui.pause 0.6
279
+ ui.link "https://github.com/danger/danger/blob/master/Dangerfile"
280
+ ui.link "https://github.com/artsy/eigen/blob/master/Dangerfile"
281
+ ui.pause 1
282
+ end
283
+
284
+ def thanks
285
+ ui.say "\n\n🎉"
286
+ ui.pause 0.6
287
+
288
+ ui.say "And you're good to go. Danger is a collaboration between Orta Therox, Gem 'Danger' McShane and Felix Krause."
289
+ ui.say "If you like Danger, let others know. If you want to know more, follow " + "@orta".yellow + " and " + "@KrauseFx".yellow + " on Twitter."
290
+ ui.say "If you don't like Danger, help us improve the project! xxx"
291
+ end
292
+
293
+ def darwin?
294
+ Gem::Platform.local.os == "darwin"
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,92 @@
1
+ module Danger
2
+ class Interviewer
3
+ attr_accessor :no_delay, :no_waiting, :ui
4
+
5
+ def initialize(cork_board)
6
+ @ui = cork_board
7
+ end
8
+
9
+ def show_prompt
10
+ ui.print "> ".bold.green
11
+ end
12
+
13
+ def yellow_bang
14
+ "! ".yellow
15
+ end
16
+
17
+ def green_bang
18
+ "! ".green
19
+ end
20
+
21
+ def red_bang
22
+ "! ".red
23
+ end
24
+
25
+ def say(output)
26
+ ui.puts output
27
+ end
28
+
29
+ def header(title)
30
+ say title.yellow
31
+ say ""
32
+ pause 0.6
33
+ end
34
+
35
+ def link(url)
36
+ say " -> " + url.underlined + "\n"
37
+ end
38
+
39
+ def pause(time)
40
+ sleep(time) unless @no_waiting
41
+ end
42
+
43
+ def wait_for_return
44
+ STDOUT.flush
45
+ STDIN.gets unless @no_delay
46
+ ui.puts
47
+ end
48
+
49
+ def run_command(command, output_command = nil)
50
+ output_command ||= command
51
+ ui.puts " " + output_command.magenta
52
+ system command
53
+ end
54
+
55
+ def ask_with_answers(question, possible_answers)
56
+ ui.print "\n#{question}? ["
57
+
58
+ print_info = proc do
59
+ possible_answers.each_with_index do |answer, i|
60
+ the_answer = i.zero? ? answer.underlined : answer
61
+ ui.print " " + the_answer
62
+ ui.print(" /") if i != possible_answers.length - 1
63
+ end
64
+ ui.print " ]\n"
65
+ end
66
+ print_info.call
67
+
68
+ answer = ""
69
+
70
+ loop do
71
+ show_prompt
72
+ answer = @no_waiting ? possible_answers[0].downcase : STDIN.gets.downcase.chomp
73
+
74
+ answer = "yes" if answer == "y"
75
+ answer = "no" if answer == "n"
76
+
77
+ # default to first answer
78
+ if answer == ""
79
+ answer = possible_answers[0].downcase
80
+ ui.puts "Using: " + answer.yellow
81
+ end
82
+
83
+ break if possible_answers.map(&:downcase).include? answer
84
+
85
+ ui.print "\nPossible answers are ["
86
+ print_info.call
87
+ end
88
+
89
+ answer
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,83 @@
1
+ require "danger/commands/local_helpers/http_cache"
2
+ require "danger/commands/local_helpers/local_setup"
3
+ require "danger/commands/local_helpers/pry_setup"
4
+ require "faraday/http_cache"
5
+ require "fileutils"
6
+ require "octokit"
7
+ require "tmpdir"
8
+
9
+ module Danger
10
+ class Local < Runner
11
+ self.summary = "Run the Dangerfile locally. This command is generally deprecated in favor of `danger pr`."
12
+ self.command = "local"
13
+
14
+ def self.options
15
+ [
16
+ ["--use-merged-pr=[#id]", "The ID of an already merged PR inside your history to use as a reference for the local run."],
17
+ ["--clear-http-cache", "Clear the local http cache before running Danger locally."],
18
+ ["--pry", "Drop into a Pry shell after evaluating the Dangerfile."]
19
+ ]
20
+ end
21
+
22
+ def initialize(argv)
23
+ show_help = true if argv.arguments == ["-h"]
24
+
25
+ @pr_num = argv.option("use-merged-pr")
26
+ @clear_http_cache = argv.flag?("clear-http-cache", false)
27
+
28
+ # Currently CLAide doesn't support short option like -h https://github.com/CocoaPods/CLAide/pull/60
29
+ # when user pass in -h, mimic the behavior of passing in --help.
30
+ argv = CLAide::ARGV.new ["--help"] if show_help
31
+
32
+ super
33
+
34
+ if argv.flag?("pry", false)
35
+ @dangerfile_path = PrySetup.new(cork).setup_pry(@dangerfile_path)
36
+ end
37
+ end
38
+
39
+ def validate!
40
+ super
41
+ unless @dangerfile_path
42
+ help! "Could not find a Dangerfile."
43
+ end
44
+ end
45
+
46
+ def run
47
+ ENV["DANGER_USE_LOCAL_GIT"] = "YES"
48
+ ENV["LOCAL_GIT_PR_ID"] = @pr_num if @pr_num
49
+
50
+ configure_octokit(ENV["DANGER_TMPDIR"] || Dir.tmpdir)
51
+
52
+ env = EnvironmentManager.new(ENV, cork)
53
+ dm = Dangerfile.new(env, cork)
54
+
55
+ LocalSetup.new(dm, cork).setup(verbose: verbose) do
56
+ dm.run(
57
+ Danger::EnvironmentManager.danger_base_branch,
58
+ Danger::EnvironmentManager.danger_head_branch,
59
+ @dangerfile_path,
60
+ nil,
61
+ nil,
62
+ nil
63
+ )
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ # this method is a duplicate of Commands::PR#configure_octokit
70
+ # - worth a refactor sometime?
71
+ def configure_octokit(cache_dir)
72
+ # setup caching for Github calls to hitting the API rate limit too quickly
73
+ cache_file = File.join(cache_dir, "danger_local_cache")
74
+ cache = HTTPCache.new(cache_file, clear_cache: @clear_http_cache)
75
+ Octokit.middleware = Faraday::RackBuilder.new do |builder|
76
+ builder.use Faraday::HttpCache, store: cache, serializer: Marshal, shared_cache: false
77
+ builder.use Octokit::Middleware::FollowRedirects
78
+ builder.use Octokit::Response::RaiseError
79
+ builder.adapter Faraday.default_adapter
80
+ end
81
+ end
82
+ end
83
+ end