danger 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e9d3bed0d3e1f30e4a29d4eef41445ccd9f5b00d
4
- data.tar.gz: eaf83e5b95373942ac5f56ecaa1cd7bfdb25cd5a
3
+ metadata.gz: c2df0507da13cc40eb7f1d93256d1c5da4363ee0
4
+ data.tar.gz: 89be5c58b12e017286d8d0dedafcd5adc80f05bf
5
5
  SHA512:
6
- metadata.gz: 340a33da5826421c3e7ddcfe7b8d7f8f23ac12260da1d81933e672df55987a1b341d23f9fcfe373c1177e541a8b45e194c74df7ffeeae7fc382dd6ee8baf12ea
7
- data.tar.gz: 8e5f6adafea5d67c8b1799123ff02cfb0752dbfc4d1113efec734c2c79dace8bab00f8c68848e2ab441f44b8a7b46125bbac15277b7acf1a8e851532c506ce8b
6
+ metadata.gz: 44a07b2b9aca7eac7d487576fc1efb3332e3e978120c49046428ae623e8b76c5ed965ec44b5482bb3b5024206301490933118537275723ba1acdc8d14fdc6690
7
+ data.tar.gz: 10c85b4daeb7feff0c22d8c3b39746aaa14963bba02788b9a83d310334670c857eb4a5d651801e74803b68c4d9c7a92b373fcaa8747d5844a4fcd7653ef259aa
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015 Orta
3
+ Copyright (c) 2015 Orta, Felix Krause
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,8 +1,23 @@
1
1
  # Danger :no_entry_sign:
2
2
 
