Class: Danger::PRSizeChecker

Inherits:
Plugin
  • Object
show all
Defined in:
lib/dangermattic/plugins/pr_size_checker.rb

Overview

Plugin to check the size of a Pull Request content and text body.

Examples:

Running a PR diff size check with default parameters


# Check the total size of changes in the PR using the default parameters, reporting a warning if the PR is larger than 500
pr_size_checker.check_diff_size(max_size: 500)

Running a PR diff size check customizing the size, message and type of report


# Check the total size of changes in the PR, reporting an error if the diff is larger than 1000 using the specified message
pr_size_checker.check_diff_size(max_size: 1000, message: 'PR too large, 1000 is the max!!', report_type: :error)

Running a PR diff size check on the specified files in part of the diff


# Check the size of insertions in the files selected by the file_selector
pr_size_checker.check_diff_size(file_selector: ->(file) { file.include?('/java/test/') }, type: :insertions)

Running a PR diff size check that excludes comment and blank lines from the count


# Only count changed lines that are neither blank nor comments (e.g. Kotlin/Java/Swift)
pr_size_checker.check_diff_size(
  max_size: 300,
  line_selector: ->(line) { stripped = line.strip; !(stripped.empty? || stripped.start_with?('//', '/*', '*', '*/')) }
)

Running a PR description length check


# Check the PR Body using the default parameters, reporting a warning if the PR is smaller than 10 characters
pr_size_checker.check_pr_body(min_length: 10)

Running a PR description length check with custom parameters


# Check if the minimum length of the PR body is smaller than 20 characters, reporting an error using a custom error message
pr_size_checker.check_pr_body(min_length: 20, message: 'Add a better description, 20 chars at least!!', report_type: :error)

See Also:

  • Automattic/dangermattic

Constant Summary collapse

DEFAULT_DIFF_SIZE_MESSAGE_FORMAT =
'This PR is larger than %d lines of changes. Please consider splitting it into smaller PRs for easier and faster reviews.'
DEFAULT_MIN_PR_BODY_MESSAGE_FORMAT =
'The PR description appears very short, less than %d characters long. Please provide a summary of your changes in the PR description.'

Instance Method Summary collapse

Instance Method Details

#check_diff_size(max_size:, file_selector: nil, line_selector: nil, type: :all, message: format(DEFAULT_DIFF_SIZE_MESSAGE_FORMAT, max_size), report_type: :warning) ⇒ void

This method returns an undefined value.

Check the size of the PR diff against a specified maximum size.

Parameters:

  • max_size (Integer)

    The maximum allowed size for the diff.

  • file_selector (Proc) (defaults to: nil)

    Optional closure to filter the files in the diff to be used for size calculation.

  • line_selector (Proc) (defaults to: nil)

    Optional closure to filter the individual changed lines counted towards the size. It receives the content of an added/removed line (without the leading +/- diff marker or trailing newline) and should return true for lines that should be counted. When provided, the size is computed by iterating the diff patches instead of the cached numstats, which is slower but allows excluding lines such as comments or blanks.

  • type (:insertions, :deletions, :all) (defaults to: :all)

    The type of diff size to check. (default: :all)

  • message (String) (defaults to: format(DEFAULT_DIFF_SIZE_MESSAGE_FORMAT, max_size))

    The message to display if the diff size exceeds the maximum. (default: DEFAULT_DIFF_SIZE_MESSAGE)

  • report_type (Symbol) (defaults to: :warning)

    (optional) The type of report for the message. Types: :error, :warning (default), :message.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/dangermattic/plugins/pr_size_checker.rb', line 59

def check_diff_size(max_size:, file_selector: nil, line_selector: nil, type: :all, message: format(DEFAULT_DIFF_SIZE_MESSAGE_FORMAT, max_size), report_type: :warning)
  size = case type
         when :insertions
           insertions_size(file_selector: file_selector, line_selector: line_selector)
         when :deletions
           deletions_size(file_selector: file_selector, line_selector: line_selector)
         when :all
           diff_size(file_selector: file_selector, line_selector: line_selector)
         else
           raise ArgumentError, "Unknown diff size type: #{type.inspect}. Use :insertions, :deletions, or :all."
         end

  reporter.report(message: message, type: report_type) if size > max_size
