danger 0.1.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 +7 -0
- data/.gitignore +44 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/README.md +72 -0
- data/Rakefile +6 -0
- data/bin/console +11 -0
- data/bin/setup +7 -0
- data/danger.gemspec +29 -0
- data/example/Dangerfile +2 -0
- data/exe/danger +7 -0
- data/lib/danger.rb +43 -0
- data/lib/danger/Dangerfile.rb +72 -0
- data/lib/danger/ci_source/circle.rb +21 -0
- data/lib/danger/ci_source/travis.rb +19 -0
- data/lib/danger/dangerfile_dsl.rb +62 -0
- data/lib/danger/environment_manager.rb +24 -0
- data/lib/danger/request_sources/github.rb +41 -0
- data/lib/danger/scm_source/git.rb +39 -0
- data/lib/danger/standard_error.rb +107 -0
- data/lib/danger/version.rb +3 -0
- metadata +168 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e9d3bed0d3e1f30e4a29d4eef41445ccd9f5b00d
|
4
|
+
data.tar.gz: eaf83e5b95373942ac5f56ecaa1cd7bfdb25cd5a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 340a33da5826421c3e7ddcfe7b8d7f8f23ac12260da1d81933e672df55987a1b341d23f9fcfe373c1177e541a8b45e194c74df7ffeeae7fc382dd6ee8baf12ea
|
7
|
+
data.tar.gz: 8e5f6adafea5d67c8b1799123ff02cfb0752dbfc4d1113efec734c2c79dace8bab00f8c68848e2ab441f44b8a7b46125bbac15277b7acf1a8e851532c506ce8b
|
data/.gitignore
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
/.bundle/
|
2
|
+
/.yardoc
|
3
|
+
/Gemfile.lock
|
4
|
+
/_yardoc/
|
5
|
+
/coverage/
|
6
|
+
/doc/
|
7
|
+
/pkg/
|
8
|
+
/spec/reports/
|
9
|
+
/tmp/
|
10
|
+
*.gem
|
11
|
+
*.rbc
|
12
|
+
/.config
|
13
|
+
/coverage/
|
14
|
+
/InstalledFiles
|
15
|
+
/pkg/
|
16
|
+
/spec/reports/
|
17
|
+
/test/tmp/
|
18
|
+
/test/version_tmp/
|
19
|
+
/tmp/
|
20
|
+
|
21
|
+
## Specific to RubyMotion:
|
22
|
+
.dat*
|
23
|
+
.repl_history
|
24
|
+
build/
|
25
|
+
|
26
|
+
## Documentation cache and generated files:
|
27
|
+
/.yardoc/
|
28
|
+
/_yardoc/
|
29
|
+
/doc/
|
30
|
+
/rdoc/
|
31
|
+
|
32
|
+
## Environment normalisation:
|
33
|
+
/.bundle/
|
34
|
+
/vendor/bundle
|
35
|
+
/lib/bundler/man/
|
36
|
+
|
37
|
+
# for a library or gem, you might want to ignore these files since the code is
|
38
|
+
# intended to run in multiple environments; otherwise, check them in:
|
39
|
+
# Gemfile.lock
|
40
|
+
# .ruby-version
|
41
|
+
# .ruby-gemset
|
42
|
+
|
43
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
44
|
+
.rvmrc
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Orta
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# Danger :no_entry_sign:
|
2
|
+
|
3
|
+
Formalize your Pull Request etiquette.
|
4
|
+
|
5
|
+
*Note:* Not ready for public usage yet. Still needs work to ensure Travis/CircleCI hook up correctly.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's [Gemfile](https://guides.cocoapods.org/using/a-gemfile.html):
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'danger'
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
In CI run `bundle exec danger`. This will look at your `Dangerfile` and provide some feedback based on that.
|
18
|
+
|
19
|
+
## DSL
|
20
|
+
|
21
|
+
Danger :no_entry_sign: | |
|
22
|
+
-------------: | ------------- | ----
|
23
|
+
:sparkles: | `lines_of_code` | The total amount of lines of code in the diff
|
24
|
+
:monorail: | `files_modified` | The list of files modified
|
25
|
+
:ship: | `files_added` | The list of files added
|
26
|
+
:pencil2: | `files_removed` | The list of files removed
|
27
|
+
:wrench: | `pr_title` | The title of the PR
|
28
|
+
:thought_balloon: | `pr_body` | The body of the PR
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
You can access more detailed information by looking through:
|
33
|
+
|
34
|
+
Danger :no_entry_sign: | |
|
35
|
+
-------------: | ------------- | ----
|
36
|
+
| :sparkles: | `env.travis` | Details on the travis integration
|
37
|
+
| :tophat: |`env.circle` | Details on the circle integration
|
38
|
+
| :octocat: | `env.github.pr_json` | The full JSON for the pull request
|
39
|
+
| :ghost: | `env.git.diff` | The full [GitDiff](https://github.com/schacon/ruby-git/blob/master/lib/git/diff.rb) file for the diff.
|
40
|
+
|
41
|
+
You can then create a `Dangerfile` like the following:
|
42
|
+
|
43
|
+
``` ruby
|
44
|
+
# Easy checks
|
45
|
+
warn("PR is classed as Work in Progress") if pr_title.include? "[WIP]"
|
46
|
+
|
47
|
+
if lines_of_code > 50 && files_modified.include? "CHANGELOG.yml" == false
|
48
|
+
fail("No CHANGELOG changes made")
|
49
|
+
end
|
50
|
+
|
51
|
+
# Stop skipping some manual testing
|
52
|
+
if lines_of_code > 50 && pr_title.include? "📱" == false
|
53
|
+
fail("Needs testing on a Phone if change is non-trivial")
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
## Constraints
|
58
|
+
|
59
|
+
* **GitHub** - Built with same-repo PRs in mind
|
60
|
+
* **Git** - Built with master as the merge branch
|
61
|
+
|
62
|
+
PRs welcome on these
|
63
|
+
|
64
|
+
## Development
|
65
|
+
|
66
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
67
|
+
|
68
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
69
|
+
|
70
|
+
## Contributing
|
71
|
+
|
72
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/orta/danger.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "danger"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
require "pry"
|
11
|
+
Pry.start
|
data/bin/setup
ADDED
data/danger.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'danger/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "danger"
|
8
|
+
spec.version = Danger::VERSION
|
9
|
+
spec.authors = ["Orta Therox", "Felix Krause"]
|
10
|
+
spec.email = ["orta.therox@gmail.com", "fastlane@krausefx.com"]
|
11
|
+
|
12
|
+
spec.summary = 'Ensure your pull request is up to standard with a nice DSL.'
|
13
|
+
spec.description = 'Create a Dangerfile to introspect your pull request in CI, makes it easy to enforce social conventions like changelogs and tests.'
|
14
|
+
spec.homepage = "http://github.com/orta/danger"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'claide', "~> 0.8"
|
22
|
+
spec.add_runtime_dependency 'git', "~> 1.2.9"
|
23
|
+
spec.add_runtime_dependency 'colored'
|
24
|
+
spec.add_runtime_dependency 'nap'
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "rspec"
|
29
|
+
end
|
data/example/Dangerfile
ADDED
data/exe/danger
ADDED
data/lib/danger.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require "danger/version"
|
2
|
+
require "danger/dangerfile"
|
3
|
+
require "danger/environment_manager"
|
4
|
+
|
5
|
+
require 'claide'
|
6
|
+
require 'colored'
|
7
|
+
|
8
|
+
module Danger
|
9
|
+
class DangerRunner < CLAide::Command
|
10
|
+
|
11
|
+
self.description = 'Run the Dangerfile.'
|
12
|
+
self.command = 'danger'
|
13
|
+
|
14
|
+
def initialize(argv)
|
15
|
+
@dangerfile_path = "Dangerfile" if File.exist? "Dangerfile"
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate!
|
20
|
+
super
|
21
|
+
unless @dangerfile_path
|
22
|
+
help! "Could not find a Dangerfile."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def run
|
27
|
+
dm = Dangerfile.new
|
28
|
+
dm.env = EnvironmentManager.new(ENV)
|
29
|
+
dm.env.fill_environment_vars
|
30
|
+
dm.update_from_env
|
31
|
+
dm.env.git.diff_for_folder(".")
|
32
|
+
dm.parse Pathname.new(@dangerfile_path)
|
33
|
+
|
34
|
+
if dm.failures
|
35
|
+
puts "Uh Oh failed"
|
36
|
+
exit(1)
|
37
|
+
else
|
38
|
+
puts "The Danger has passed. Phew."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# So much was ripped direct from CocoaPods-Core - thanks!
|
2
|
+
|
3
|
+
require 'danger/dangerfile_dsl'
|
4
|
+
require 'danger/standard_error'
|
5
|
+
|
6
|
+
module Danger
|
7
|
+
class Dangerfile
|
8
|
+
|
9
|
+
include Danger::Dangerfile::DSL
|
10
|
+
|
11
|
+
# The DSL includes a bunch of read only attributes + docs
|
12
|
+
# we make them readwrite in here
|
13
|
+
attr_accessor :files_modified, :files_removed, :files_added, :pr_title, :pr_body
|
14
|
+
attr_accessor :env, :warnings, :failures
|
15
|
+
|
16
|
+
# @return [Pathname] the path where the Dangerfile was loaded from. It is nil
|
17
|
+
# if the podfile was generated programmatically.
|
18
|
+
#
|
19
|
+
attr_accessor :defined_in_file
|
20
|
+
|
21
|
+
# @return [String] a string useful to represent the Dangerfile in a message
|
22
|
+
# presented to the user.
|
23
|
+
#
|
24
|
+
def to_s
|
25
|
+
'Dangerfile'
|
26
|
+
end
|
27
|
+
|
28
|
+
# Parses the file at a path, optionally takes the content of the file for DI
|
29
|
+
#
|
30
|
+
def parse(path, contents = nil)
|
31
|
+
warnings = [], failures =[]
|
32
|
+
|
33
|
+
contents ||= File.open(path, 'r:utf-8') { |f| f.read }
|
34
|
+
|
35
|
+
# Work around for Rubinius incomplete encoding in 1.9 mode
|
36
|
+
if contents.respond_to?(:encoding) && contents.encoding.name != 'UTF-8'
|
37
|
+
contents.encode!('UTF-8')
|
38
|
+
end
|
39
|
+
|
40
|
+
if contents.tr!('“”‘’‛', %(""'''))
|
41
|
+
# Changes have been made
|
42
|
+
puts "Your #{path.basename} has had smart quotes sanitised. " \
|
43
|
+
'To avoid issues in the future, you should not use ' \
|
44
|
+
'TextEdit for editing it. If you are not using TextEdit, ' \
|
45
|
+
'you should turn off smart quotes in your editor of choice.'.red
|
46
|
+
end
|
47
|
+
|
48
|
+
self.defined_in_file = path
|
49
|
+
instance_eval do
|
50
|
+
# rubocop:disable Lint/RescueException
|
51
|
+
begin
|
52
|
+
# rubocop:disable Eval
|
53
|
+
eval(contents, nil, path.to_s)
|
54
|
+
# rubocop:enable Eval
|
55
|
+
rescue Exception => e
|
56
|
+
message = "Invalid `#{path.basename}` file: #{e.message}"
|
57
|
+
raise DSLError.new(message, path, e.backtrace, contents)
|
58
|
+
end
|
59
|
+
# rubocop:enable Lint/RescueException
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def update_from_env
|
64
|
+
self.files_modified = env.git.modified_files
|
65
|
+
self.files_removed = env.git.removed_files
|
66
|
+
self.files_added = env.git.added_files
|
67
|
+
self.pr_title = env.github.pr_title
|
68
|
+
self.pr_body = env.github.pr_body
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# https://circleci.com/docs/environment-variables
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module Danger
|
5
|
+
class CircleCI
|
6
|
+
|
7
|
+
attr_accessor :repo_slug, :pull_request_id
|
8
|
+
|
9
|
+
def self.validates?(env)
|
10
|
+
return env["CIRCLE_BUILD_NUM"] != nil && ["CI_PULL_REQUEST"] != nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(env)
|
14
|
+
paths = URI::parse(env["CI_PULL_REQUEST"]).path.split("/")
|
15
|
+
# the first one is an extra slash, ignore it
|
16
|
+
self.repo_slug = paths[1] + "/" + paths[2]
|
17
|
+
self.pull_request_id = paths[4]
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# http://docs.travis-ci.com/user/osx-ci-environment/
|
2
|
+
# http://docs.travis-ci.com/user/environment-variables/
|
3
|
+
|
4
|
+
module Danger
|
5
|
+
class Travis
|
6
|
+
|
7
|
+
attr_accessor :repo_slug, :pull_request_id
|
8
|
+
|
9
|
+
def self.validates?(env)
|
10
|
+
return env["HAS_JOSH_K_SEAL_OF_APPROVAL"] != nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(env)
|
14
|
+
self.repo_slug = env["TRAVIS_REPO_SLUG"]
|
15
|
+
self.pull_request_id = env["TRAVIS_PULL_REQUEST"]
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Danger
|
2
|
+
class Dangerfile
|
3
|
+
module DSL
|
4
|
+
|
5
|
+
public
|
6
|
+
|
7
|
+
# @!group Enviroment
|
8
|
+
# @return [EnvironmentManager] Provides access to the raw Travis/Circle/GitHub
|
9
|
+
# objects, which you can use to pull out extra bits of information. _Warning_
|
10
|
+
# the api of these objects is **not** considered a part of the Dangerfile public
|
11
|
+
# API, and is viable to change occasionally on the whims of developers.
|
12
|
+
|
13
|
+
attr_reader :env
|
14
|
+
|
15
|
+
# @!group Code
|
16
|
+
# @return [Number] The total amount of lines of code in the diff
|
17
|
+
#
|
18
|
+
attr_reader :lines_of_code
|
19
|
+
|
20
|
+
# @return [Array of Strings] The list of files modified
|
21
|
+
#
|
22
|
+
attr_reader :files_modified
|
23
|
+
|
24
|
+
# @return [Array of Strings] The list of files removed
|
25
|
+
#
|
26
|
+
attr_reader :files_removed
|
27
|
+
|
28
|
+
# @return [Array of Strings] The list of files added
|
29
|
+
#
|
30
|
+
attr_reader :files_added
|
31
|
+
|
32
|
+
# @!group Pull Request Meta
|
33
|
+
# @return [String] The title of the PR
|
34
|
+
#
|
35
|
+
attr_reader :pr_title
|
36
|
+
|
37
|
+
# @return [String] The body of the PR
|
38
|
+
#
|
39
|
+
attr_reader :pr_body
|
40
|
+
|
41
|
+
|
42
|
+
# Declares a CI blocking error
|
43
|
+
#
|
44
|
+
# @param [String] message
|
45
|
+
# The message to present to the user
|
46
|
+
def fail(message)
|
47
|
+
self.failures << message
|
48
|
+
puts "fail #{fail}"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Specifies a problem, but not critical
|
52
|
+
#
|
53
|
+
# @param [String] message
|
54
|
+
# The message to present to the user
|
55
|
+
def warn(message)
|
56
|
+
self.warnings << "message"
|
57
|
+
puts "warn #{fail}"
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "danger/ci_source/travis"
|
2
|
+
require "danger/ci_source/circle"
|
3
|
+
require "danger/request_sources/github"
|
4
|
+
|
5
|
+
module Danger
|
6
|
+
class EnvironmentManager
|
7
|
+
|
8
|
+
attr_accessor :travis, :circle, :github, :git
|
9
|
+
|
10
|
+
def initialize(env)
|
11
|
+
self.travis = Travis.new(env) if Travis.validates?(env)
|
12
|
+
self.circle = CircleCI.new(env) if CircleCI.validates?(env)
|
13
|
+
raise "Could not find a CI source" unless self.travis || self.circle
|
14
|
+
|
15
|
+
self.github = GitHub.new( travis || circle)
|
16
|
+
end
|
17
|
+
|
18
|
+
def fill_environment_vars
|
19
|
+
github.get_details
|
20
|
+
|
21
|
+
self.git = GitRepo.new
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rest'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Danger
|
5
|
+
class GitHub
|
6
|
+
|
7
|
+
attr_accessor :ci_source, :pr_json
|
8
|
+
|
9
|
+
def initialize(ci_source)
|
10
|
+
self.ci_source = ci_source
|
11
|
+
end
|
12
|
+
|
13
|
+
def api_url
|
14
|
+
"https://api.github.com/repos/#{ci_source.repo_slug}/pulls/#{ci_source.pull_request_id}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_details
|
18
|
+
response = REST.get api_url
|
19
|
+
if response.ok?
|
20
|
+
self.pr_json = JSON.parse(response.body)
|
21
|
+
else
|
22
|
+
puts "Something went wrong getting GitHub details for #{api_url} - (#{response.status_code})"
|
23
|
+
puts response.body
|
24
|
+
raise "Could not get the pull request details from GitHub."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def latest_pr_commit_ref
|
29
|
+
self.pr_json['base']['sha']
|
30
|
+
end
|
31
|
+
|
32
|
+
def pr_title
|
33
|
+
self.pr_json['title']
|
34
|
+
end
|
35
|
+
|
36
|
+
def pr_body
|
37
|
+
self.pr_json['body']
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# https://github.com/schacon/ruby-git
|
2
|
+
|
3
|
+
require 'git'
|
4
|
+
|
5
|
+
module Danger
|
6
|
+
class GitRepo
|
7
|
+
attr_accessor :diff
|
8
|
+
|
9
|
+
def diff_for_folder(folder, from = "HEAD", to = 'master')
|
10
|
+
g = Git.open(folder)
|
11
|
+
self.diff = g.diff(to, from)
|
12
|
+
end
|
13
|
+
|
14
|
+
def modified_files
|
15
|
+
@diff.to_a.map { |d| d.path }
|
16
|
+
end
|
17
|
+
|
18
|
+
def removed_files
|
19
|
+
@diff.to_a.select { |d| d.type == "deleted" } .map { |d| d.path }
|
20
|
+
end
|
21
|
+
|
22
|
+
def added_files
|
23
|
+
@diff.to_a.select { |d| d.type == "new" } .map { |d| d.path }
|
24
|
+
end
|
25
|
+
|
26
|
+
def lines_of_code
|
27
|
+
@diff.lines
|
28
|
+
end
|
29
|
+
|
30
|
+
def deletions
|
31
|
+
@diff.deletions
|
32
|
+
end
|
33
|
+
|
34
|
+
def insertions
|
35
|
+
@diff.insertions
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'claide'
|
2
|
+
require 'claide/informative_error'
|
3
|
+
|
4
|
+
module Danger
|
5
|
+
# Ripped direct from CocoaPods-Core - thanks!
|
6
|
+
|
7
|
+
#-------------------------------------------------------------------------#
|
8
|
+
|
9
|
+
# Wraps an exception raised by a DSL file in order to show to the user the
|
10
|
+
# contents of the line that raised the exception.
|
11
|
+
#
|
12
|
+
class DSLError < StandardError
|
13
|
+
# @return [String] the description that should be presented to the user.
|
14
|
+
#
|
15
|
+
attr_reader :description
|
16
|
+
|
17
|
+
# @return [String] the path of the dsl file that raised the exception.
|
18
|
+
#
|
19
|
+
attr_reader :dsl_path
|
20
|
+
|
21
|
+
# @return [Exception] the backtrace of the exception raised by the
|
22
|
+
# evaluation of the dsl file.
|
23
|
+
#
|
24
|
+
attr_reader :backtrace
|
25
|
+
|
26
|
+
# @param [Exception] backtrace @see backtrace
|
27
|
+
# @param [String] dsl_path @see dsl_path
|
28
|
+
#
|
29
|
+
def initialize(description, dsl_path, backtrace, contents = nil)
|
30
|
+
@description = description
|
31
|
+
@dsl_path = dsl_path
|
32
|
+
@backtrace = backtrace
|
33
|
+
@contents = contents
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [String] the contents of the DSL that cause the exception to
|
37
|
+
# be raised.
|
38
|
+
#
|
39
|
+
def contents
|
40
|
+
@contents ||= begin
|
41
|
+
dsl_path && File.exist?(dsl_path) && File.read(dsl_path)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# The message of the exception reports the content of podspec for the
|
46
|
+
# line that generated the original exception.
|
47
|
+
#
|
48
|
+
# @example Output
|
49
|
+
#
|
50
|
+
# Invalid podspec at `RestKit.podspec` - undefined method
|
51
|
+
# `exclude_header_search_paths=' for #<Pod::Specification for
|
52
|
+
# `RestKit/Network (0.9.3)`>
|
53
|
+
#
|
54
|
+
# from spec-repos/master/RestKit/0.9.3/RestKit.podspec:36
|
55
|
+
# -------------------------------------------
|
56
|
+
# # because it would break: #import <CoreData/CoreData.h>
|
57
|
+
# > ns.exclude_header_search_paths = 'Code/RestKit.h'
|
58
|
+
# end
|
59
|
+
# -------------------------------------------
|
60
|
+
#
|
61
|
+
# @return [String] the message of the exception.
|
62
|
+
#
|
63
|
+
def message
|
64
|
+
@message ||= begin
|
65
|
+
trace_line, description = parse_line_number_from_description
|
66
|
+
|
67
|
+
m = "\n[!] "
|
68
|
+
m << description
|
69
|
+
m << ". Updating the Danger gem might fix the issue.\n"
|
70
|
+
m = m.red if m.respond_to?(:red)
|
71
|
+
|
72
|
+
return m unless backtrace && dsl_path && contents
|
73
|
+
|
74
|
+
trace_line = backtrace.find { |l| l.include?(dsl_path.to_s) } || trace_line
|
75
|
+
return m unless trace_line
|
76
|
+
line_numer = trace_line.split(':')[1].to_i - 1
|
77
|
+
return m unless line_numer
|
78
|
+
|
79
|
+
lines = contents.lines
|
80
|
+
indent = ' # '
|
81
|
+
indicator = indent.gsub('#', '>')
|
82
|
+
first_line = (line_numer.zero?)
|
83
|
+
last_line = (line_numer == (lines.count - 1))
|
84
|
+
|
85
|
+
m << "\n"
|
86
|
+
m << "#{indent}from #{trace_line.gsub(/:in.*$/, '')}\n"
|
87
|
+
m << "#{indent}-------------------------------------------\n"
|
88
|
+
m << "#{indent}#{ lines[line_numer - 1] }" unless first_line
|
89
|
+
m << "#{indicator}#{ lines[line_numer] }"
|
90
|
+
m << "#{indent}#{ lines[line_numer + 1] }" unless last_line
|
91
|
+
m << "\n" unless m.end_with?("\n")
|
92
|
+
m << "#{indent}-------------------------------------------\n"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def parse_line_number_from_description
|
99
|
+
description = self.description
|
100
|
+
if dsl_path && description =~ /((#{Regexp.quote File.expand_path(dsl_path)}|#{Regexp.quote dsl_path.to_s}):\d+)/
|
101
|
+
trace_line = Regexp.last_match[1]
|
102
|
+
description = description.sub(/#{Regexp.quote trace_line}:\s*/, '')
|
103
|
+
end
|
104
|
+
[trace_line, description]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
metadata
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: danger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Orta Therox
|
8
|
+
- Felix Krause
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-09-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: claide
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0.8'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0.8'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: git
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 1.2.9
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 1.2.9
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: colored
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: nap
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: bundler
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '1.10'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '1.10'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rake
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '10.0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '10.0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: rspec
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
description: Create a Dangerfile to introspect your pull request in CI, makes it easy
|
113
|
+
to enforce social conventions like changelogs and tests.
|
114
|
+
email:
|
115
|
+
- orta.therox@gmail.com
|
116
|
+
- fastlane@krausefx.com
|
117
|
+
executables:
|
118
|
+
- danger
|
119
|
+
extensions: []
|
120
|
+
extra_rdoc_files: []
|
121
|
+
files:
|
122
|
+
- ".gitignore"
|
123
|
+
- ".rspec"
|
124
|
+
- ".travis.yml"
|
125
|
+
- CHANGELOG.md
|
126
|
+
- Gemfile
|
127
|
+
- LICENSE
|
128
|
+
- README.md
|
129
|
+
- Rakefile
|
130
|
+
- bin/console
|
131
|
+
- bin/setup
|
132
|
+
- danger.gemspec
|
133
|
+
- example/Dangerfile
|
134
|
+
- exe/danger
|
135
|
+
- lib/danger.rb
|
136
|
+
- lib/danger/Dangerfile.rb
|
137
|
+
- lib/danger/ci_source/circle.rb
|
138
|
+
- lib/danger/ci_source/travis.rb
|
139
|
+
- lib/danger/dangerfile_dsl.rb
|
140
|
+
- lib/danger/environment_manager.rb
|
141
|
+
- lib/danger/request_sources/github.rb
|
142
|
+
- lib/danger/scm_source/git.rb
|
143
|
+
- lib/danger/standard_error.rb
|
144
|
+
- lib/danger/version.rb
|
145
|
+
homepage: http://github.com/orta/danger
|
146
|
+
licenses: []
|
147
|
+
metadata: {}
|
148
|
+
post_install_message:
|
149
|
+
rdoc_options: []
|
150
|
+
require_paths:
|
151
|
+
- lib
|
152
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
requirements: []
|
163
|
+
rubyforge_project:
|
164
|
+
rubygems_version: 2.4.8
|
165
|
+
signing_key:
|
166
|
+
specification_version: 4
|
167
|
+
summary: Ensure your pull request is up to standard with a nice DSL.
|
168
|
+
test_files: []
|