3
+ [![License](http://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/orta/danger/blob/master/LICENSE)
4
+ [![Gem](https://img.shields.io/gem/v/danger.svg?style=flat)](http://rubygems.org/gems/danger)
5
+
3
6
  Formalize your Pull Request etiquette.
4
7
 
5
- *Note:* Not ready for public usage yet. Still needs work to ensure Travis/CircleCI hook up correctly.
8
+ *Note:* Not ready for public usage yet. Work in progress
9
+
10
+ -------
11
+ <p align="center">
12
+ <a href="#installation">Installation</a> &bull;
13
+ <a href="#usage">Usage</a> &bull;
14
+ <a href="#dsl">DSL</a> &bull;
15
+ <a href="#constraints">Constraints</a> &bull;
16
+ <a href="#advanced">Advanced</a> &bull;
17
+ <a href="#contributing">Contributing</a>
18
+ </p>
19
+
20
+ -------
6
21
 
7
22
  ## Installation
8
23
 
@@ -12,31 +27,27 @@ Add this line to your application's [Gemfile](https://guides.cocoapods.org/using
12
27
  gem 'danger'
13
28
  ```
14
29
 
30
+ and then run the following to set up `danger` for your repository
31
+
32
+ ```
33
+ danger init
34
+ ```
35
+
15
36
  ## Usage
16
37
 
17
38
  In CI run `bundle exec danger`. This will look at your `Dangerfile` and provide some feedback based on that.
18
39
 
19
40
  ## DSL
20
41
 
21
- Danger :no_entry_sign: | &nbsp; | &nbsp;
42
+ &nbsp; | &nbsp; | Danger :no_entry_sign:
22
43
  -------------: | ------------- | ----
23
44
  :sparkles: | `lines_of_code` | The total amount of lines of code in the diff
24
- :monorail: | `files_modified` | The list of files modified
45
+ :pencil2: | `files_modified` | The list of files modified
25
46
  :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: | &nbsp; | &nbsp;
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.
47
+ :recycle: | `files_removed` | The list of files removed
48
+ :abc: | `pr_title` | The title of the PR
49
+ :book: | `pr_body` | The body of the PR
50
+ :busts_in_silhouette: | `pr_author` | The author who submitted the PR
40
51
 
41
52
  You can then create a `Dangerfile` like the following:
42
53
 
@@ -52,6 +63,9 @@ end
52
63
  if lines_of_code > 50 && pr_title.include? "📱" == false
53
64
  fail("Needs testing on a Phone if change is non-trivial")
54
65
  end
66
+
67
+ message("This pull request adds #{lines_of_code} new lines")
68
+ warn("Author @#{pr_author} is not a contributor") unless ["KrauseFx", "orta"].include?(pr_author)
55
69
  ```
56
70
 
57
71
  ## Constraints
@@ -59,14 +73,20 @@ end
59
73
  * **GitHub** - Built with same-repo PRs in mind
60
74
  * **Git** - Built with master as the merge branch
61
75
 
62
- PRs welcome on these
76
+ ## Advanced
77
+
78
+ You can access more detailed information by accessing the following variables
63
79
 
64
- ## Development
80
+ &nbsp; | Danger :no_entry_sign:
81
+ ------------- | ----
82
+ `env.request_source.pr_json` | The full JSON for the pull request
83
+ `env.scm.diff` | The full [GitDiff](https://github.com/schacon/ruby-git/blob/master/lib/git/diff.rb) file for the diff.
84
+ `env.ci_source` | To get information like the repo slug or pull request ID
65
85
 
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.
86
+ ## Special Thanks
67
87
 
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).
88
+ Thanks [@orta](https://twitter.com/orta) for starting this project
69
89
 
70
- ## Contributing
90
+ ## License
71
91
 
72
- Bug reports and pull requests are welcome on GitHub at https://github.com/orta/danger.
92
+ > 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.
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
3
+
4
+ require 'danger'
5
+ Danger::Runner.run ARGV
@@ -0,0 +1,15 @@
1
+ puts "OK"
2
+ puts "Lines"
3
+ puts lines_of_code
4
+ puts "Added"
5
+ puts files_added
6
+ puts "modified"
7
+ puts files_modified
8
+
9
+ puts ""
10
+ puts pr_body
11
+ puts ""
12
+ puts pr_title
13
+
14
+ warn("Some random warning")
15
+ fail("Orta is not really orta")
@@ -1,43 +1,26 @@
1
1
  require "danger/version"
2
2
  require "danger/dangerfile"
3
3
  require "danger/environment_manager"
4
+ require "danger/runner"
5
+ require "danger/init"
6
+ require "danger/available_values"
4
7
 
5
- require 'claide'
6
- require 'colored'
8
+ require "claide"
9
+ require "colored"
10
+ require "pathname"
7
11
 
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)
12
+ # Import all the Sources (CI, Request and SCM)
13
+ Dir[File.expand_path('danger/*source/*.rb', File.dirname(__FILE__))].each do |file|
14
+ require file
15
+ end
33
16
 
34
- if dm.failures
35
- puts "Uh Oh failed"
36
- exit(1)
37
- else
38
- puts "The Danger has passed. Phew."
39
- end
17
+ module Danger
18
+ # @return [String] The path to the local gem directory
19
+ def self.gem_path
20
+ gem_name = "danger"
21
+ unless Gem::Specification.find_all_by_name(gem_name).any?
22
+ raise "Couldn't find gem directory for 'danger'"
40
23
  end
41
-
24
+ return Gem::Specification.find_by_name(gem_name).gem_dir
42
25
  end
43
26
  end
@@ -0,0 +1,27 @@
1
+ module Danger
2
+ # Defines all the values that should be available in someone's Dangerfile
3
+ class AvailableValues
4
+ def self.all
5
+ self.scm + self.request_source
6
+ end
7
+
8
+ def self.scm
9
+ [
10
+ :lines_of_code,
11
+ :files_modified,
12
+ :files_removed,
13
+ :files_added,
14
+ :deletions,
15
+ :insertions
16
+ ]
17
+ end
18
+
19
+ def self.request_source
20
+ [
21
+ :pr_title,
22
+ :pr_body,
23
+ :pr_author
24
+ ]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ # https://buildkite.com/docs/agent/osx
2
+ # https://buildkite.com/docs/guides/environment-variables
3
+
4
+ module Danger
5
+ module CISource
6
+ class Buildkite < CI
7
+ def self.validates?(env)
8
+ return !env["BUILDKITE"].nil?
9
+ end
10
+
11
+ def initialize(env)
12
+ repo = env["BUILDKITE_REPO"]
13
+ unless repo.nil?
14
+ repo_matches = repo.match(%r{([\/:])([^\/]+\/[^\/.]+)(?:.git)?$})
15
+ self.repo_slug = repo_matches[2] unless repo_matches.nil?
16
+ end
17
+
18
+ self.pull_request_id = env["BUILDKITE_PULL_REQUEST"]
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ module Danger
2
+ module CISource
3
+ # "abstract" CI class
4
+ class CI
5
+ attr_accessor :repo_slug, :pull_request_id
6
+
7
+ def self.validates?(_env)
8
+ false
9
+ end
10
+
11
+ def initialize(_env)
12
+ raise "Subclass and overwrite initialize"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -2,20 +2,18 @@
2
2
  require 'uri'
3
3
 
4
4
  module Danger
5
- class CircleCI
5
+ module CISource
6
+ class CircleCI < CI
7
+ def self.validates?(env)
8
+ return !env["CIRCLE_BUILD_NUM"].nil? && !env["CI_PULL_REQUEST"].nil?
9
+ end
6
10
 
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]
11
+ def initialize(env)
12
+ paths = URI.parse(env["CI_PULL_REQUEST"]).path.split("/")
13
+ # the first one is an extra slash, ignore it
14
+ self.repo_slug = paths[1] + "/" + paths[2]
15
+ self.pull_request_id = paths[4]
16
+ end
18
17
  end
19
-
20
18
  end
21
19
  end
@@ -2,18 +2,19 @@
2
2
  # http://docs.travis-ci.com/user/environment-variables/
3
3
 
4
4
  module Danger
5
- class Travis
5
+ module CISource
6
+ class Travis < CI
7
+ def self.validates?(env)
8
+ return !env["HAS_JOSH_K_SEAL_OF_APPROVAL"].nil?
9
+ end
6
10
 
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"]
11
+ def initialize(env)
12
+ self.repo_slug = env["TRAVIS_REPO_SLUG"]
13
+ # from https://docs.travis-ci.com/user/pull-requests, as otherwise it's "false"
14
+ if env["TRAVIS_PULL_REQUEST"].to_i > 0
15
+ self.pull_request_id = env["TRAVIS_PULL_REQUEST"]
16
+ end
17
+ end
16
18
  end
17
-
18
19
  end
19
20
  end
@@ -0,0 +1,32 @@
1
+ <% if @errors.count > 0 %>
2
+ &nbsp; | <%= @errors.count %> Error<%= "s" unless @errors.count == 1 %>
3
+ ------------- | ------------ <% @errors.each do |error| %>
4
+ :no_entry_sign: | <%= error %><% end %>
5
+ <% else %>
6
+ :white_check_mark: | No errors found
7
+ ------------- | ------------
8
+ <% end %>
9
+
10
+ <% if @warnings.count > 0 %>
11
+ &nbsp; | <%= @warnings.count %> Warning<%= "s" unless @warnings.count == 1 %>
12
+ ------------- | ------------ <% @warnings.each do |warning| %>
13
+ :warning: | <%= warning %><% end %>
14
+ <% else %>
15
+ :white_check_mark: | No warnings found
16
+ ------------- | ------------
17
+ <% end %>
18
+
19
+ <% if @messages.count > 0 %>
20
+ &nbsp; | <%= @messages.count %> Message<%= "s" unless @messages.count == 1 %>
21
+ ------------- | ------------ <% @messages.each do |message| %>
22
+ :book: | <%= message %><% end %>
23
+ <% end %>
24
+
25
+ <p align="right">
26
+ Generated by
27
+ <a href="https://github.com/KrauseFx/danger">danger</a>
28
+ on
29
+ <i><%= Time.now.strftime("%Y-%m-%d") %></i>
30
+ </p>
31
+
32
+ <% "" # the reason why we have the each in the same line is because we don't want a new line in the markdown file %>
@@ -5,16 +5,12 @@ require 'danger/standard_error'
5
5
 
6
6
  module Danger
7
7
  class Dangerfile
8
-
9
8
  include Danger::Dangerfile::DSL
10
9
 
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
10
+ attr_accessor :env, :warnings, :errors, :messages
15
11
 
16
12
  # @return [Pathname] the path where the Dangerfile was loaded from. It is nil
17
- # if the podfile was generated programmatically.
13
+ # if the Dangerfile was generated programmatically.
18
14
  #
19
15
  attr_accessor :defined_in_file
20
16
 
@@ -28,9 +24,7 @@ module Danger
28
24
  # Parses the file at a path, optionally takes the content of the file for DI
29
25
  #
30
26
  def parse(path, contents = nil)
31
- warnings = [], failures =[]
32
-
33
- contents ||= File.open(path, 'r:utf-8') { |f| f.read }
27
+ contents ||= File.open(path, 'r:utf-8', &:read)
34
28
 
35
29
  # Work around for Rubinius incomplete encoding in 1.9 mode
36
30
  if contents.respond_to?(:encoding) && contents.encoding.name != 'UTF-8'
@@ -39,12 +33,16 @@ module Danger
39
33
 
40
34
  if contents.tr!('“”‘’‛', %(""'''))
41
35
  # Changes have been made
42
- puts "Your #{path.basename} has had smart quotes sanitised. " \
36
+ puts "Your #{path.basename} has had smart quotes sanitised. " \
43
37
  'To avoid issues in the future, you should not use ' \
44
38
  'TextEdit for editing it. If you are not using TextEdit, ' \
45
39
  'you should turn off smart quotes in your editor of choice.'.red
46
40
  end
47
41
 
42
+ if contents.include?("puts")
43
+ puts "You used `puts` in your Dangerfile. To print out text to GitHub use `message` instead"
44
+ end
45
+
48
46
  self.defined_in_file = path
49
47
  instance_eval do
50
48
  # rubocop:disable Lint/RescueException
@@ -59,14 +57,5 @@ module Danger
59
57
  # rubocop:enable Lint/RescueException
60
58
  end
61
59
  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
60
  end
72
61
  end
@@ -1,51 +1,27 @@
1
1
  module Danger
2
2
  class Dangerfile
3
3
  module DSL
4
-
5
- public
6
-
7
4
  # @!group Enviroment
8
- # @return [EnvironmentManager] Provides access to the raw Travis/Circle/GitHub
5
+ # @return [EnvironmentManager] Provides access to the raw Travis/Circle/Buildkite/GitHub
9
6
  # objects, which you can use to pull out extra bits of information. _Warning_
10
7
  # the api of these objects is **not** considered a part of the Dangerfile public
11
8
  # API, and is viable to change occasionally on the whims of developers.
12
9
 
13
10
  attr_reader :env
14
11
 
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
-
12
+ def initialize
13
+ self.warnings = []
14
+ self.errors = []
15
+ self.messages = []
16
+ end
41
17
 
42
18
  # Declares a CI blocking error
43
19
  #
44
20
  # @param [String] message
45
21
  # The message to present to the user
46
22
  def fail(message)
47
- self.failures << message
48
- puts "fail #{fail}"
23
+ self.errors << message
24
+ puts "Raising error '#{message}'"
49
25
  end
50
26
 
51
27
  # Specifies a problem, but not critical
@@ -53,10 +29,34 @@ module Danger
53
29
  # @param [String] message
54
30
  # The message to present to the user
55
31
  def warn(message)
56
- self.warnings << "message"
57
- puts "warn #{fail}"
32
+ self.warnings << message
33
+ puts "Printing warning '#{message}'"
58
34
  end
59
35
 
36
+ # Print out a generate message on the PR
37
+ #
38
+ # @param [String] message
39
+ # The message to present to the user
40
+ def message(message)
41
+ self.messages << message
42
+ puts "Printing message '#{message}'"
43
+ end
44
+
45
+ def method_missing(method_sym, *_arguments, &_block)
46
+ unless AvailableValues.all.include?(method_sym)
47
+ raise "Unknown method '#{method_sym}', please check out the documentation for available variables".red
48
+ end
49
+
50
+ if AvailableValues.scm.include?(method_sym)
51
+ # SCM Source
52
+ return env.scm.send(method_sym)
53
+ end
54
+
55
+ if AvailableValues.request_source.include?(method_sym)
56
+ # Request Source
57
+ return env.request_source.send(method_sym)
58
+ end
59
+ end
60
60
  end
61
61
  end
62
62
  end
@@ -1,24 +1,35 @@
1
- require "danger/ci_source/travis"
2
- require "danger/ci_source/circle"
1
+ require "danger/ci_source/ci_source"
3
2
  require "danger/request_sources/github"
4
3
 
5
4
  module Danger
6
5
  class EnvironmentManager
7
-
8
- attr_accessor :travis, :circle, :github, :git
6
+ attr_accessor :ci_source, :request_source, :scm
9
7
 
10
8
  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
9
+ CISource.constants.each do |symb|
10
+ c = CISource.const_get(symb)
11
+ next unless c.kind_of?(Class)
12
+ next unless c.validates?(env)
13
+
14
+ self.ci_source = c.new(env)
15
+ if self.ci_source.repo_slug and self.ci_source.pull_request_id
16
+ break
17
+ else
18
+ puts "Not a Pull Request - skipping `danger` run"
19
+ self.ci_source = nil
20
+ return nil
21
+ end
22
+ end
14
23
 
15
- self.github = GitHub.new( travis || circle)
24
+ raise "Could not find a CI source".red unless self.ci_source
25
+
26
+ self.request_source = GitHub.new(self.ci_source) # for now
16
27
  end
17
28
 
18
29
  def fill_environment_vars
19
- github.get_details
20
-
21
- self.git = GitRepo.new
30
+ request_source.fetch_details
31
+
32
+ self.scm = GitRepo.new # For now
22
33
  end
23
34
  end
24
35
  end
@@ -0,0 +1,25 @@
1
+ module Danger
2
+ class Init < Danger::Runner
3
+ self.description = 'Creates a Dangerfile.'
4
+ self.command = 'init'
5
+
6
+ def initialize(argv)
7
+ @dangerfile_path = "Dangerfile" if File.exist? "Dangerfile"
8
+ super
9
+ end
10
+
11
+ def validate!
12
+ if @dangerfile_path
13
+ help! "Found an existing Dangerfile."
14
+ end
15
+ end
16
+
17
+ def run
18
+ dir = Danger.gem_path
19
+
20
+ content = File.read(File.join(dir, "lib", "assets", "DangerfileTemplate"))
21
+ File.write("Dangerfile", content)
22
+ puts "Successfully created 'Dangerfile'"
23
+ end
24
+ end
25
+ end
@@ -1,41 +1,97 @@
1
1
  require 'rest'
2
2
  require 'json'
3
+ require 'base64'
4
+ require 'octokit'
3
5
 
4
6
  module Danger
5
7
  class GitHub
6
-
7
8
  attr_accessor :ci_source, :pr_json
8
9
 
9
10
  def initialize(ci_source)
10
11
  self.ci_source = ci_source
11
12
  end
12
13
 
13
- def api_url
14
- "https://api.github.com/repos/#{ci_source.repo_slug}/pulls/#{ci_source.pull_request_id}"
14
+ def client
15
+ token = ENV["DANGER_GITHUB_API_TOKEN"]
16
+ raise "No API given, please provide one using `DANGER_GITHUB_API_TOKEN`" unless token
17
+
18
+ @client ||= Octokit::Client.new(
19
+ access_token: token
20
+ )
15
21
  end
16
22
 
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
23
+ def fetch_details
24
+ self.pr_json = client.pull_request(ci_source.repo_slug, ci_source.pull_request_id)
26
25
  end
27
26
 
28
27
  def latest_pr_commit_ref
29
- self.pr_json['base']['sha']
28
+ self.pr_json[:head][:sha]
30
29
  end
31
30
 
32
31
  def pr_title
33
- self.pr_json['title']
32
+ self.pr_json[:title]
34
33
  end
35
34
 
36
35
  def pr_body
37
- self.pr_json['body']
36
+ self.pr_json[:body]
37
+ end
38
+
39
+ def pr_author
40
+ self.pr_json[:user][:login]
41
+ end
42
+
43
+ # Sending data to GitHub
44
+ def update_pull_request!(warnings: nil, errors: nil, messages: nil)
45
+ # First, add a comment
46
+ body = generate_comment(warnings: warnings, errors: errors, messages: messages)
47
+ result = client.add_comment(ci_source.repo_slug, ci_source.pull_request_id, body)
48
+ delete_old_comment!(except: result[:id])
49
+
50
+ # Now, set the pull request status
51
+ submit_pull_request_status!(warnings: warnings,
52
+ errors: errors,
53
+ details_url: result['html_url'])
54
+ end
55
+
56
+ def submit_pull_request_status!(warnings: nil, errors: nil, details_url: nil)
57
+ status = (errors.count == 0 ? 'success' : 'failure')
58
+ client.create_status(ci_source.repo_slug, latest_pr_commit_ref, status, {
59
+ description: generate_github_description(warnings: warnings, errors: errors),
60
+ context: "KrauseFx/danger",
61
+ target_url: details_url
62
+ })
38
63
  end
39
64
 
65
+ # Get rid of the previously posted comment, to only have the latest one
66
+ def delete_old_comment!(except: nil)
67
+ issues = client.issue_comments(ci_source.repo_slug, ci_source.pull_request_id)
68
+ issues.each do |issue|
69
+ next unless issue[:body].gsub(/\s+/, "").include?("Generatedby<ahref=")
70
+ next if issue[:id] == except
71
+ client.delete_comment(ci_source.repo_slug, issue[:id])
72
+ end
73
+ end
74
+
75
+ def generate_github_description(warnings: nil, errors: nil)
76
+ if errors.count > 0
77
+ "danger found errors"
78
+ elsif warnings.count > 0
79
+ "⚠️ danger found warnings, merge with caution"
80
+ else
81
+ "danger was successful"
82
+ end
83
+ end
84
+
85
+ def generate_comment(warnings: nil, errors: nil, messages: nil)
86
+ require 'erb'
87
+
88
+ @warnings = warnings
89
+ @errors = errors
90
+ @messages = messages
91
+
92
+ md_template = File.join(Danger.gem_path, "lib/danger/comment_generators/github.md.erb")
93
+ comment = ERB.new(File.read(md_template)).result(binding) # http://www.rrn.dk/rubys-erb-templating-system
94
+ return comment
95
+ end
40
96
  end
41
97
  end
@@ -0,0 +1,35 @@
1
+ module Danger
2
+ class Runner < CLAide::Command
3
+ self.description = 'Run the Dangerfile.'
4
+ self.command = 'danger'
5
+
6
+ def initialize(argv)
7
+ @dangerfile_path = "Dangerfile" if File.exist? "Dangerfile"
8
+ super
9
+ end
10
+
11
+ def validate!
12
+ super
13
+ unless @dangerfile_path
14
+ help! "Could not find a Dangerfile."
15
+ end
16
+ end
17
+
18
+ def run
19
+ # The order of the following commands is *really* important
20
+ dm = Dangerfile.new
21
+ dm.env = EnvironmentManager.new(ENV)
22
+ return unless dm.env.ci_source # if it's not a PR
23
+ dm.env.fill_environment_vars
24
+ dm.env.scm.diff_for_folder(".")
25
+ dm.parse Pathname.new(@dangerfile_path)
26
+
27
+ post_results(dm)
28
+ end
29
+
30
+ def post_results(dm)
31
+ gh = dm.env.request_source
32
+ gh.update_pull_request!(warnings: dm.warnings, errors: dm.errors, messages: dm.messages)
33
+ end
34
+ end
35
+ end
@@ -11,16 +11,16 @@ module Danger
11
11
  self.diff = g.diff(to, from)
12
12
  end
13
13
 
14
- def modified_files
15
- @diff.to_a.map { |d| d.path }
14
+ def files_modified
15
+ @diff.to_a.map(&:path)
16
16
  end
17
17
 
18
- def removed_files
19
- @diff.to_a.select { |d| d.type == "deleted" } .map { |d| d.path }
18
+ def files_removed
19
+ @diff.to_a.select { |d| d.type == "deleted" }.map(&:path)
20
20
  end
21
21
 
22
- def added_files
23
- @diff.to_a.select { |d| d.type == "new" } .map { |d| d.path }
22
+ def files_added
23
+ @diff.to_a.select { |d| d.type == "new" }.map(&:path)
24
24
  end
25
25
 
26
26
  def lines_of_code
@@ -34,6 +34,5 @@ module Danger
34
34
  def insertions
35
35
  @diff.insertions
36
36
  end
37
-
38
37
  end
39
38
  end
@@ -78,16 +78,16 @@ module Danger
78
78
 
79
79
  lines = contents.lines
80
80
  indent = ' # '
81
- indicator = indent.gsub('#', '>')
81
+ indicator = indent.tr('#', '>')
82
82
  first_line = (line_numer.zero?)
83
83
  last_line = (line_numer == (lines.count - 1))
84
84
 
85
85
  m << "\n"
86
86
  m << "#{indent}from #{trace_line.gsub(/:in.*$/, '')}\n"
87
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
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
91
  m << "\n" unless m.end_with?("\n")
92
92
  m << "#{indent}-------------------------------------------\n"
93
93
  end
@@ -1,3 +1,4 @@
1
1
  module Danger
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
+ DESCRIPTION = "Ensure your pull request is up to standard with a nice DSL"
3
4
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: danger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Orta Therox
8
8
  - Felix Krause
9
9
  autorequire:
10
- bindir: exe
10
+ bindir: bin
11
11
  cert_chain: []
12
- date: 2015-09-29 00:00:00.000000000 Z
12
+ date: 2016-01-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: claide
@@ -67,6 +67,20 @@ dependencies:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: octokit
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
70
84
  - !ruby/object:Gem::Dependency
71
85
  name: bundler
72
86
  requirement: !ruby/object:Gem::Requirement
@@ -109,41 +123,81 @@ dependencies:
109
123
  - - ">="
110
124
  - !ruby/object:Gem::Version
111
125
  version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: webmock
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ - !ruby/object:Gem::Dependency
141
+ name: fastlane
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: 1.49.0
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: 1.49.0
154
+ - !ruby/object:Gem::Dependency
155
+ name: rubocop
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
112
168
  description: Create a Dangerfile to introspect your pull request in CI, makes it easy
113
169
  to enforce social conventions like changelogs and tests.
114
170
  email:
115
171
  - orta.therox@gmail.com
116
- - fastlane@krausefx.com
172
+ - danger@krausefx.com
117
173
  executables:
118
174
  - danger
119
175
  extensions: []
120
176
  extra_rdoc_files: []
121
177
  files:
122
- - ".gitignore"
123
- - ".rspec"
124
- - ".travis.yml"
125
- - CHANGELOG.md
126
- - Gemfile
127
178
  - LICENSE
128
179
  - README.md
129
- - Rakefile
130
- - bin/console
131
- - bin/setup
132
- - danger.gemspec
133
- - example/Dangerfile
134
- - exe/danger
180
+ - bin/danger
181
+ - lib/assets/DangerfileTemplate
135
182
  - lib/danger.rb
136
- - lib/danger/Dangerfile.rb
183
+ - lib/danger/available_values.rb
184
+ - lib/danger/ci_source/buildkite.rb
185
+ - lib/danger/ci_source/ci_source.rb
137
186
  - lib/danger/ci_source/circle.rb
138
187
  - lib/danger/ci_source/travis.rb
188
+ - lib/danger/comment_generators/github.md.erb
189
+ - lib/danger/dangerfile.rb
139
190
  - lib/danger/dangerfile_dsl.rb
140
191
  - lib/danger/environment_manager.rb
192
+ - lib/danger/init.rb
141
193
  - lib/danger/request_sources/github.rb
142
- - lib/danger/scm_source/git.rb
194
+ - lib/danger/runner.rb
195
+ - lib/danger/scm_source/git_repo.rb
143
196
  - lib/danger/standard_error.rb
144
197
  - lib/danger/version.rb
145
198
  homepage: http://github.com/orta/danger
146
- licenses: []
199
+ licenses:
200
+ - MIT
147
201
  metadata: {}
148
202
  post_install_message:
149
203
  rdoc_options: []
@@ -153,7 +207,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
153
207
  requirements:
154
208
  - - ">="
155
209
  - !ruby/object:Gem::Version
156
- version: '0'
210
+ version: 2.0.0
157
211
  required_rubygems_version: !ruby/object:Gem::Requirement
158
212
  requirements:
159
213
  - - ">="
@@ -161,8 +215,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
161
215
  version: '0'
162
216
  requirements: []
163
217
  rubyforge_project:
164
- rubygems_version: 2.4.8
218
+ rubygems_version: 2.4.6
165
219
  signing_key:
166
220
  specification_version: 4
167
- summary: Ensure your pull request is up to standard with a nice DSL.
221
+ summary: Ensure your pull request is up to standard with a nice DSL
168
222
  test_files: []
data/.gitignore DELETED
@@ -1,44 +0,0 @@
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 DELETED
@@ -1,2 +0,0 @@
1
- --format documentation
2
- --color
@@ -1,4 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.1.3
4
- before_install: gem install bundler -v 1.10.6
@@ -1,7 +0,0 @@
1
- ## 0.1
2
-
3
- * Parses a `Dangerfile` - orta
4
- * Gets GitHub details from Travis & CircleCI - orta
5
- * Gets PR details from GitHub - orta
6
- * Gets Git details from local Git - orta
7
- * Fails when you say it's failed in the Dangerfile - orta
data/Gemfile DELETED
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in danger.gemspec
4
- gemspec
5
-
6
- gem "pry"
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task :default => :spec
@@ -1,11 +0,0 @@
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 DELETED
@@ -1,7 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
-
5
- bundle install
6
-
7
- # Do any other automated setup that you need to do here
@@ -1,29 +0,0 @@
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
@@ -1,2 +0,0 @@
1
- puts "Hi"
2
- puts lines_of_code
data/exe/danger DELETED
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
- $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
-
6
- require 'danger'
7
- Danger::DangerRunner.run ARGV