danger 0.8.3 ā 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/danger/ci_source/circle.rb +0 -1
- data/lib/danger/commands/init.rb +3 -1
- data/lib/danger/commands/plugins/plugin_abstract.rb +11 -0
- data/lib/danger/commands/plugins/plugin_lint.rb +37 -0
- data/lib/danger/commands/{new_plugin.rb ā plugins/plugin_new.rb} +2 -2
- data/lib/danger/commands/plugins/plugin_readme.rb +42 -0
- data/lib/danger/commands/runner.rb +1 -1
- data/lib/danger/danger_core/dangerfile.rb +19 -7
- data/lib/danger/danger_core/plugins/dangerfile_git_plugin.rb +31 -0
- data/lib/danger/danger_core/plugins/dangerfile_github_plugin.rb +66 -13
- data/lib/danger/danger_core/plugins/dangerfile_import_plugin.rb +33 -4
- data/lib/danger/danger_core/plugins/dangerfile_messaging_plugin.rb +56 -0
- data/lib/danger/plugin_support/plugin.rb +4 -0
- data/lib/danger/plugin_support/plugin_file_resolver.rb +48 -0
- data/lib/danger/plugin_support/plugin_parser.rb +36 -19
- data/lib/danger/plugin_support/templates/readme_table.html.erb +24 -0
- data/lib/danger/version.rb +1 -1
- metadata +22 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f27652279a0f07304e15f1f8dacf222f2da87e14
|
4
|
+
data.tar.gz: 5446bc7ea136645a886279cc5323b507a5d4b487
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 385dac5d395271a311240bb80ad17b92b8020369ccd332f4d6bf2c5d7f90584c0036e10140dd20fc8b15f3250a18e59d48980d4dfdc9fafb53b6811801e3c57b
|
7
|
+
data.tar.gz: 27ea416083b1b0bd56252d4bb9185be4ef7e1904a4021fe96cda3ae90ea25de33c63d6680a4aa819b14df46746d5040004e95330f10c5aa9f61c9c4bf31ff662
|
data/README.md
CHANGED
@@ -25,13 +25,13 @@ Add this line to your application's [Gemfile](https://guides.cocoapods.org/using
|
|
25
25
|
gem 'danger'
|
26
26
|
```
|
27
27
|
|
28
|
-
|
28
|
+
Next, use Bundler to install the gem.
|
29
29
|
|
30
30
|
```shell
|
31
31
|
bundle install
|
32
32
|
```
|
33
33
|
|
34
|
-
|
34
|
+
After the gem is installed, you can run Danger's interactive getting started guide:
|
35
35
|
|
36
36
|
```
|
37
37
|
bundle exec danger init
|
data/lib/danger/commands/init.rb
CHANGED
@@ -121,6 +121,8 @@ module Danger
|
|
121
121
|
ui.pause 1
|
122
122
|
ui.say "It's worth noting that you " + "should not".bold.white + " re-use this token for OSS repos."
|
123
123
|
ui.say "Make a new one for those repos with just " + "public_repo".yellow + "."
|
124
|
+
ui.pause 1
|
125
|
+
ui.say "Additionally, don't forget to add your new GitHub account as a collaborator to your Closed Source project."
|
124
126
|
end
|
125
127
|
|
126
128
|
ui.say "\nš, please press return when you have your token set up..."
|
@@ -225,7 +227,7 @@ module Danger
|
|
225
227
|
|
226
228
|
ui.say "On Danger/Danger we turn on " + "Permissive building of fork pull requests".yellow + " this exposes the token to Danger"
|
227
229
|
ui.say "You can find this setting at:"
|
228
|
-
ui.link "https://circleci.com/gh/#{current_repo_slug}/edit#
|
230
|
+
ui.link "https://circleci.com/gh/#{current_repo_slug}/edit#advanced-settings\n"
|
229
231
|
ui.say "I'll hold..."
|
230
232
|
ui.wait_for_return
|
231
233
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Danger
|
2
|
+
class PluginAbstract < Runner
|
3
|
+
require 'danger/commands/plugins/plugin_lint'
|
4
|
+
require 'danger/commands/plugins/plugin_readme'
|
5
|
+
require 'danger/commands/plugins/plugin_new'
|
6
|
+
|
7
|
+
self.command = 'plugin'
|
8
|
+
|
9
|
+
self.abstract_command = true
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'danger/commands/plugins/plugin_abstract'
|
2
|
+
require 'danger/plugin_support/plugin_parser'
|
3
|
+
require 'danger/plugin_support/plugin_file_resolver'
|
4
|
+
|
5
|
+
module Danger
|
6
|
+
class PluginLint < PluginAbstract
|
7
|
+
self.summary = 'Lints a plugin'
|
8
|
+
self.command = 'lint'
|
9
|
+
|
10
|
+
def initialize(argv)
|
11
|
+
@refs = argv.arguments! unless argv.arguments.empty?
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
self.summary = 'Lint plugins from files, gems or the current folder. Outputs JSON array representation of Plugins on success.'
|
16
|
+
|
17
|
+
self.description = <<-DESC
|
18
|
+
Converts a collection of file paths of Danger plugins into a JSON format.
|
19
|
+
Note: Before 1.0, it will also parse the represented JSON to validate whether http://danger.systems would
|
20
|
+
show the plugin on the website.
|
21
|
+
DESC
|
22
|
+
|
23
|
+
self.arguments = [
|
24
|
+
CLAide::Argument.new('Paths, Gems or Nothing', false, true)
|
25
|
+
]
|
26
|
+
|
27
|
+
def run
|
28
|
+
file_resolver = PluginFileResolver.new(@refs)
|
29
|
+
paths = file_resolver.resolve_to_paths
|
30
|
+
|
31
|
+
parser = PluginParser.new(paths)
|
32
|
+
parser.parse
|
33
|
+
json = parser.to_json
|
34
|
+
cork.puts json
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'danger/commands/plugins/plugin_abstract'
|
2
|
+
require 'danger/plugin_support/plugin_parser'
|
3
|
+
require 'danger/plugin_support/plugin_file_resolver'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Danger
|
7
|
+
class PluginReadme < PluginAbstract
|
8
|
+
self.summary = 'Generates a README from a set of plugins'
|
9
|
+
self.command = 'readme'
|
10
|
+
|
11
|
+
def initialize(argv)
|
12
|
+
@refs = argv.arguments! unless argv.arguments.empty?
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
self.summary = 'Lint plugins from files, gems or the current folder. Outputs JSON array representation of Plugins on success.'
|
17
|
+
|
18
|
+
self.description = <<-DESC
|
19
|
+
Converts a collection of file paths of Danger plugins into a format usable in a README.
|
20
|
+
This is useful for Danger itself, but also for any plugins wanting to showcase their API.
|
21
|
+
DESC
|
22
|
+
|
23
|
+
self.arguments = [
|
24
|
+
CLAide::Argument.new('Paths, Gems or Nothing', false, true)
|
25
|
+
]
|
26
|
+
|
27
|
+
attr_accessor :json, :markdown
|
28
|
+
def run
|
29
|
+
file_resolver = PluginFileResolver.new(@refs)
|
30
|
+
paths = file_resolver.resolve_to_paths
|
31
|
+
|
32
|
+
parser = PluginParser.new(paths)
|
33
|
+
parser.parse
|
34
|
+
|
35
|
+
self.markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, no_intra_emphasis: true)
|
36
|
+
self.json = JSON.parse(parser.to_json)
|
37
|
+
|
38
|
+
template = File.join(Danger.gem_path, "lib/danger/plugin_support/templates/readme_table.html.erb")
|
39
|
+
cork.puts ERB.new(File.read(template), 0, "-").result(binding)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -2,7 +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/
|
5
|
+
require 'danger/commands/plugins/plugin_abstract'
|
6
6
|
|
7
7
|
self.summary = 'Run the Dangerfile.'
|
8
8
|
self.command = 'danger'
|
@@ -30,7 +30,7 @@ module Danger
|
|
30
30
|
|
31
31
|
# These are the classes that are allowed to also use method_missing
|
32
32
|
# in order to provide broader plugin support
|
33
|
-
def core_plugin_classes
|
33
|
+
def self.core_plugin_classes
|
34
34
|
[
|
35
35
|
Danger::DangerfileMessagingPlugin,
|
36
36
|
Danger::DangerfileImportPlugin,
|
@@ -94,7 +94,7 @@ module Danger
|
|
94
94
|
instance_variable_set("@#{name}", plugin)
|
95
95
|
|
96
96
|
@plugins[klass] = plugin
|
97
|
-
@core_plugins << plugin if core_plugin_classes.include? klass
|
97
|
+
@core_plugins << plugin if self.class.core_plugin_classes.include? klass
|
98
98
|
end
|
99
99
|
end
|
100
100
|
alias init_plugins refresh_plugins
|
@@ -113,12 +113,24 @@ module Danger
|
|
113
113
|
methods = plugin_hash[:methods].select { |name| plugin.method(name).parameters.empty? }
|
114
114
|
|
115
115
|
methods.map do |method|
|
116
|
-
|
117
|
-
|
116
|
+
case method
|
117
|
+
when :api
|
118
|
+
value = "Octokit::Client"
|
119
|
+
|
120
|
+
when :pr_json
|
121
|
+
value = "[Skipped]"
|
122
|
+
|
123
|
+
when :pr_body
|
124
|
+
value = plugin.send(method)
|
125
|
+
value = value.scan(/.{,80}/).to_a.each(&:strip!).join("\n")
|
126
|
+
|
127
|
+
else
|
128
|
+
value = plugin.send(method)
|
129
|
+
# So that we either have one value per row
|
130
|
+
# or we have [] for an empty array
|
131
|
+
value = value.join("\n") if value.kind_of?(Array) && value.count > 0
|
132
|
+
end
|
118
133
|
|
119
|
-
# So that we either have one value per row
|
120
|
-
# or we have [] for an empty array
|
121
|
-
value = value.join("\n") if value.kind_of?(Array) && value.count > 0
|
122
134
|
[method.to_s, value]
|
123
135
|
end
|
124
136
|
end
|
@@ -2,7 +2,38 @@ require 'danger/plugin_support/plugin'
|
|
2
2
|
require 'danger/core_ext/file_list'
|
3
3
|
|
4
4
|
module Danger
|
5
|
+
# Handles interacting with git inside a Dangerfile. Providing access to files that have changed, and useful statistics. Also provides
|
6
|
+
# access to the commits in the form of [Git::Log](https://github.com/schacon/ruby-git/blob/master/lib/git/log.rb) objects.
|
7
|
+
#
|
8
|
+
# @example Do something to all new and edited markdown files
|
9
|
+
#
|
10
|
+
# markdowns = (git.added_files + git.modified_files)
|
11
|
+
# do_something markdowns.select{ |file| file.end_with? "md" }
|
12
|
+
#
|
13
|
+
# @example Don't allow a file to be deleted
|
14
|
+
#
|
15
|
+
# deleted = git.deleted_files.include? "my/favourite.file"
|
16
|
+
# fail "Don't delete my precious" if deleted
|
17
|
+
#
|
18
|
+
# @example Fail really big diffs
|
19
|
+
#
|
20
|
+
# fail "We cannot handle the scale of this PR" if git.lines_of_code > 50_000
|
21
|
+
#
|
22
|
+
# @example Warn when there are merge commits in the diff
|
23
|
+
#
|
24
|
+
# if commits.any? { |c| c.message =~ /^Merge branch 'master'/ }
|
25
|
+
# warn 'Please rebase to get rid of the merge commits in this PR'
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
#
|
29
|
+
# @see danger/danger
|
30
|
+
# @tags core, git
|
31
|
+
|
5
32
|
class DangerfileGitPlugin < Plugin
|
33
|
+
def self.instance_name
|
34
|
+
"git"
|
35
|
+
end
|
36
|
+
|
6
37
|
def initialize(dangerfile)
|
7
38
|
super(dangerfile)
|
8
39
|
raise unless dangerfile.env.scm.class == Danger::GitRepo
|
@@ -1,6 +1,30 @@
|
|
1
1
|
require 'danger/plugin_support/plugin'
|
2
2
|
|
3
3
|
module Danger
|
4
|
+
# Handles interacting with GitHub inside a Dangerfile. Provides a few functions which wrap `pr_json` and also
|
5
|
+
# through a few standard functions to simplify your code.
|
6
|
+
#
|
7
|
+
# @example Warn when a PR is classed as work in progress
|
8
|
+
#
|
9
|
+
# warn "PR is classed as Work in Progress" if github.pr_title.include? "[WIP]"
|
10
|
+
#
|
11
|
+
# @example Ensure that labels have been used on the PR
|
12
|
+
#
|
13
|
+
# fail "Please add labels to this PR" if github.labels.empty?
|
14
|
+
#
|
15
|
+
# @example Check if a user is in a specific GitHub org, and message them if so
|
16
|
+
#
|
17
|
+
# unless github.api.organization_member?('danger', github.pr_author)
|
18
|
+
# message "@#{pr_author} is not a contributor yet, would you like to join the Danger org?"
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# @example Ensure there is a summary for a PR
|
22
|
+
#
|
23
|
+
# fail "Please provide a summary in the Pull Request description" if github.pr_body.length < 5
|
24
|
+
#
|
25
|
+
# @see danger/danger
|
26
|
+
# @tags core, github
|
27
|
+
|
4
28
|
class DangerfileGitHubPlugin < Plugin
|
5
29
|
def initialize(dangerfile)
|
6
30
|
super(dangerfile)
|
@@ -9,8 +33,12 @@ module Danger
|
|
9
33
|
@github = dangerfile.env.request_source
|
10
34
|
end
|
11
35
|
|
36
|
+
def self.instance_name
|
37
|
+
"github"
|
38
|
+
end
|
39
|
+
|
12
40
|
# @!group PR Metadata
|
13
|
-
# The title of the Pull Request
|
41
|
+
# The title of the Pull Request.
|
14
42
|
# @return String
|
15
43
|
#
|
16
44
|
def pr_title
|
@@ -18,23 +46,23 @@ module Danger
|
|
18
46
|
end
|
19
47
|
|
20
48
|
# @!group PR Metadata
|
21
|
-
# The body text of the Pull Request
|
49
|
+
# The body text of the Pull Request.
|
22
50
|
# @return String
|
23
51
|
#
|
24
52
|
def pr_body
|
25
|
-
|
53
|
+
pr_json[:body].to_s
|
26
54
|
end
|
27
55
|
|
28
56
|
# @!group PR Metadata
|
29
|
-
# The username of the author of the Pull Request
|
57
|
+
# The username of the author of the Pull Request.
|
30
58
|
# @return String
|
31
59
|
#
|
32
60
|
def pr_author
|
33
|
-
|
61
|
+
pr_json[:user][:login].to_s
|
34
62
|
end
|
35
63
|
|
36
64
|
# @!group PR Metadata
|
37
|
-
# The labels assigned to the Pull Request
|
65
|
+
# The labels assigned to the Pull Request.
|
38
66
|
# @return [String]
|
39
67
|
#
|
40
68
|
def pr_labels
|
@@ -42,27 +70,52 @@ module Danger
|
|
42
70
|
end
|
43
71
|
|
44
72
|
# @!group PR Commit Metadata
|
45
|
-
# The branch to which the PR is going to be merged into
|
73
|
+
# The branch to which the PR is going to be merged into.
|
46
74
|
# @return String
|
47
75
|
#
|
48
|
-
def
|
49
|
-
|
76
|
+
def branch_for_base
|
77
|
+
pr_json[:base][:ref]
|
50
78
|
end
|
51
79
|
|
52
80
|
# @!group PR Commit Metadata
|
53
|
-
# The
|
81
|
+
# The branch to which the PR is going to be merged from.
|
82
|
+
# @return String
|
83
|
+
#
|
84
|
+
def branch_for_head
|
85
|
+
pr_json[:head][:ref]
|
86
|
+
end
|
87
|
+
|
88
|
+
# @!group PR Commit Metadata
|
89
|
+
# The base commit to which the PR is going to be merged as a parent.
|
54
90
|
# @return String
|
55
91
|
#
|
56
92
|
def base_commit
|
57
|
-
|
93
|
+
pr_json[:base][:sha]
|
58
94
|
end
|
59
95
|
|
60
96
|
# @!group PR Commit Metadata
|
61
|
-
# The head commit to which the PR is requesting to be merged from
|
97
|
+
# The head commit to which the PR is requesting to be merged from.
|
62
98
|
# @return String
|
63
99
|
#
|
64
100
|
def head_commit
|
65
|
-
|
101
|
+
pr_json[:head][:sha]
|
102
|
+
end
|
103
|
+
|
104
|
+
# @!group GitHub Misca
|
105
|
+
# The hash that represents the PR's JSON. For an example of what this looks like
|
106
|
+
# see the [Danger Fixture'd one](https://raw.githubusercontent.com/danger/danger/master/spec/fixtures/pr_response.json).
|
107
|
+
# @return Hash
|
108
|
+
#
|
109
|
+
def pr_json
|
110
|
+
@github.pr_json
|
111
|
+
end
|
112
|
+
|
113
|
+
# @!group GitHub Misc
|
114
|
+
# Provides access to the GitHub API client used inside Danger. Making
|
115
|
+
# it easy to use the GitHub API inside a Dangerfile.
|
116
|
+
# @return Octokit::Client
|
117
|
+
def api
|
118
|
+
@github.client
|
66
119
|
end
|
67
120
|
end
|
68
121
|
end
|
@@ -1,9 +1,35 @@
|
|
1
1
|
require 'danger/plugin_support/plugin'
|
2
2
|
|
3
3
|
module Danger
|
4
|
+
# One way to support internal plugins is via `plugin.import` this gives you
|
5
|
+
# the chance to quickly iterate without the need for building rubygems. As such,
|
6
|
+
# it does not have the stringent rules around documentation expected of a public plugin.
|
7
|
+
# It's worth noting, that you can also have plugins inside `./danger_plugins` and they
|
8
|
+
# will be automatically imported into your Dangerfile at launch.
|
9
|
+
#
|
10
|
+
# @example Import a plugin available over HTTP
|
11
|
+
#
|
12
|
+
# device_grid = "https://raw.githubusercontent.com/fastlane/fastlane/master/danger-device_grid/lib/device_grid/plugin.rb"
|
13
|
+
# plugin.import device_grid
|
14
|
+
#
|
15
|
+
# @example Import from a local file reference
|
16
|
+
#
|
17
|
+
# plugin.import "danger/plugins/watch_plugin.rb"
|
18
|
+
#
|
19
|
+
# @example Import all files inside a folder
|
20
|
+
#
|
21
|
+
# plugin.import "danger/plugins/*.rb"
|
22
|
+
#
|
23
|
+
# @see danger/danger
|
24
|
+
# @tags core, plugins
|
25
|
+
|
4
26
|
class DangerfileImportPlugin < Plugin
|
27
|
+
def self.instance_name
|
28
|
+
"plugin"
|
29
|
+
end
|
30
|
+
|
5
31
|
# @!group Plugins
|
6
|
-
# Download a local or remote plugin and use it
|
32
|
+
# Download a local or remote plugin and use it inside the Dangerfile.
|
7
33
|
#
|
8
34
|
# @param [String] path
|
9
35
|
# a local path or a https URL to the Ruby file to import
|
@@ -19,8 +45,10 @@ module Danger
|
|
19
45
|
end
|
20
46
|
end
|
21
47
|
|
48
|
+
private
|
49
|
+
|
22
50
|
# @!group Plugins
|
23
|
-
# Download a remote plugin and use it locally
|
51
|
+
# Download a remote plugin and use it locally.
|
24
52
|
#
|
25
53
|
# @param [String] url
|
26
54
|
# https URL to the Ruby file to use
|
@@ -43,14 +71,15 @@ module Danger
|
|
43
71
|
end
|
44
72
|
|
45
73
|
# @!group Plugins
|
46
|
-
# Import one or more local plugins
|
74
|
+
# Import one or more local plugins.
|
47
75
|
#
|
48
76
|
# @param [String] path
|
49
77
|
# The path to the file to import
|
50
78
|
# Can also be a pattern (./**/*plugin.rb)
|
51
79
|
def import_local(path)
|
52
80
|
Dir[path].each do |file|
|
53
|
-
|
81
|
+
# Without the expand_path it would fail if the path doesn't start with ./
|
82
|
+
require File.expand_path(file)
|
54
83
|
refresh_plugins
|
55
84
|
end
|
56
85
|
end
|
@@ -2,6 +2,47 @@ require 'danger/danger_core/violation'
|
|
2
2
|
require 'danger/plugin_support/plugin'
|
3
3
|
|
4
4
|
module Danger
|
5
|
+
# Provides the feedback mechanism for Danger. Danger can keep track of
|
6
|
+
# messages, warnings, failure and post arbitrary markdown into a comment.
|
7
|
+
#
|
8
|
+
# The message within which Danger communicates back is amended on each run in a session.
|
9
|
+
#
|
10
|
+
# Each of `message`, `warn` and `fail` have a `sticky` flag, `true` by default, which
|
11
|
+
# means that the message will be crossed out instead of being removed. If it's not use on
|
12
|
+
# subsequent runs.
|
13
|
+
#
|
14
|
+
# By default, using `fail` would fail the corresponding build. Either via an API call, or
|
15
|
+
# via the return value for the danger command.
|
16
|
+
#
|
17
|
+
# It is possible to have Danger ignore specific warnings or errors by writing `Danger: Ignore "[warning/error text]`.
|
18
|
+
#
|
19
|
+
# Sidenote: Messaging is the only plugin which adds functions to the root of the Dangerfile.
|
20
|
+
#
|
21
|
+
# @example Failing a build
|
22
|
+
#
|
23
|
+
# fail "This build didn't pass tests"
|
24
|
+
#
|
25
|
+
# @example Failing a build, but not keeping it's value around on subsequent runs
|
26
|
+
#
|
27
|
+
# fail("This build didn't pass tests", sticky: false)
|
28
|
+
#
|
29
|
+
# @example Passing a warning
|
30
|
+
#
|
31
|
+
# warn "This build didn't pass linting"
|
32
|
+
#
|
33
|
+
# @example Displaying a markdown table
|
34
|
+
#
|
35
|
+
# message = "### Proselint found issues\n\n"
|
36
|
+
# message << "Line | Message | Severity |\n"
|
37
|
+
# message << "| --- | ----- | ----- |\n"
|
38
|
+
# message << "20 | No documentation | Error \n"
|
39
|
+
# markdown message
|
40
|
+
#
|
41
|
+
#
|
42
|
+
# @see danger/danger
|
43
|
+
# @tags core, messaging
|
44
|
+
#
|
45
|
+
|
5
46
|
class DangerfileMessagingPlugin < Plugin
|
6
47
|
def initialize(dangerfile)
|
7
48
|
super(dangerfile)
|
@@ -12,6 +53,10 @@ module Danger
|
|
12
53
|
@markdowns = []
|
13
54
|
end
|
14
55
|
|
56
|
+
def self.instance_name
|
57
|
+
"messaging"
|
58
|
+
end
|
59
|
+
|
15
60
|
# @!group Core
|
16
61
|
# Print markdown to below the table
|
17
62
|
#
|
@@ -57,6 +102,11 @@ module Danger
|
|
57
102
|
@errors << Violation.new(message, sticky)
|
58
103
|
end
|
59
104
|
|
105
|
+
# @!group Reporting
|
106
|
+
# A list of all messages passed to Danger, including
|
107
|
+
# the markdowns.
|
108
|
+
#
|
109
|
+
# @return Hash
|
60
110
|
def status_report
|
61
111
|
{
|
62
112
|
errors: @errors.map(&:message).clone.freeze,
|
@@ -66,6 +116,12 @@ module Danger
|
|
66
116
|
}
|
67
117
|
end
|
68
118
|
|
119
|
+
# @!group Reporting
|
120
|
+
# A list of all violations passed to Danger, we don't
|
121
|
+
# anticipate users of Danger needing to use this.
|
122
|
+
#
|
123
|
+
# @visibility hidden
|
124
|
+
# @return Hash
|
69
125
|
def violation_report
|
70
126
|
{
|
71
127
|
errors: @errors.clone.freeze,
|
@@ -25,6 +25,10 @@ module Danger
|
|
25
25
|
@all_plugins ||= []
|
26
26
|
end
|
27
27
|
|
28
|
+
def self.clear_external_plugins
|
29
|
+
@all_plugins = @all_plugins.select { |plugin| Dangerfile.core_plugin_classes.include? plugin }
|
30
|
+
end
|
31
|
+
|
28
32
|
def self.inherited(plugin)
|
29
33
|
Plugin.all_plugins.push(plugin)
|
30
34
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module Danger
|
5
|
+
class PluginFileResolver
|
6
|
+
# Takes an array of files, gems or nothing, then resolves them into
|
7
|
+
# paths that should be sent into the documentation parser
|
8
|
+
def initialize(references)
|
9
|
+
@refs = references
|
10
|
+
end
|
11
|
+
|
12
|
+
def resolve_to_paths
|
13
|
+
# When given existing paths, map to absolute & existing paths
|
14
|
+
if !@refs.nil? and @refs.select { |ref| File.file? ref }.any?
|
15
|
+
@refs.select { |ref| File.file? ref }.map { |path| File.expand_path(path) }
|
16
|
+
|
17
|
+
# When given a list of gems
|
18
|
+
elsif @refs and @refs.kind_of? Array
|
19
|
+
|
20
|
+
Dir.mktmpdir do |dir|
|
21
|
+
gem_names = @refs
|
22
|
+
deps = gem_names.map { |name| Bundler::Dependency.new(name, ">= 0") }
|
23
|
+
|
24
|
+
# Use Gems from rubygems.org
|
25
|
+
source = Bundler::SourceList.new
|
26
|
+
source.add_rubygems_remote("https://rubygems.org")
|
27
|
+
|
28
|
+
# Create a definition to bundle, make sure it always updates
|
29
|
+
# and uses the latest version from the server
|
30
|
+
bundler = Bundler::Definition.new(nil, deps, source, true)
|
31
|
+
bundler.resolve_remotely!
|
32
|
+
|
33
|
+
# Install the gems into a tmp dir
|
34
|
+
options = { path: dir }
|
35
|
+
Bundler::Installer.install(Pathname.new(dir), bundler, options)
|
36
|
+
|
37
|
+
# Get the name'd gems out of bundler, then pull out all their paths
|
38
|
+
gems = gem_names.flat_map { |name| bundler.specs[name] }
|
39
|
+
gems.flat_map { |gem| Dir.glob(File.join(gem.gem_dir, "lib/**/**/**.rb")) }
|
40
|
+
end
|
41
|
+
|
42
|
+
# When empty, imply you want to test the current lib folder as a plugin
|
43
|
+
else
|
44
|
+
Dir.glob(File.join(".", "lib/*.rb"))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,32 +1,46 @@
|
|
1
|
-
require '
|
1
|
+
require 'json'
|
2
2
|
|
3
3
|
module Danger
|
4
4
|
class PluginParser
|
5
5
|
attr_accessor :registry
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
|
7
|
+
def initialize(paths)
|
8
|
+
raise "Path cannot be empty" if paths.empty?
|
9
|
+
|
10
|
+
if paths.is_a? String
|
11
|
+
@paths = [File.expand_path(paths)]
|
12
|
+
else
|
13
|
+
@paths = paths
|
14
|
+
end
|
9
15
|
end
|
10
16
|
|
11
17
|
def parse
|
18
|
+
require 'yard'
|
12
19
|
# could this go in a singleton-y place instead?
|
13
20
|
# like class initialize?
|
14
21
|
YARD::Tags::Library.define_tag('tags', :tags)
|
22
|
+
YARD::Tags::Library.define_tag('availablity', :availablity)
|
23
|
+
files = ["lib/danger/plugin_support/plugin.rb"] + @paths
|
15
24
|
|
16
|
-
|
25
|
+
# This turns on YARD debugging
|
26
|
+
# $DEBUG = true
|
27
|
+
|
17
28
|
self.registry = YARD::Registry.load(files, true)
|
18
29
|
end
|
19
30
|
|
20
31
|
def classes_in_file
|
21
|
-
|
22
|
-
.select { |thing| thing.type == :class }
|
23
|
-
.select { |klass| klass.file == @path }
|
32
|
+
registry.all(:class).select { |klass| @paths.include? klass.file }
|
24
33
|
end
|
25
34
|
|
26
35
|
def plugins_from_classes(classes)
|
27
36
|
classes.select { |klass| klass.inheritance_tree.map(&:name).include? :Plugin }
|
28
37
|
end
|
29
38
|
|
39
|
+
def to_json
|
40
|
+
plugins = plugins_from_classes(classes_in_file)
|
41
|
+
to_dict(plugins).to_json
|
42
|
+
end
|
43
|
+
|
30
44
|
def to_dict(classes)
|
31
45
|
d_meth = lambda do |meth|
|
32
46
|
return nil if meth.nil?
|
@@ -50,20 +64,23 @@ module Danger
|
|
50
64
|
end
|
51
65
|
|
52
66
|
classes.map do |klass|
|
67
|
+
# Adds the class being parsed into the ruby runtime
|
68
|
+
require klass.file
|
69
|
+
real_klass = Danger.const_get klass.name
|
70
|
+
attribute_meths = klass.attributes[:instance].values.map(&:values).flatten
|
53
71
|
{
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
72
|
+
name: klass.name.to_s,
|
73
|
+
body_md: klass.docstring,
|
74
|
+
instance_name: real_klass.instance_name,
|
75
|
+
example_code: klass.tags.select { |t| t.tag_name == "example" }.map { |tag| {:title => tag.name, :text => tag.text} }.compact,
|
76
|
+
attributes: klass.attributes[:instance].map do |pair|
|
77
|
+
{ pair.first => d_attr.call(pair.last) }
|
78
|
+
end,
|
79
|
+
methods: (klass.meths - klass.inherited_meths - attribute_meths ).select { |m| m.visibility == :public }.map { |m| d_meth.call(m) },
|
80
|
+
tags: klass.tags.select { |t| t.tag_name == "tags" }.map(&:name).compact,
|
81
|
+
see: klass.tags.select { |t| t.tag_name == "see" }.map(&:name).map(&:split).flatten.compact,
|
82
|
+
file: klass.file.gsub(File.expand_path("."), "")
|
60
83
|
}
|
61
|
-
end,
|
62
|
-
methods: (klass.meths - klass.inherited_meths).select { |m| m.visibility == :public }.map { |m| d_meth.call(m) },
|
63
|
-
tags: klass.tags.select { |t| t.tag_name == "tags" }.map(&:name).compact,
|
64
|
-
see: klass.tags.select { |t| t.tag_name == "see" }.map(&:name).map(&:split).flatten.compact,
|
65
|
-
file: klass.file
|
66
|
-
}
|
67
84
|
end
|
68
85
|
end
|
69
86
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<% json.each do |plugin| %>
|
2
|
+
|
3
|
+
### <%= plugin["instance_name"] %>
|
4
|
+
|
5
|
+
<%= plugin["body_md"] %>
|
6
|
+
<%- plugin["example_code"].each do |example| %>
|
7
|
+
<blockquote><%= example["title"] %>
|
8
|
+
<pre><%= example["text"] %></pre>
|
9
|
+
</blockquote>
|
10
|
+
<%- end %>
|
11
|
+
|
12
|
+
<%- unless plugin["attributes"].empty? %>
|
13
|
+
#### Attributes
|
14
|
+
<%- plugin["attributes"].each do |attribute| %><tr>
|
15
|
+
`<%= attribute.keys.first %>` - <%= attribute.values.first["write"]["body_md"] %>
|
16
|
+
<%- end %>
|
17
|
+
<%- end %>
|
18
|
+
|
19
|
+
#### Methods
|
20
|
+
<%- plugin["methods"].each do |method| %>
|
21
|
+
`<%= method["name"] %>` - <%= method["body_md"] %>
|
22
|
+
<%- end %>
|
23
|
+
|
24
|
+
<% end %>
|
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: 0.8.
|
4
|
+
version: 0.8.4
|
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-
|
12
|
+
date: 2016-07-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: claide
|
@@ -263,6 +263,20 @@ dependencies:
|
|
263
263
|
- - "~>"
|
264
264
|
- !ruby/object:Gem::Version
|
265
265
|
version: '4.7'
|
266
|
+
- !ruby/object:Gem::Dependency
|
267
|
+
name: guard-rubocop
|
268
|
+
requirement: !ruby/object:Gem::Requirement
|
269
|
+
requirements:
|
270
|
+
- - "~>"
|
271
|
+
- !ruby/object:Gem::Version
|
272
|
+
version: '1.2'
|
273
|
+
type: :development
|
274
|
+
prerelease: false
|
275
|
+
version_requirements: !ruby/object:Gem::Requirement
|
276
|
+
requirements:
|
277
|
+
- - "~>"
|
278
|
+
- !ruby/object:Gem::Version
|
279
|
+
version: '1.2'
|
266
280
|
description: Create a Dangerfile to introspect your pull request in CI, makes it easy
|
267
281
|
to enforce social conventions like changelogs and tests.
|
268
282
|
email:
|
@@ -293,7 +307,10 @@ files:
|
|
293
307
|
- lib/danger/commands/init.rb
|
294
308
|
- lib/danger/commands/init_helpers/interviewer.rb
|
295
309
|
- lib/danger/commands/local.rb
|
296
|
-
- lib/danger/commands/
|
310
|
+
- lib/danger/commands/plugins/plugin_abstract.rb
|
311
|
+
- lib/danger/commands/plugins/plugin_lint.rb
|
312
|
+
- lib/danger/commands/plugins/plugin_new.rb
|
313
|
+
- lib/danger/commands/plugins/plugin_readme.rb
|
297
314
|
- lib/danger/commands/runner.rb
|
298
315
|
- lib/danger/comment_generators/github.md.erb
|
299
316
|
- lib/danger/core_ext/file_list.rb
|
@@ -308,7 +325,9 @@ files:
|
|
308
325
|
- lib/danger/danger_core/standard_error.rb
|
309
326
|
- lib/danger/danger_core/violation.rb
|
310
327
|
- lib/danger/plugin_support/plugin.rb
|
328
|
+
- lib/danger/plugin_support/plugin_file_resolver.rb
|
311
329
|
- lib/danger/plugin_support/plugin_parser.rb
|
330
|
+
- lib/danger/plugin_support/templates/readme_table.html.erb
|
312
331
|
- lib/danger/request_source/github.rb
|
313
332
|
- lib/danger/request_source/request_source.rb
|
314
333
|
- lib/danger/scm_source/git_repo.rb
|