danger 8.0.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.
Files changed (121) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +94 -0
  4. data/bin/danger +5 -0
  5. data/lib/assets/DangerfileTemplate +13 -0
  6. data/lib/danger.rb +44 -0
  7. data/lib/danger/ci_source/appcenter.rb +55 -0
  8. data/lib/danger/ci_source/appveyor.rb +60 -0
  9. data/lib/danger/ci_source/azure_pipelines.rb +44 -0
  10. data/lib/danger/ci_source/bamboo.rb +41 -0
  11. data/lib/danger/ci_source/bitbucket_pipelines.rb +37 -0
  12. data/lib/danger/ci_source/bitrise.rb +65 -0
  13. data/lib/danger/ci_source/buddybuild.rb +62 -0
  14. data/lib/danger/ci_source/buildkite.rb +51 -0
  15. data/lib/danger/ci_source/ci_source.rb +37 -0
  16. data/lib/danger/ci_source/circle.rb +94 -0
  17. data/lib/danger/ci_source/circle_api.rb +51 -0
  18. data/lib/danger/ci_source/cirrus.rb +31 -0
  19. data/lib/danger/ci_source/code_build.rb +57 -0
  20. data/lib/danger/ci_source/codefresh.rb +53 -0
  21. data/lib/danger/ci_source/codeship.rb +44 -0
  22. data/lib/danger/ci_source/dotci.rb +52 -0
  23. data/lib/danger/ci_source/drone.rb +71 -0
  24. data/lib/danger/ci_source/github_actions.rb +43 -0
  25. data/lib/danger/ci_source/gitlab_ci.rb +86 -0
  26. data/lib/danger/ci_source/jenkins.rb +149 -0
  27. data/lib/danger/ci_source/local_git_repo.rb +119 -0
  28. data/lib/danger/ci_source/local_only_git_repo.rb +47 -0
  29. data/lib/danger/ci_source/screwdriver.rb +47 -0
  30. data/lib/danger/ci_source/semaphore.rb +37 -0
  31. data/lib/danger/ci_source/support/commits.rb +17 -0
  32. data/lib/danger/ci_source/support/find_repo_info_from_logs.rb +35 -0
  33. data/lib/danger/ci_source/support/find_repo_info_from_url.rb +42 -0
  34. data/lib/danger/ci_source/support/local_pull_request.rb +14 -0
  35. data/lib/danger/ci_source/support/no_pull_request.rb +7 -0
  36. data/lib/danger/ci_source/support/no_repo_info.rb +5 -0
  37. data/lib/danger/ci_source/support/pull_request_finder.rb +179 -0
  38. data/lib/danger/ci_source/support/remote_pull_request.rb +15 -0
  39. data/lib/danger/ci_source/support/repo_info.rb +10 -0
  40. data/lib/danger/ci_source/surf.rb +37 -0
  41. data/lib/danger/ci_source/teamcity.rb +161 -0
  42. data/lib/danger/ci_source/travis.rb +51 -0
  43. data/lib/danger/ci_source/vsts.rb +73 -0
  44. data/lib/danger/ci_source/xcode_server.rb +48 -0
  45. data/lib/danger/clients/rubygems_client.rb +14 -0
  46. data/lib/danger/commands/dangerfile/gem.rb +43 -0
  47. data/lib/danger/commands/dangerfile/init.rb +30 -0
  48. data/lib/danger/commands/dry_run.rb +54 -0
  49. data/lib/danger/commands/init.rb +297 -0
  50. data/lib/danger/commands/init_helpers/interviewer.rb +92 -0
  51. data/lib/danger/commands/local.rb +83 -0
  52. data/lib/danger/commands/local_helpers/http_cache.rb +36 -0
  53. data/lib/danger/commands/local_helpers/local_setup.rb +46 -0
  54. data/lib/danger/commands/local_helpers/pry_setup.rb +31 -0
  55. data/lib/danger/commands/plugins/plugin_json.rb +46 -0
  56. data/lib/danger/commands/plugins/plugin_lint.rb +54 -0
  57. data/lib/danger/commands/plugins/plugin_readme.rb +45 -0
  58. data/lib/danger/commands/pr.rb +92 -0
  59. data/lib/danger/commands/runner.rb +94 -0
  60. data/lib/danger/commands/staging.rb +53 -0
  61. data/lib/danger/commands/systems.rb +43 -0
  62. data/lib/danger/comment_generators/bitbucket_server.md.erb +20 -0
  63. data/lib/danger/comment_generators/bitbucket_server_inline.md.erb +15 -0
  64. data/lib/danger/comment_generators/bitbucket_server_message_group.md.erb +12 -0
  65. data/lib/danger/comment_generators/github.md.erb +55 -0
  66. data/lib/danger/comment_generators/github_inline.md.erb +26 -0
  67. data/lib/danger/comment_generators/gitlab.md.erb +40 -0
  68. data/lib/danger/comment_generators/gitlab_inline.md.erb +26 -0
  69. data/lib/danger/comment_generators/vsts.md.erb +20 -0
  70. data/lib/danger/core_ext/file_list.rb +18 -0
  71. data/lib/danger/core_ext/string.rb +20 -0
  72. data/lib/danger/danger_core/dangerfile.rb +341 -0
  73. data/lib/danger/danger_core/dangerfile_dsl.rb +29 -0
  74. data/lib/danger/danger_core/dangerfile_generator.rb +11 -0
  75. data/lib/danger/danger_core/environment_manager.rb +123 -0
  76. data/lib/danger/danger_core/executor.rb +92 -0
  77. data/lib/danger/danger_core/message_aggregator.rb +49 -0
  78. data/lib/danger/danger_core/message_group.rb +68 -0
  79. data/lib/danger/danger_core/messages/base.rb +56 -0
  80. data/lib/danger/danger_core/messages/markdown.rb +42 -0
  81. data/lib/danger/danger_core/messages/violation.rb +54 -0
  82. data/lib/danger/danger_core/plugins/dangerfile_bitbucket_cloud_plugin.rb +144 -0
  83. data/lib/danger/danger_core/plugins/dangerfile_bitbucket_server_plugin.rb +211 -0
  84. data/lib/danger/danger_core/plugins/dangerfile_danger_plugin.rb +248 -0
  85. data/lib/danger/danger_core/plugins/dangerfile_git_plugin.rb +158 -0
  86. data/lib/danger/danger_core/plugins/dangerfile_github_plugin.rb +254 -0
  87. data/lib/danger/danger_core/plugins/dangerfile_gitlab_plugin.rb +240 -0
  88. data/lib/danger/danger_core/plugins/dangerfile_local_only_plugin.rb +42 -0
  89. data/lib/danger/danger_core/plugins/dangerfile_messaging_plugin.rb +218 -0
  90. data/lib/danger/danger_core/plugins/dangerfile_vsts_plugin.rb +191 -0
  91. data/lib/danger/danger_core/standard_error.rb +143 -0
  92. data/lib/danger/helpers/array_subclass.rb +61 -0
  93. data/lib/danger/helpers/comment.rb +32 -0
  94. data/lib/danger/helpers/comments_helper.rb +178 -0
  95. data/lib/danger/helpers/comments_parsing_helper.rb +70 -0
  96. data/lib/danger/helpers/emoji_mapper.rb +41 -0
  97. data/lib/danger/helpers/find_max_num_violations.rb +31 -0
  98. data/lib/danger/helpers/message_groups_array_helper.rb +31 -0
  99. data/lib/danger/plugin_support/gems_resolver.rb +77 -0
  100. data/lib/danger/plugin_support/plugin.rb +49 -0
  101. data/lib/danger/plugin_support/plugin_file_resolver.rb +30 -0
  102. data/lib/danger/plugin_support/plugin_linter.rb +161 -0
  103. data/lib/danger/plugin_support/plugin_parser.rb +199 -0
  104. data/lib/danger/plugin_support/templates/readme_table.html.erb +26 -0
  105. data/lib/danger/request_sources/bitbucket_cloud.rb +171 -0
  106. data/lib/danger/request_sources/bitbucket_cloud_api.rb +181 -0
  107. data/lib/danger/request_sources/bitbucket_server.rb +105 -0
  108. data/lib/danger/request_sources/bitbucket_server_api.rb +117 -0
  109. data/lib/danger/request_sources/github/github.rb +530 -0
  110. data/lib/danger/request_sources/github/github_review.rb +126 -0
  111. data/lib/danger/request_sources/github/github_review_resolver.rb +19 -0
  112. data/lib/danger/request_sources/github/github_review_unsupported.rb +25 -0
  113. data/lib/danger/request_sources/gitlab.rb +525 -0
  114. data/lib/danger/request_sources/local_only.rb +53 -0
  115. data/lib/danger/request_sources/request_source.rb +85 -0
  116. data/lib/danger/request_sources/support/get_ignored_violation.rb +17 -0
  117. data/lib/danger/request_sources/vsts.rb +118 -0
  118. data/lib/danger/request_sources/vsts_api.rb +138 -0
  119. data/lib/danger/scm_source/git_repo.rb +181 -0
  120. data/lib/danger/version.rb +4 -0
  121. metadata +339 -0
