danger 0.8.3 ā 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|