danger 0.5.1 → 0.7.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 25ffbe9e81d58bb03a50c0813b2340802520b827
4
- data.tar.gz: 11b7151376d9c471c80d522a81eb17a88c487e1c
3
+ metadata.gz: f405c58b164cfb051f33ce62eff96d6954ccedf8
4
+ data.tar.gz: e487a8349af60005ce0f63ec429cd8e73a561055
5
5
  SHA512:
6
- metadata.gz: 744f9c2444f90270cb142684ba457a31f889d49031cb582526c6a3ad13b5b8e05a3c0320e79bff2d31a6b24767baa53c7aea45c3f33d95094944781189b9397e
7
- data.tar.gz: b94a33faeb13e99218c602e18dca552eada52d22836cab057417d2e15e203254a634b8c2fc3a01822a3641d070d5d16e8d6743822d0f9b87166817263d5d8035
6
+ metadata.gz: 3ce00623811798d3bf0cb0e77bc788bc0c99fac1045d00a33cf3c68b297983e669de41544bae3f8310257e3a34a3e8704aedb2d9f9fc2064e4f0a3e443cdcbc5
7
+ data.tar.gz: e0cdd1d536430c45226a3638ff0a2cd659db62a19e643c931230961e00967e7705321ec561c2afd276c0e73f6570d2335f7126b82017be95f5dcd0de18d9c906
data/README.md CHANGED
@@ -38,7 +38,7 @@ bundle exec danger init
38
38
  bundle exec danger
39
39
  ```
40
40
 
41
- This will look at your `Dangerfile` and update the pull request accordingly. While you are setting up Danger, you may want to use: `--verbose` for more debug information.
41
+ This will look at your `Dangerfile` and update the pull request accordingly. While you are setting up Danger, you may want to use: `--verbose` for more debug information.
42
42
 
43
43
  ## What happens?
44
44
 
@@ -49,9 +49,9 @@ Danger runs at the end of a CI build, she will execute a `Dangerfile`. This file
49
49
    |   | Danger :no_entry_sign:
50
50
  -------------: | ------------- | ----
51
51
  :sparkles: | `lines_of_code` | The total amount of lines of code in the diff
52
- :pencil2: | `files_modified` | The list of files modified
53
- :ship: | `files_added` | The list of files added
54
- :recycle: | `files_removed` | The list of files removed
52
+ :pencil2: | `modified_files` | The list of modified files
53
+ :ship: | `added_files` | The list of added files
54
+ :recycle: | `deleted_files` | The list of removed files
55
55
  :abc: | `pr_title` | The title of the PR
56
56
  :book: | `pr_body` | The body of the PR
57
57
  :busts_in_silhouette: | `pr_author` | The author who submitted the PR
@@ -67,18 +67,18 @@ The `Dangerfile` is a ruby file, so really, you can do anything. However, at thi
67
67
  declared_trivial = pr_title.include? "#trivial"
68
68
 
69
69
  # Just to let people know
70
- warn("PR is classed as Work in Progress") if pr_title.include? "[WIP]"
70
+ warn("PR is classed as Work in Progress", sticky: false) if pr_title.include? "[WIP]"
71
71
  ```
72
72
 
73
73
  #### Being cautious around specific files
74
74
 
75
75
  ``` ruby
76
76
  # Devs shouldn't ship changes to this file
77
- fail("Developer Specific file shouldn't be changed") if files_modified.include?("Artsy/View_Controllers/App_Navigation/ARTopMenuViewController+DeveloperExtras.m")
77
+ fail("Developer Specific file shouldn't be changed", sticky: false) if modified_files.include?("Artsy/View_Controllers/App_Navigation/ARTopMenuViewController+DeveloperExtras.m")
78
78
 
79
79
  # Did you make analytics changes? Well you should also include a change to our analytics spec
80
- made_analytics_changes = files_modified.include?("/Artsy/App/ARAppDelegate+Analytics.m")
81
- made_analytics_specs_changes = files_modified.include?("/Artsy_Tests/Analytics_Tests/ARAppAnalyticsSpec.m")
80
+ made_analytics_changes = modified_files.include?("/Artsy/App/ARAppDelegate+Analytics.m")
81
+ made_analytics_specs_changes = modified_files.include?("/Artsy_Tests/Analytics_Tests/ARAppAnalyticsSpec.m")
82
82
  if made_analytics_changes
83
83
  fail("Analytics changes should have reflected specs changes") if !made_analytics_specs_changes
84
84
 
@@ -91,7 +91,7 @@ end
91
91
  #### Pinging people when a specific file has changed
92
92
 
93
93
  ```ruby