@@ -0,0 +1,29 @@
1
+ module Danger
2
+ class Dangerfile
3
+ # Anything inside this module is considered public API, and in the future
4
+ # documentation will be generated from it via rdoc.
5
+
6
+ module DSL
7
+ # @!group Danger Zone
8
+ # Provides access to the raw Travis/Circle/Buildkite/GitHub objects, which
9
+ # you can use to pull out extra bits of information. _Warning_
10
+ # the interfaces 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
+ # @return [EnvironmentManager]
13
+
14
+ attr_reader :env
15
+
16
+ private
17
+
18
+ def initialize
19
+ load_default_plugins
20
+ end
21
+
22
+ def load_default_plugins
23
+ Dir["./danger_plugins/*.rb"].each do |file|
24
+ require File.expand_path(file)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ module Danger
2
+ class DangerfileGenerator
3
+ # returns the string for a Dangerfile based on a folder's contents'
4
+ def self.create_dangerfile(_path, _ui)
5
+ # Use this template for now, but this is a really ripe place to
6
+ # improve now!
7
+ dir = Danger.gem_path
8
+ File.read(File.join(dir, "lib", "assets", "DangerfileTemplate"))
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,123 @@
1
+ require "danger/ci_source/ci_source"
2
+ require "danger/request_sources/request_source"
3
+
4
+ module Danger
5
+ class EnvironmentManager
6
+ attr_accessor :ci_source, :request_source, :scm, :ui, :danger_id
7
+
8
+ # Finds a Danger::CI class based on the ENV
9
+ def self.local_ci_source(env)
10
+ CI.available_ci_sources.find { |ci| ci.validates_as_ci? env }
11
+ end
12
+
13
+ # Uses the current Danger::CI subclass, and sees if it is a PR
14
+ def self.pr?(env)
15
+ local_ci_source(env).validates_as_pr?(env)
16
+ end
17
+
18
+ # @return [String] danger's default head branch
19
+ def self.danger_head_branch
20
+ "danger_head".freeze
21
+ end
22
+
23
+ # @return [String] danger's default base branch
24
+ def self.danger_base_branch
25
+ "danger_base".freeze
26
+ end
27
+
28
+ def initialize(env, ui = nil, danger_id = "danger")
29
+ ci_klass = self.class.local_ci_source(env)
30
+ self.ci_source = ci_klass.new(env)
31
+ self.ui = ui || Cork::Board.new(silent: false, verbose: false)
32
+ self.danger_id = danger_id
33
+
34
+ RequestSources::RequestSource.available_request_sources.each do |klass|
35
+ next unless self.ci_source.supports?(klass)
36
+
37
+ request_source = klass.new(self.ci_source, env)
38
+ next unless request_source.validates_as_ci?
39
+ next unless request_source.validates_as_api_source?
40
+ self.request_source = request_source
41
+ end
42
+
43
+ raise_error_for_no_request_source(env, self.ui) unless self.request_source
44
+ self.scm = self.request_source.scm
45
+ end
46
+
47
+ def pr?
48
+ self.ci_source != nil
49
+ end
50
+
51
+ def fill_environment_vars
52
+ request_source.fetch_details
53
+ end
54
+
55
+ def ensure_danger_branches_are_setup
56
+ clean_up
57
+
58
+ self.request_source.setup_danger_branches
59
+ end
60
+
61
+ def clean_up
62
+ [EnvironmentManager.danger_base_branch, EnvironmentManager.danger_head_branch].each do |branch|
63
+ scm.exec("branch -D #{branch}") unless scm.exec("rev-parse --quiet --verify #{branch}").empty?
64
+ end
65
+ end
66
+
67
+ def meta_info_for_head
68
+ scm.exec("--no-pager log #{EnvironmentManager.danger_head_branch} -n1")
69
+ end
70
+
71
+ def meta_info_for_base
72
+ scm.exec("--no-pager log #{EnvironmentManager.danger_base_branch} -n1")
73
+ end
74
+
75
+ def raise_error_for_no_request_source(env, ui)
76
+ title, subtitle = extract_title_and_subtitle_from_source(ci_source.repo_url)
77
+ subtitle += travis_note if env["TRAVIS_SECURE_ENV_VARS"] == "true"
78
+
79
+ ui_display_no_request_source_error_message(ui, env, title, subtitle)
80
+
81
+ exit(1)
82
+ end
83
+
84
+ private
85
+
86
+ def get_repo_source(repo_url)
87
+ if repo_url =~ /github/i
88
+ RequestSources::GitHub
89
+ elsif repo_url =~ /gitlab/i
90
+ RequestSources::GitLab
91
+ elsif repo_url =~ /bitbucket\.(org|com)/i
92
+ RequestSources::BitbucketCloud
93
+ end
94
+ end
95
+
96
+ def extract_title_and_subtitle_from_source(repo_url)
97
+ source = get_repo_source(repo_url)
98
+
99
+ if source
100
+ title = "For your #{source.source_name} repo, you need to expose: " + source.env_vars.join(", ").yellow
101
+ subtitle = "You may also need: #{source.optional_env_vars.join(', ')}" if source.optional_env_vars.any?
102
+ else
103
+ title = "For Danger to run on this project, you need to expose a set of following the ENV vars:\n#{RequestSources::RequestSource.available_source_names_and_envs.join("\n")}"
104
+ end
105
+
106
+ [title, (subtitle || "")]
107
+ end
108
+
109
+ def ui_display_no_request_source_error_message(ui, env, title, subtitle)
110
+ ui.title "Could not set up API to Code Review site for Danger\n".freeze
111
+ ui.puts title
112
+ ui.puts subtitle
113
+ ui.puts "\nFound these keys in your ENV: #{env.keys.join(', '.freeze)}."
114
+ ui.puts "\nFailing the build, Danger cannot run without API access.".freeze
115
+ ui.puts "You can see more information at https://danger.systems/guides/getting_started.html".freeze
116
+ end
117
+
118
+ def travis_note
119
+ "\nTravis note: If you have an open source project, you should ensure 'Display value in build log' enabled for these flags, so that PRs from forks work." \
120
+ "\nThis also means that people can see this token, so this account should have no write access to repos."
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,92 @@
1
+ module Danger
2
+ class Executor
3
+ def initialize(system_env)
4
+ @system_env = system_env
5
+ end
6
+
7
+ def run(env: nil,
8
+ dm: nil,
9
+ cork: nil,
10
+ base: nil,
11
+ head: nil,
12
+ dangerfile_path: nil,
13
+ danger_id: nil,
14
+ new_comment: nil,
15
+ fail_on_errors: nil,
16
+ fail_if_no_pr: nil,
17
+ remove_previous_comments: nil)
18
+ # Create a silent Cork instance if cork is nil, as it's likely a test
19
+ cork ||= Cork::Board.new(silent: false, verbose: false)
20
+
21
+ # Run some validations
22
+ validate!(cork, fail_if_no_pr: fail_if_no_pr)
23
+
24
+ # OK, we now know that Danger can run in this environment
25
+ env ||= EnvironmentManager.new(system_env, cork, danger_id)
26
+ dm ||= Dangerfile.new(env, cork)
27
+
28
+ ran_status = begin
29
+ dm.run(
30
+ base_branch(base),
31
+ head_branch(head),
32
+ dangerfile_path,
33
+ danger_id,
34
+ new_comment,
35
+ remove_previous_comments
36
+ )
37
+ end
38
+
39
+ # By default Danger will use the status API to fail a build,
40
+ # allowing execution to continue, this behavior isn't always
41
+ # optimal for everyone.
42
+ exit(1) if fail_on_errors && ran_status
43
+ end
44
+
45
+ def validate!(cork, fail_if_no_pr: false)
46
+ validate_ci!
47
+ validate_pr!(cork, fail_if_no_pr)
48
+ end
49
+
50
+ private
51
+
52
+ attr_reader :system_env
53
+
54
+ # Could we find a CI source at all?
55
+ def validate_ci!
56
+ unless EnvironmentManager.local_ci_source(system_env)
57
+ abort("Could not find the type of CI for Danger to run on.".red)
58
+ end
59
+ end
60
+
61
+ # Could we determine that the CI source is inside a PR?
62
+ def validate_pr!(cork, fail_if_no_pr)
63
+ unless EnvironmentManager.pr?(system_env)
64
+ ci_name = EnvironmentManager.local_ci_source(system_env).name.split("::").last
65
+
66
+ msg = "Not a #{ci_name} #{commit_request(ci_name)} - skipping `danger` run. "
67
+ # circle won't run danger properly if the commit is pushed and build runs before the PR exists
68
+ # https://danger.systems/guides/troubleshooting.html#circle-ci-doesnt-run-my-build-consistently
69
+ # the best solution is to enable `fail_if_no_pr`, and then re-run the job once the PR is up
70
+ if ci_name == "CircleCI"
71
+ msg << "If you only created the PR recently, try re-running your workflow."
72
+ end
73
+ cork.puts msg.strip.yellow
74
+
75
+ exit(fail_if_no_pr ? 1 : 0)
76
+ end
77
+ end
78
+
79
+ def base_branch(user_specified_base_branch)
80
+ user_specified_base_branch || EnvironmentManager.danger_base_branch
81
+ end
82
+
83
+ def head_branch(user_specified_head_branch)
84
+ user_specified_head_branch || EnvironmentManager.danger_head_branch
85
+ end
86
+
87
+ def commit_request(ci_name)
88
+ return "Merge Request" if ci_name == 'GitLabCI'
89
+ return "Pull Request"
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+ require "danger/danger_core/message_group"
3
+ require "danger/helpers/message_groups_array_helper"
4
+
5
+ module Danger
6
+ class MessageAggregator
7
+ def self.aggregate(*args)
8
+ new(*args).aggregate
9
+ end
10
+
11
+ def initialize(warnings: [],
12
+ errors: [],
13
+ messages: [],
14
+ markdowns: [],
15
+ danger_id: "danger")
16
+ @messages = warnings + errors + messages + markdowns
17
+ @danger_id = danger_id
18
+ end
19
+
20
+ # aggregates the messages into an array of MessageGroups
21
+ # @return [[MessageGroup]]
22
+ def aggregate
23
+ # oookay I took some shortcuts with this one.
24
+ # first, sort messages by file and line
25
+ @messages.sort! { |a, b| a.compare_by_file_and_line(b) }
26
+
27
+ # now create an initial empty message group
28
+ first_group = MessageGroup.new(file: nil,
29
+ line: nil)
30
+ @message_groups = @messages.reduce([first_group]) do |groups, msg|
31
+ # We get to take a shortcut because we sorted the messages earlier - only
32
+ # have to see if we can append msg to the last group in the list
33
+ if groups.last << msg
34
+ # we appended it, so return groups unchanged
35
+ groups
36
+ else
37
+ # have to create a new group since msg wasn't appended to the other
38
+ # group
39
+ new_group = MessageGroup.new(file: msg.file,
40
+ line: msg.line)
41
+ new_group << msg
42
+ groups << new_group
43
+ end
44
+ end
45
+
46
+ @message_groups.extend(Helpers::MessageGroupsArrayHelper)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Danger
4
+ class MessageGroup
5
+ def initialize(file: nil, line: nil)
6
+ @file = file
7
+ @line = line
8
+ end
9
+
10
+ # Returns whether this `MessageGroup` is for the same line of code as
11
+ # `other`, taking which file they are in to account.
12
+ # @param other [MessageGroup, Markdown, Violation]
13
+ # @return [Boolean] whether this `MessageGroup` is for the same line of code
14
+ def same_line?(other)
15
+ other.file == file && other.line == line
16
+ end
17
+
18
+ # Merges two `MessageGroup`s that represent the same line of code
19
+ # In future, perhaps `MessageGroup` will be able to represent a group of
20
+ # messages for multiple lines.
21
+ def merge(other)
22
+ raise ArgumentError, "Cannot merge with MessageGroup for a different line" unless same_line?(other)
23
+
24
+ @messages = (messages + other.messages).uniq
25
+ end
26
+
27
+ # Adds a message to the group.
28
+ # @param message [Markdown, Violation] the message to add
29
+ def <<(message)
30
+ # TODO: insertion sort
31
+ return nil unless same_line?(message)
32
+
33
+ inserted = false
34
+ messages.each.with_index do |other, idx|
35
+ if (message <=> other) == -1
36
+ inserted = true
37
+ messages.insert(idx, message)
38
+ break
39
+ end
40
+ end
41
+ messages << message unless inserted
42
+ messages
43
+ end
44
+
45
+ # The list of messages in this group. This list will be sorted in decreasing
46
+ # order of severity (error, warning, message, markdown)
47
+ def messages
48
+ @messages ||= []
49
+ end
50
+
51
+ attr_reader :file, :line
52
+
53
+ # @return a hash of statistics. Currently only :warnings_count and
54
+ # :errors_count
55
+ def stats
56
+ stats = { warnings_count: 0, errors_count: 0 }
57
+ messages.each do |msg|
58
+ stats[:warnings_count] += 1 if msg.type == :warning
59
+ stats[:errors_count] += 1 if msg.type == :error
60
+ end
61
+ stats
62
+ end
63
+
64
+ def markdowns
65
+ messages.select { |x| x.type == :markdown }
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,56 @@
1
+ module Danger
2
+ class BaseMessage
3
+ attr_accessor :message, :file, :line, :type
4
+
5
+ def initialize(type:, message:, file: nil, line: nil)
6
+ @type = type
7
+ @message = message
8
+ @file = file
9
+ @line = line
10
+ end
11
+
12
+ def compare_by_file_and_line(other)
13
+ order = cmp_nils(file, other.file)
14
+ return order unless order.nil?
15
+
16
+ order = file <=> other.file
17
+ return order unless order.zero?
18
+
19
+ order = cmp_nils(line, other.line)
20
+ return order unless order.nil?
21
+
22
+ line <=> other.line
23
+ end
24
+ # compares a and b based entirely on whether one or the other is nil
25
+ # arguments are in the same order as `a <=> b`
26
+ # nil is sorted earlier - so cmp_nils(nil, 1) => -1
27
+ #
28
+ # If neither are nil, rather than returning `a <=> b` which would seem
29
+ # like the obvious shortcut, `nil` is returned.
30
+ # This allows us to distinguish between cmp_nils returning 0 for a
31
+ # comparison of filenames, which means "a comparison on the lines is
32
+ # meaningless - you cannot have a line number for a nil file - so they
33
+ # should be sorted the same", and a <=> b returning 0, which means "the
34
+ # files are the same, so compare on the lines"
35
+ #
36
+ # @return 0, 1, -1, or nil
37
+ def cmp_nils(a, b)
38
+ if a.nil? && b.nil?
39
+ 0
40
+ elsif a.nil?
41
+ -1
42
+ elsif b.nil?
43
+ 1
44
+ end
45
+ end
46
+
47
+ def eql?(other)
48
+ return self == other
49
+ end
50
+
51
+ # @return [Boolean] returns true if is a file or line, false otherwise
52
+ def inline?
53
+ file || line
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+ require "danger/danger_core/messages/base"
3
+
4
+ module Danger
5
+ class Markdown < BaseMessage
6
+
7
+ def initialize(message, file = nil, line = nil)
8
+ super(type: :markdown, message: message, file: file, line: line)
9
+ end
10
+
11
+ def ==(other)
12
+ return false if other.nil?
13
+ return false unless other.kind_of? self.class
14
+
15
+ other.message == message &&
16
+ other.file == file &&
17
+ other.line == line
18
+ end
19
+
20
+ def hash
21
+ h = 1
22
+ h = h * 31 + message.hash
23
+ h = h * 17 + file.hash
24
+ h = h * 17 + line.hash
25
+ h
26
+ end
27
+
28
+ def to_s
29
+ extra = []
30
+ extra << "file: #{file}" unless file
31
+ extra << "line: #{line}" unless line
32
+
33
+ "Markdown #{message} { #{extra.join ', '.freeze} }"
34
+ end
35
+
36
+ def <=>(other)
37
+ return 1 if other.type != :markdown
38
+
39
+ compare_by_file_and_line(other)
40
+ end
41
+ end
42
+ end