Skip to content

Commit

Permalink
Added functionality for multiple line comment characters (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
NikkelM authored Feb 22, 2024
1 parent 7a8d83c commit 9511494
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 25 deletions.
8 changes: 5 additions & 3 deletions .github/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ todo-pr-checker:
ignore_files: null
# What action items should be looked for (setting this will the overwrite default values)
action_items: ['TODO', 'FIXME', 'BUG']
# Languages/file types to add. At least either the line comment or both block comment definitions are required.
# If there are no line comments in the language, you may set the value to null.
# Languages/file types to add. At least either the line comment or both block comment definitions are required
# If there are no line comments in the language, you may set the value to null
# The languages shown here are examples and already included in the default configuration
add_languages: [
['js', '//', '/*', '*/'],
['css', null, '/*', '*/'],
['php', ['//', '#'], '/*', '*/'],
['.py', '#']
]
# Whether or not searching for action items should be case sensitive
Expand All @@ -19,7 +21,7 @@ todo-pr-checker:
multiline_comments: false
# How many lines below found action items should be shown in the embedded code snippet
# If there are no more lines below the action item before the file ends, the code snippet will not be able to render
additional_lines: 0
additional_lines: 1
# Whether or not each action item should always be rendered in a separate code snippet
# If disabled, action items that are located close to each other will be rendered in the same code snippet
always_split_snippets: false
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<!--Releasenotes start-->
- Added a new `additional_lines` configuration option to control how many lines below action items are rendered in code snippets.
- Added a new `always_split_snippets` configuration option to control whether or not action items should always be rendered in seperate code snippets, even when they are located close to each other in code.
- The app now supports multiple line comment types for languages that have them, such as `//` and `#` for PHP.
<!--Releasenotes end-->

## v1.3.2
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ To get started, you can copy the `.github/config.yml` file from this repository
| `post_comment` | `items_found`, `always`, `never` | Controls when the app should post a comment. By default, a comment is only posted if an action item has been found. If set to `never`, the check will still fail. If set to `always`, the app will post a comment that all action items have been resolved if none are found. | `items_found` |
| `ignore_files` | `string[]`, maximum 7 entries | A list of glob patterns to specify files that should be ignored during the check. You may specify up to 7 patterns. The pattern matching logic used is the same as for `.gitignore` files. | `null` |
| `action_items` | `string[]`, maximum 15 entries | A list of action items to look for in code comments. If you set this option, the default values will be overwritten, so you must include them in your list to use them. By default, action items are case insensitive. You may specify up to 15 items. | `['TODO', 'FIXME', 'BUG']` |
| `add_languages` | `[string[file_type, line_start, block_start, block_end]]`</br>Example: `[['js', '//', '/*', '*,'], ['css', null, '/*', '*/'], ['.py', '#']]`, maximum 10 entries | A list of a list of programming languages to add support for. This list will be added to the already supported languages. If you define a language that is already supported, the default values will be overwritten. `file_type` must be the extension of the file (e.g. `js`) and may start with a `.`. You may omit the block comment definitions if the file type does not support block comments. If you want to omit the definition of a line comment, you must set `line_start` to `null`. If defining `block_start`, `block_end` must also be defined. You may specify up to 10 new file types. *The file types shown in the example are already natively supported by the app.* | `null` |
| `add_languages` | `[string[file_type, line_start, block_start, block_end]]`</br>Example: `[['js', '//', '/*', '*,'], ['php', ['//', '#'], '/*', '*/'], ['css', null, '/*', '*/'], ['.py', '#']]`, maximum 10 entries | A list of a list of programming languages to add support for. This list will be added to the already supported languages. If you define a language that is already supported, the default values will be overwritten. `file_type` must be the extension of the file (e.g. `js`) and may start with a `.`. If the file type you are adding supports mulitple line comment types, you may define an `array` of `strings` instead of just a `string`. You may omit the block comment definitions if the file type does not support block comments. If you want to omit the definition of a line comment, you may set `line_start` to `null` or omit it. If defining `block_start`, `block_end` must also be defined. You may specify up to 10 new file types. *The file types shown in the example are already natively supported by the app.* | `null` |
| `case_sensitive` | `true`, `false` | Controls whether the app should look for action items in a case-sensitive manner. | `false` |
| `multiline_comments` | `true`, `false` | Whether or not looking for action items in multiline block comments is enabled or not. When enabled, the app *may* incorrectly mark action items in your Pull Request if at least one of the opening or closing line of the block comment (e.g. `*/` and `/*` in JavaScript) are not included in the Pull Request diff, which causes them to not be found by the app. For multiline comments to always work, you must ensure that both the opening and closing characters are included in the diff. Action items located on the first line of a block comment will always be detected, even if this option is disabled. | `false` |
| `additional_lines` | `integer` between `0` and `10` | The number of additional lines to include below found action items in embedded code snippets. The default of `0` shows only the line with the action item. This setting does not influence the behaviour of showing multiple action items in one snippet if they are located close to each other. *Note that if there are not enough lines left in the file to display, the embedded code snippet will not be able to render at all and will display as a link only.* | `0` |
| `additional_lines` | `integer` between `0` and `10` | The number of additional lines to include below found action items in embedded code snippets. If set to `0`, the code snippet shows only the line with the action item. This setting does not influence the behaviour of showing multiple action items in one snippet if they are located close to each other. *Note that if there are not enough lines left in the file to display, the embedded code snippet will not be able to render at all and will display as a link only.* | `1` |
| `always_split_snippets` | `true`, `false` | Whether or not action items should always be rendered in separate code snippets, even when they are located close to each other in code. | `false` |

<details>
Expand Down
53 changes: 33 additions & 20 deletions app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,18 @@ def get_app_options(full_repo_name, head_sha)
'multiline_comments' => ->(value) { [true, false].include?(value) },
'action_items' => ->(value) { value.is_a?(Array) && (0..15).include?(value.size) },
'case_sensitive' => ->(value) { [true, false].include?(value) },
'add_languages' => ->(value) { value.is_a?(Array) && (1..10).include?(value.size) && value.all? { |v| v.is_a?(Array) && (2..4).include?(v.size) && v.all? { |i| i.is_a?(String) || i.nil? } } },
# A language may have multiple line characters, defined as an array of strings in second place, or just a string
'add_languages' => lambda do |value|
value.is_a?(Array) &&
(1..10).include?(value.size) &&
value.all? do |v|
v.is_a?(Array) &&
(2..4).include?(v.size) &&
v[0].is_a?(String) &&
(v.size == 2 || v.size == 4 ? (v[1].is_a?(Array) && v[1].all? { |i| i.is_a?(String) }) || v[1].is_a?(String) : v[1].is_a?(String)) &&
(v[2..] || []).all? { |i| i.is_a?(String) || i.nil? }
end
end,
# The regex checks if the given input is a valid .gitignore pattern
'ignore_files' => ->(value) { value.is_a?(Array) && (1..7).include?(value.size) && value.all? { |v| v.is_a?(String) && %r{\A(/?(\*\*/)?[\w*\[\]{}?\.\/-]+(/\*\*)?/?)\Z}.match?(v) } },
'additional_lines' => ->(value) { value.is_a?(Integer) && (0..10).include?(value) },
Expand Down Expand Up @@ -221,7 +232,6 @@ def get_pull_request_changes(full_repo_name, pull_number, ignore_files_regex)
current_file = ''
line_number = 0
changes = {}
print diff

diff_enum = diff.each_line
line = diff_enum.next rescue nil
Expand Down Expand Up @@ -291,7 +301,7 @@ def check_for_todos(changes, options)
on_block_comment_starting_line = comment_char[1][:block_start] && text.start_with?(comment_char[1][:block_start])

# If the line is a comment and contains any action item, add it to the output collection
file_todos << line if (text.start_with?(comment_char[1][:line]) || on_block_comment_starting_line || in_multiline_comment) && regexes.any? { |regex| text.match(regex) }
file_todos << line if (comment_char[1][:line].any? { |char| text.start_with?(char) } || on_block_comment_starting_line || in_multiline_comment) && regexes.any? { |regex| text.match(regex) }

# Reset the flag if the line ends a block comment
in_multiline_comment = false if !multiline_comments || (comment_char[1][:block_end] && text.end_with?(comment_char[1][:block_end]))
Expand All @@ -307,20 +317,21 @@ def check_for_todos(changes, options)
# (6) Retrieves the file types and comment characters for the app's supported languages, and user defined values
def get_comment_chars(added_languages)
default_comment_chars = {
%w[md html xml] => { line: '<!--', block_start: '<!--', block_end: '-->' },
%w[astro] => { line: '//', block_start: '<!--', block_end: '-->' },
%w[js java ts c cpp cs php swift go kt rs dart sc groovy less sass scss] => { line: '//', block_start: '/*', block_end: '*/' },
%w[css] => { line: '/*', block_start: '/*', block_end: '*/' },
%w[r gitignore sh bash yml yaml] => { line: '#', block_start: nil, block_end: nil },
%w[rb] => { line: '#', block_start: '=begin', block_end: '=end' },
%w[pl] => { line: '#', block_start: '=', block_end: '=cut' },
%w[py] => { line: '#', block_start: "'''", block_end: "'''" },
%w[ps1] => { line: '#', block_start: '<#', block_end: '#>' },
%w[sql] => { line: '--', block_start: '/*', block_end: '*/' },
%w[hs] => { line: '--', block_start: '{-', block_end: '-}' },
%w[lua] => { line: '--', block_start: '--[[', block_end: ']]' },
%w[m] => { line: '%', block_start: '%{', block_end: '%}' },
%w[tex] => { line: '%', block_start: nil, block_end: nil }
%w[md html xml] => { line: ['<!--'], block_start: '<!--', block_end: '-->' },
%w[astro] => { line: ['//'], block_start: '<!--', block_end: '-->' },
%w[js java ts c cpp cs swift go kt rs dart sc groovy less sass scss] => { line: ['//'], block_start: '/*', block_end: '*/' },
%w[php] => { line: ['//', '#'], block_start: '/*', block_end: '*/' },
%w[css] => { line: ['/*'], block_start: '/*', block_end: '*/' },
%w[r gitignore sh bash yml yaml] => { line: ['#'], block_start: nil, block_end: nil },
%w[rb] => { line: ['#'], block_start: '=begin', block_end: '=end' },
%w[pl] => { line: ['#'], block_start: '=', block_end: '=cut' },
%w[py] => { line: ['#'], block_start: "'''", block_end: "'''" },
%w[ps1] => { line: ['#'], block_start: '<#', block_end: '#>' },
%w[sql] => { line: ['--'], block_start: '/*', block_end: '*/' },
%w[hs] => { line: ['--'], block_start: '{-', block_end: '-}' },
%w[lua] => { line: ['--'], block_start: '--[[', block_end: ']]' },
%w[m] => { line: ['%'], block_start: '%{', block_end: '%}' },
%w[tex] => { line: ['%'], block_start: nil, block_end: nil }
}

unwrapped_comment_chars = {}
Expand All @@ -332,15 +343,17 @@ def get_comment_chars(added_languages)

added_languages.each do |lang|
file_type = lang[0].sub(/^\./, '')
line_chars = lang[1].is_a?(Array) ? lang[1] : [lang[1]]
# The length of lang defines which permutation is given by the user
# Users may overwrite the default comment characters for a file type
case lang.length
when 2
unwrapped_comment_chars[file_type] = { line: lang[1], block_start: nil, block_end: nil }
unwrapped_comment_chars[file_type] = { line: line_chars, block_start: nil, block_end: nil }
when 3
unwrapped_comment_chars[file_type] = { line: lang[1], block_start: lang[1], block_end: lang[2] }
# If only the block comment was defined, we need to extract the character from the array entry when setting the block start character, as it was parsed to an array earlier
unwrapped_comment_chars[file_type] = { line: line_chars, block_start: line_chars[0], block_end: lang[2] }
when 4
unwrapped_comment_chars[file_type] = { line: lang[1], block_start: lang[2], block_end: lang[3] }
unwrapped_comment_chars[file_type] = { line: line_chars, block_start: lang[2], block_end: lang[3] }
end
end

Expand Down
7 changes: 7 additions & 0 deletions validation/validation.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* TODO: Alerts in this file: 3 if multiline comments, 2 else */
/* TODO */



/* This is
TODO Number 2 */
17 changes: 17 additions & 0 deletions validation/validation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php
// TODO: Alerts in this file: 3 if multiline comments, 3 else



# TODO



/* TODO */



/* This is a
TODO
*/
?>

0 comments on commit 9511494

Please sign in to comment.