94
- message("@orta something changed in elan!") if files_modified.include? "/components/lib/variables/colors.json"
94
+ message("@orta something changed in elan!") if modified_files.include? "/components/lib/variables/colors.json"
95
95
  ```
96
96
 
97
97
  #### Exposing aspects of CI logs into the PR discussion
@@ -102,6 +102,40 @@ snapshots_url = build_log.match(%r{https://eigen-ci.s3.amazonaws.com/\d+/index.h
102
102
  fail("There were [snapshot errors](#{snapshots_url})") if snapshots_url
103
103
  ```
104
104
 
105
+ #### Available commands
106
+
107
+ Command | Description
108
+ ------------- | ----
109
+ `fail` | Causes the PR to fail and print out the error on the PR
110
+ `warn` | Prints out a warning to the PR, but still enables the merge button
111
+ `message` | Show neutral messages on the PR
112
+ `markdown` | Print raw markdown below the summary tables on the PR
113
+
114
+ ## Plugins
115
+
116
+ Danger was built with a platform in mind: It can be used with any kind of software project and allows you to write your own action to have structured source code.
117
+
118
+ In your `Dangerfile` you can import local or remote actions using
119
+
120
+ ```ruby
121
+ import "./danger_plugins/work_in_progress_warning"
122
+ # or
123
+ import "https://raw.githubusercontent.com/danger/danger/master/danger_plugins/work_in_progress_warning.rb"
124
+
125
+ # Call those actions using
126
+ work_in_progress_warning
127
+
128
+ custom_plugin(variable: "value")
129
+ ```
130
+
131
+ To create a new plugin run
132
+
133
+ ```
134
+ danger new_plugin
135
+ ```
136
+
137
+ This will generate a new Ruby file which you can modify to fit your needs.
138
+
105
139
  ## Support
106
140
 
107
141
  Danger currently is supported on Travis CI, Circle CI, BuildKite and Jenkins. These work via environment variables, so it's easy to extend to include your own.
@@ -124,6 +158,23 @@ open to turning useful bits into the official API.
124
158
  Using `danger local` will look for the last merged pull request in your git history, and apply your current
125
159
  `Dangerfile` against that Pull Request. Useful when editing.
126
160
 
161
+ ## Suppress Violations
162
+
163
+ You can tell Danger to ignore a specific warning or error by commenting on the PR body:
164
+
165
+ ```
166
+ > Danger: Ignore "Developer Specific file shouldn't be changed"
167
+ ```
168
+
169
+ ## Sticky
170
+
171
+ Danger can keep its history if a warning/error/message is marked as *sticky*. When the violation is resolved,
172
+ Danger will update the comment to cross it out. If you don't want this behavior, just use `sticky: false`.
173
+
174
+ ```ruby
175
+ fail("PR needs labels", sticky: false) if pr_labels.empty?
176
+ ```
177
+
127
178
  ## Useful bits of knowledge
128
179
 
129
180
  * You can set the base branch in the command line arguments see: `bundle exec danger --help`, if you commonly merge into non-master branches.