end

#check_pr_body(min_length:, message: format(DEFAULT_MIN_PR_BODY_MESSAGE_FORMAT, min_length), report_type: :warning) ⇒ void

This method returns an undefined value.

Check the size of the Pull Request description (PR body) against a specified minimum size.

Parameters:

  • min_length (Integer)

    The minimum allowed length for the PR body.

  • message (String) (defaults to: format(DEFAULT_MIN_PR_BODY_MESSAGE_FORMAT, min_length))

    The message to display if the length of the PR body is smaller than the minimum. (default: DEFAULT_MIN_PR_BODY_MESSAGE_FORMAT)

  • report_type (Boolean) (defaults to: :warning)

    If true, fail the PR check when the PR body length is too small. (default: false)



81
82
83
84
85
# File 'lib/dangermattic/plugins/pr_size_checker.rb', line 81

def check_pr_body(min_length:, message: format(DEFAULT_MIN_PR_BODY_MESSAGE_FORMAT, min_length), report_type: :warning)
  return if danger.github.pr_body.length > min_length

  reporter.report(message: message, type: report_type)
end

#deletions_size(file_selector: nil, line_selector: nil) ⇒ Integer

Calculate the total size of deletions in modified files that match the file selector.

Parameters:

  • file_selector (Proc) (defaults to: nil)

    Select the files to be used for the deletions calculation.

  • line_selector (Proc) (defaults to: nil)

    Optional closure to select which removed lines are counted (see #check_diff_size).

Returns:

  • (Integer)

    The total size of deletions in the selected modified files.



113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/dangermattic/plugins/pr_size_checker.rb', line 113

def deletions_size(file_selector: nil, line_selector: nil)
  return filtered_diff_size(file_selector: file_selector, line_selector: line_selector, change_types: [:removed]) if line_selector

  return danger.git.deletions unless file_selector

  filtered_files = git_utils.all_changed_files.select(&file_selector)

  filtered_files.sum do |file|
    # Use cached stats directly instead of calling info_for_file for each file
    danger.git.diff.stats[:files][file]&.[](:deletions).to_i
  end
end

#diff_size(file_selector: nil, line_selector: nil) ⇒ Integer

Calculate the total size of changes (insertions and deletions) in modified files that match the file selector.

Parameters:

  • file_selector (Proc) (defaults to: nil)

    Select the files to be used for the total insertions and deletions calculation.

  • line_selector (Proc) (defaults to: nil)

    Optional closure to select which added/removed lines are counted (see #check_diff_size).

Returns:

  • (Integer)

    The total size of changes in the selected modified files.



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/dangermattic/plugins/pr_size_checker.rb', line 132

def diff_size(file_selector: nil, line_selector: nil)
  return filtered_diff_size(file_selector: file_selector, line_selector: line_selector, change_types: %i[added removed]) if line_selector

  return danger.git.lines_of_code unless file_selector

  filtered_files = git_utils.all_changed_files.select(&file_selector)

  filtered_files.sum do |file|
    # Use cached stats directly instead of calling info_for_file for each file
    stats = danger.git.diff.stats[:files][file]
    next 0 unless stats

    stats[:deletions].to_i + stats[:insertions].to_i
  end
end

#insertions_size(file_selector: nil, line_selector: nil) ⇒ Integer

Calculate the total size of insertions in modified files that match the file selector.

Parameters:

  • file_selector (Proc) (defaults to: nil)

    Select the files to be used for the insertions calculation.

  • line_selector (Proc) (defaults to: nil)

    Optional closure to select which added lines are counted (see #check_diff_size).

Returns:

  • (Integer)

    The total size of insertions in the selected modified files.



93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/dangermattic/plugins/pr_size_checker.rb', line 93

def insertions_size(file_selector: nil, line_selector: nil)
  return filtered_diff_size(file_selector: file_selector, line_selector: line_selector, change_types: [:added]) if line_selector

  return danger.git.insertions unless file_selector

  # Only check added and modified files - deleted files have 0 insertions
  filtered_files = git_utils.added_and_modified_files.select(&file_selector)

  filtered_files.sum do |file|
    # Use cached stats directly instead of calling info_for_file for each file
    danger.git.diff.stats[:files][file]&.[](:insertions).to_i
  end
end