@@ -133,6 +184,8 @@ Here are some real-world Dangerfiles: [artsy/eigen](https://github.com/artsy/eig
133
184
 
134
185
  ## License, Contributor's Guidelines and Code of Conduct
135
186
 
187
+ [Join our Slack Group](https://danger-slack.herokuapp.com/)
188
+
136
189
  > This project is open source under the MIT license, which means you have full access to the source code and can modify it to fit your own needs.
137
190
 
138
191
  > This project subscribes to the [Moya Contributors Guidelines](https://github.com/Moya/contributors) which TLDR: means we give out push access easily and often.
@@ -0,0 +1,20 @@
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
@@ -8,9 +8,9 @@ module Danger
8
8
  def self.scm
9
9
  [
10
10
  :lines_of_code,
11
- :files_modified,
12
- :files_deleted,
13
- :files_added,
11
+ :modified_files,
12
+ :deleted_files,
13
+ :added_files,
14
14
  :deletions,
15
15
  :insertions
16
16
  ]
@@ -1,6 +1,6 @@
1
1
  # For more info see: https://github.com/schacon/ruby-git
2
2
 
3
- require 'grit'
3
+ require 'git'
4
4
  require 'uri'
5
5
 
6
6
  module Danger
@@ -13,41 +13,38 @@ module Danger
13
13
  end
14
14
 
15
15
  def git
16
- @git ||= Grit::Git.new(".")
16
+ @git ||= GitRepo.new
17
17
  end
18
18
 
19
19
  def run_git(command)
20
- binary = Grit::Git.git_binary
21
- git.sh "#{binary} #{command}"
20
+ git.exec command
22
21
  end
23
22
 
24
- def initialize(*)
23
+ def initialize(env = {})
24
+ github_host = env["DANGER_GITHUB_HOST"] || "github.com"
25
+
25
26
  # get the remote URL
26
27
  remote = run_git "remote show origin -n | grep \"Fetch URL\" | cut -d ':' -f 2-"
27
28
  if remote
28
- url = remote[0].strip
29
- # deal with https://
30
- if url.start_with? "https://github.com/"
31
- self.repo_slug = url.gsub("https://github.com/", "").gsub(".git", '')
32
-
33
- # deal with SSH origin
34
- elsif url.start_with? "git@github.com:"
35
- self.repo_slug = url.gsub("git@github.com:", "").gsub(".git", '')
29
+ remote_url_matches = remote.match(%r{#{Regexp.escape github_host}(:|/)(?<repo_slug>.+/.+?)(?:\.git)?$})
30
+ if !remote_url_matches.nil? and remote_url_matches["repo_slug"]
31
+ self.repo_slug = remote_url_matches["repo_slug"]
36
32
  else
37
- puts "Danger local requires a repository hosted on github."
33
+ puts "Danger local requires a repository hosted on GitHub.com or GitHub Enterprise."
38
34
  end
39
35
  end
40
36
 
41
37
  # get the most recent PR merge
42
- logs = run_git "log --since='2 weeks ago' --merges --oneline | grep \"Merge pull request\" | head -n 1"
43
- pr_merge = logs[0].strip
44
- if pr_merge
45
- self.pull_request_id = pr_merge.match("#[0-9]*")[0].delete("#")
46
- sha = pr_merge.split(" ")[0]
47
- parents = run_git "rev-list --parents -n 1 #{sha}"
48
- self.base_commit = parents[0].strip.split(" ")[0]
49
- self.head_commit = parents[0].strip.split(" ")[1]
38
+ pr_merge = run_git "log --since='2 weeks ago' --merges --oneline | grep \"Merge pull request\" | head -n 1".strip
39
+ if pr_merge.to_s.empty?
40
+ raise "No recent pull requests found for this repo, danger requires at least one PR for the local mode"
50
41
  end
42
+
43
+ self.pull_request_id = pr_merge.match("#([0-9]+)")[1]
44
+ sha = pr_merge.split(" ")[0]
45
+ parents = run_git("rev-list --parents -n 1 #{sha}").strip.split(" ")
46
+ self.base_commit = parents[0]
47
+ self.head_commit = parents[1]
51
48
  end
52
49
  end
53
50
  end
@@ -14,7 +14,7 @@ module Danger
14
14
 
15
15
  def fetch_build(repo_slug, build_number)
16
16
  url = "project/#{repo_slug}/#{build_number}"
17
- params = { :'circle-token' => circle_token }
17
+ params = { 'circle-token' => circle_token }
18
18
  response = client.get url, params, accept: 'application/json'
19
19
  json = JSON.parse(response.body, symbolize_names: true)
20
20
  json
@@ -75,18 +75,18 @@ module Danger
75
75
  ui.say "that come up in day to day programming. It can be difficult to try and see those from day 1."
76
76
 
77
77
  ui.say "\nIf you'd like to investigate the file, and make some changes - I'll wait here,"
78
- ui.say "press return when you're ready to move on"
78
+ ui.say "press return when you're ready to move on..."
79
79
  ui.wait_for_return
80
80
  end
81
81
 
82
82
  def setup_github_account
83
83
  ui.header 'Step 2: Creating a GitHub account'
84
84
 
85
- ui.say "In order to get the most out of Danger, I'd recommend given her the ability to post in"
85
+ ui.say "In order to get the most out of Danger, I'd recommend giving her the ability to post in"
86
86
  ui.say "the code-review comment section.\n\n"
87
87
  ui.pause 1
88
88
 
89
- ui.say "IMO, it's best do this by using the private mode of your browser. Create an account like"
89
+ ui.say "IMO, it's best to do this by using the private mode of your browser. Create an account like"
90
90
  ui.say "#{@bot_name}, and don't forget a cool robot avatar.\n\n"
91
91
  ui.pause 1
92
92
  ui.say 'Here are great resources for creative commons images of robots:'
@@ -96,14 +96,14 @@ module Danger
96
96
  ui.say ""
97
97
  note_about_clicking_links
98
98
  ui.pause 1
99
- ui.say "\nCool, please press return when you have your account ready (and you've verified the email)"
99
+ ui.say "\nCool, please press return when you have your account ready (and you've verified the email...)"
100
100
  ui.wait_for_return
101
101
  end
102
102
 
103
103
  def setup_access_token
104
104
  ui.header 'Step 3: Configuring a GitHub Personal Access Token'
105
105
 
106
- ui.say "Here's the link, you should open this in your private session with the new GitHub account"
106
+ ui.say "Here's the link, you should open this in the private session where you just created the new GitHub account"
107
107
  ui.link "https://github.com/settings/tokens/new"
108
108
  ui.pause 1
109
109
 
@@ -111,20 +111,21 @@ module Danger
111
111
 
112
112
  if considered_an_oss_repo?
113
113
  ui.say "For Open Source projects, I'd recommend giving the token the smallest scope possible."
114
- ui.say "This means only providing access to " + "public_info".yellow + " in the token.\n\n"
114
+ ui.say "This means only providing access to " + "public_repo".yellow + " in the token.\n\n"
115
115
  ui.pause 1
116
116
  ui.say "This token limits Danger's abilities to just to writing comments on OSS projects. I recommend"
117
- ui.say "this because the token can be quite easily be extracted from the environment via pull requests."
118
- ui.say "#{@bot_name} does not need admin access to your repo. So it's ability to cause chaos is minimalized.\n"
117
+ ui.say "this because the token can quite easily be extracted from the environment via pull requests."
118
+ ui.say "#{@bot_name} does not need admin access to your repo. So its ability to cause chaos is minimalized.\n"
119
119
 
120
120
  elsif @is_open_source == "closed"
121
121
  ui.say "For Closed Source projects, I'd recommend giving the token access to the whole repo scope."
122
- ui.say "This means only providing access to " + "repo".yellow + ", and it's children in the token.\n\n"
122
+ ui.say "This means only providing access to " + "repo".yellow + ", and its children in the token.\n\n"
123
123
  ui.pause 1
124
- ui.say "It's worth noting that you " + "should not".bold.white + " re-use this token for OSS repos. Make a new one for those repos with just " + "public_info".yellow + "."
124
+ ui.say "It's worth noting that you " + "should not".bold.white + " re-use this token for OSS repos."
125
+ ui.say "Make a new one for those repos with just " + "public_repo".yellow + "."
125
126
  end
126
127
 
127
- ui.say "\n👍, please press return when you have your token set up"
128
+ ui.say "\n👍, please press return when you have your token set up..."
128
129
  ui.wait_for_return
129
130
  end
130
131
 
@@ -144,14 +145,14 @@ module Danger
144
145
  uses_circle if File.exist? "circle.yml"
145
146
  unsure_ci unless File.exist?(".travis.yml") || File.exist?(".circle.yml")
146
147
 
147
- ui.say "\nOK, I'll give you a moment to do this"
148
+ ui.say "\nOK, I'll give you a moment to do this..."
148
149
  ui.wait_for_return
149
150
 
150
- ui.say "Final step: exposing the GitHub token as a environment build variable."
151
+ ui.say "Final step: exposing the GitHub token as an environment build variable."
151
152
  ui.pause 0.4
152
153
  if considered_an_oss_repo?
153
154
  ui.say "As you have an Open Source repo, this token should be considered public, otherwise you cannot"
154
- ui.say "run Danger on pull requests from forks, limiting it's use.\n"
155
+ ui.say "run Danger on pull requests from forks, limiting its use.\n"
155
156
  ui.pause 1
156
157
  end
157
158
 
@@ -160,7 +161,7 @@ module Danger
160
161
  unsure_token unless File.exist?(".travis.yml") || File.exist?(".circle.yml")
161
162
 
162
163
  ui.pause 0.6
163
- ui.say "This is the last step, I can give you a second"
164
+ ui.say "This is the last step, I can give you a second..."
164
165
  ui.wait_for_return
165
166
  end
166
167
 
@@ -178,7 +179,7 @@ module Danger
178
179
  end
179
180
 
180
181
  def uses_circle
181
- danger = "bundle exec danger".yellow
182
+ danger = "- bundle exec danger".yellow
182
183
  config = YAML.load(File.read("circle.yml"))
183
184
 
184
185
  if config["test"]
@@ -191,14 +192,14 @@ module Danger
191
192
  ui.say "Add this to the bottom of your circle.yml file:"
192
193
  ui.say "test:".green
193
194
  ui.say " post:".green
194
- ui.say " - bundle exec danger".green
195
+ ui.say " #{danger}".green
195
196
  end
196
197
  end
197
198
 
198
199
  def unsure_ci
199
200
  danger = "bundle exec danger".yellow
200
- ui.say "As I'm not sure what CI you want to run Danger on base on the files in your repo, I'll just offer some generic"
201
- ui.say "advice. You want to run " + danger + " after your tests have finished running, it should be during the testing"
201
+ 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"
202
+ ui.say "advice. You want to run " + danger + " after your tests have finished running, it should still be during the testing"
202
203
  ui.say "process so the build can fail."
203
204
  end
204
205
 
@@ -215,18 +216,18 @@ module Danger
215
216
  def circle_token
216
217
  # https://circleci.com/gh/artsy/eigen/edit#env-vars
217
218
  if considered_an_oss_repo?
218
- ui.say "Before we start, it's important to be up-front. Circle CI only really has one option to support running Danger"
219
+ ui.say "Before we start, it's important to be up-front. CircleCI only really has one option to support running Danger"
219
220
  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"
220
- ui.say "the ramnifications for turning on a setting I'm about to advise.\n"
221
+ ui.say "the ramifications of turning on a setting I'm about to advise.\n"
221
222
  ui.link "https://circleci.com/docs/fork-pr-builds"
222
223
  ui.say "TLDR: If you have anything other than Danger config settings in CircleCI, then you should not turn on the setting."
223
- ui.say "I'll give you a minute to read it"
224
+ ui.say "I'll give you a minute to read it..."
224
225
  ui.wait_for_return
225
226
 
226
227
  ui.say "On Danger/Danger we turn on " + "Permissive building of fork pull requests".yellow + " this exposes the token to Danger"
227
228
  ui.say "You can find this setting at:"
228
229
  ui.link "https://circleci.com/gh/#{current_repo_slug}/edit#experimental\n"
229
- ui.say "I'll hold"
230
+ ui.say "I'll hold..."
230
231
  ui.wait_for_return
231
232
  end
232
233
 
@@ -248,7 +249,7 @@ module Danger
248
249
  ui.header "Useful info"
249
250
  ui.say "- One of the best ways to test out new rules locally is via " + "bundle exec danger local".yellow + "."
250
251
  ui.pause 0.6
251
- ui.say "- You can have Danger output all of it's variables to the console via the " + "--verbose".yellow + "option."
252
+ ui.say "- You can have Danger output all of its variables to the console via the " + "--verbose".yellow + " option."
252
253
  ui.pause 0.6
253
254
  ui.say "- You can look at the following Dangerfiles to get some more ideas:"
254
255
  ui.pause 0.6
@@ -56,7 +56,7 @@ module Danger
56
56
  show_prompt
57
57
  answer = STDIN.gets.chomp
58
58
 
59
- break if answer.length > 0
59
+ break if answer.empty?
60
60
 
61
61
  print "\nYou need to provide an answer."
62
62
  end
@@ -22,12 +22,14 @@ module Danger
22
22
  dm.env = EnvironmentManager.new(ENV)
23
23
 
24
24
  source = dm.env.ci_source
25
- unless source.repo_slug
26
- puts "danger local".red " failed because it only works with GitHub projects at the moment. Sorry."
25
+ if source.nil? or source.repo_slug.empty?
26
+ puts "danger local failed because it only works with GitHub projects at the moment. Sorry.".red
27
27
  exit 0
28
28
  end
29
29
 
30
- puts "Running your Dangerfile against this PR - https://github.com/#{source.repo_slug}/pulls/#{source.pull_request_id}"
30
+ gh = dm.env.request_source
31
+
32
+ puts "Running your Dangerfile against this PR - https://#{gh.github_host}/#{source.repo_slug}/pull/#{source.pull_request_id}"
31
33
 
32
34
  if verbose != true
33
35
  puts "Turning on --verbose"
@@ -36,7 +38,6 @@ module Danger
36
38
 
37
39
  puts ""
38
40
 
39
- gh = GitHub.new(dm.env.ci_source, ENV)
40
41
  # We can use tokenless here, as it's running on someone's computer
41
42
  # and is IP locked, as opposed to on the CI.
42
43
  gh.support_tokenless_auth = true
@@ -47,7 +48,8 @@ module Danger
47
48
  dm.env.scm = GitRepo.new
48
49
 
49
50
  dm.env.scm.diff_for_folder(".", from: dm.env.ci_source.base_commit, to: dm.env.ci_source.head_commit)
50
- dm.parse Pathname.new(@dangerfile_path)
51
+ dm.parse(Pathname.new(@dangerfile_path))
52
+ dm.print_results
51
53
  end
52
54
  end
53
55
  end
@@ -0,0 +1,43 @@
1
+ module Danger
2
+ class NewPlugin < Runner
3
+ self.summary = 'Generate a new danger plugin.'
4
+ self.command = 'new_plugin'
5
+
6
+ def initialize(argv)
7
+ super
8
+ end
9
+
10
+ def validate!
11
+ super
12
+ end
13
+
14
+ def run
15
+ require 'fileutils'
16
+
17
+ puts "Must be lower case, and use a '_' between words. Do not use '.'".green
18
+ puts "examples: 'number_of_emojis', 'ensure_pr_title_contains_keyword'".green
19
+ puts "Name of your new plugin: "
20
+ name = STDIN.gets.strip
21
+
22
+ dir = Danger.gem_path
23
+ content = File.read(File.join(dir, "lib", "assets", "PluginTemplate.rb.template"))
24
+ content.gsub!("[[CLASS_NAME]]", name.danger_class)
25
+
26
+ plugins_path = "danger_plugins"
27
+ FileUtils.mkdir_p("plugins_path") unless File.directory?(plugins_path)
28
+
29
+ output_path = File.join(plugins_path, "#{name}.rb")
30
+ raise "File '#{output_path}' already exists!" if File.exist?(output_path)
31
+ File.write(output_path, content)
32
+
33
+ puts ""
34
+ puts "Successfully created new plugin at path '#{output_path}'".green
35
+ puts "Add this to your `Dangerfile` to use it:"
36
+ puts ""
37
+ puts "import \"#{output_path.gsub('.rb', '')}\"".blue
38
+ puts "#{name}(parameter1: 123, parameter2: \"Club Mate\")".blue
39
+ puts ""
40
+ puts "Enjoy ✨"
41
+ end
42
+ end
43
+ end
@@ -2,6 +2,7 @@ module Danger
2
2
  class Runner < CLAide::Command
3
3
  require 'danger/commands/init'
4
4
  require 'danger/commands/local'
5
+ require 'danger/commands/new_plugin'
5
6
 
6
7
  self.summary = 'Run the Dangerfile.'
7
8
  self.command = 'danger'
@@ -33,22 +34,27 @@ module Danger
33
34
  dm.verbose = verbose
34
35
  dm.env = EnvironmentManager.new(ENV)
35
36
  return unless dm.env.ci_source # if it's not a PR
36
- dm.env.fill_environment_vars
37
37
 
38
- gh = dm.env.request_source
39
- ci_base = @base || gh.base_commit
40
- ci_head = @head || gh.head_commit
38
+ dm.env.fill_environment_vars
39
+ dm.env.ensure_danger_branches_are_setup
41
40
 
41
+ # Offer the chance for a user to specify a branch through the command line
42
+ ci_base = @base || dm.env.danger_head_branch
43
+ ci_head = @head || dm.env.danger_base_branch
42
44
  dm.env.scm.diff_for_folder(".", from: ci_base, to: ci_head)
43
45
 
44
46
  dm.parse Pathname.new(@dangerfile_path)
45
47
 
46
48
  post_results(dm)
49
+
50
+ dm.env.clean_up
51
+
52
+ dm.print_results
47
53
  end
48
54
 
49
55
  def post_results(dm)
50
56
  gh = dm.env.request_source
51
- gh.update_pull_request!(warnings: dm.warnings, errors: dm.errors, messages: dm.messages)
57
+ gh.update_pull_request!(warnings: dm.warnings, errors: dm.errors, messages: dm.messages, markdowns: dm.markdowns)
52
58
  end
53
59
  end
54
60
  end
@@ -1,24 +1,41 @@
1
1
  <% @tables.each do |table| %>
2
- <% if table[:content].any? %>
2
+ <% if table[:content].any? || table[:resolved].any? %>
3
3
  <table>
4
4
  <thead>
5
5
  <tr>
6
6
  <th width="50"></th>
7
- <th width="100%"><%= table[:content].count %> <%= table[:name] %><%= "s" unless table[:content].count == 1 %></th>
7
+ <th width="100%" data-kind="<%= table[:name] %>">
8
+ <% if table[:count] > 0 %>
9
+ <%= table[:count] %> <%= table[:name] %><%= "s" unless table[:count] == 1 %>
10
+ <% else %>
11
+ :white_check_mark: <%= random_compliment %>
12
+ <% end %>
13
+ </th>
8
14
  </tr>
9
15
  </thead>
10
16
  <tbody>
11
- <% table[:content].each do |message| -%>
17
+ <% table[:content].each do |violation| -%>
12
18
  <tr>
13
19
  <td>:<%= table[:emoji] %>:</td>
14
- <td><%= message %></td>
20
+ <td data-sticky="<%= violation.sticky %>"><%= violation.message %></td>
15
21
  </tr>
16
22
  <% end %>
23
+ <% table[:resolved].each do |message| -%>
24
+ <tr>
25
+ <td>:white_check_mark:</td>
26
+ <td data-sticky="true"><del><%= message %></del></td>
27
+ </tr>
28
+ <% end %>
17
29
  </tbody>
18
30
  </table>
19
31
  <% end %>
20
32
  <% end %>
21
33
 
34
+ <% @markdowns.each do |current| %>
35
+ <%= current %>
36
+ <%# the previous line has to be aligned far to the left, otherwise markdown can break easily %>
37
+ <% end %>
38
+
22
39
  <p align="right" data-meta="generated_by_danger" data-base-commit="<%= @base_commit %>" data-head-commit="<%= @head_commit %>" >
23
40
  Generated by :no_entry_sign: <a href="https://github.com/danger/danger/">danger</a>
24
41
  </p>
@@ -0,0 +1,13 @@
1
+ class String
2
+ def danger_class
3
+ split('_').collect!(&:capitalize).join
4
+ end
5
+
6
+ def danger_underscore
7
+ self.gsub(/::/, '/').
8
+ gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
9
+ gsub(/([a-z\d])([A-Z])/, '\1_\2').
10
+ tr("-", "_").
11
+ downcase
12
+ end
13
+ end