-
Notifications
You must be signed in to change notification settings - Fork 598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes updating columns when using alternative formats #784
base: develop
Are you sure you want to change the base?
Conversation
Runs annotate on 'rake db:rollback' too
Revert "Runs annotate on 'rake db:rollback' too"
ac98ea2
to
9cd0fc2
Compare
lib/annotate/annotate_models.rb
Outdated
@@ -362,7 +366,7 @@ def annotate_one_file(file_name, info_block, position, options = {}) | |||
old_header = old_content.match(header_pattern).to_s | |||
new_header = info_block.match(header_pattern).to_s | |||
|
|||
column_pattern = /^#[\t ]+[\w\*\.`]+[\t ]+.+$/ | |||
column_pattern = /^#[\t ]+[\w\*\.\`\@\!\:]+[\t ]+.+$/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was originally going to break this regular expression up into something like:
def column_pattern_for(format_type)
case format_type
when :yard then //
when :rdoc then //
# etc...
end
end
By the time I go to the end, I saw that the original regular expression could be updated and cover all cases.
I could see an advantage to breaking this up, but didn't want to go too far with refactoring and delay sharing this fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tmr08c if you're still interested in getting this patch in, I think there's value into breaking it up. The column pattern regex is hard to understand already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review and feedback @drwl! Working on updating this PR and adding some additional tests.
Updates `column_pattern` in `AnnotateModels.annotate_one_file` to support RDoc and Yard doc formats. `column_pattern` is responsible for searching for existing annotations in the file - if the patten is not matched in file, annotations are not updated. Since the previous regular expression did not match the Yard (`@!`) or RDoc (`**<attributed>**::`), when attempting to update annotations for a model, it would look like there were no changes since parsing the annotation blocks with the regular expression would return nothing.
9cd0fc2
to
ecc5c9e
Compare
@tvallois since you added Yard support (#724) and @Samsinite since you were interested in YARD support (#720), I figured I'd ping you both to see if you had any thoughts around this change or experienced this issue. |
lib/annotate/annotate_models.rb
Outdated
@@ -362,7 +366,7 @@ def annotate_one_file(file_name, info_block, position, options = {}) | |||
old_header = old_content.match(header_pattern).to_s | |||
new_header = info_block.match(header_pattern).to_s | |||
|
|||
column_pattern = /^#[\t ]+[\w\*\.`]+[\t ]+.+$/ | |||
column_pattern = /^#[\t ]+[\w\*\.\`\@\!\:]+[\t ]+.+$/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tmr08c if you're still interested in getting this patch in, I think there's value into breaking it up. The column pattern regex is hard to understand already.
* Creates a method that checks the options to determine the current format option being used and return a symbol representation. * Breaks up the single regular expression used for determining if a line was an annotation for a column definition into a method that will `case` on the different format option.
* Adds tests for updating the type of a column * Fixes the regular expressions for `rdoc` and `yard` annotation types
# annotations | ||
def column_pattern_for(format_type) | ||
case format_type | ||
when :markdown then /^#\s+\*{2}`\w+`\*{2}(?:\s+\|\s`.*`)*$/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went for stricter matches. I'm not sure if it would make sense to be a bit looser and do something like:
/^#\s+\*{2}`\w+.*$/
that would catch
# **column_name** ...
Currently, I'm checking for the fact there may be additional columns in the markdown table
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After revisiting this PR, I'm not sure how I feel about this. I'm sure if we just grabbing all lines in the annotation section would end up being a problem.
The previous implementation seemed to sort of be checking that the comment had an indication that it was the "column section" (e.g., # col_name
or # * col_name
). This PR goes a bit further and does some stricter checking based on the format.
If we pulled in any non-empty comment line, it seems it shouldn't cause a problem since we are essentially checking for any difference. If we pulled in non-column comments, we'd get them in both old_columns
and new_columns
, so it shouldn't be flagged as a change.
I think the situation that we are avoiding by doing it this way is if there are non-annotation comments in the annotation block since it looks like the header_pattern
grabs all groups comments after the Table name:
comment.
when :markdown then /^#\s+\*{2}`\w+`\*{2}(?:\s+\|\s`.*`)*$/ | ||
when :rdoc then | ||
field_name_regex = /^#\s+\*\w+\*\:{2}/ | ||
field_info_regex = /\s+\<tt\>.*\<\/tt\>$/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to above, rather than checking the <tt>...</tt>
this could all probably be .*$
lib/annotate/annotate_models.rb
Outdated
|
||
/#{attribute_regex}|#{return_regex}/ | ||
else # :bare/default | ||
/^#[\t ]+[\w\*\.\`\@\!\:]+[\t ]+.+$/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the catch-all regular expression. I would like to move it to something more specific to the bare
format.
My initial implementation broke something for foreign keys, so I will need to see how that is handled for the various formats.
Updates the regular expression to more explicitly match the bare case and no longer be the general purpose regex.
- Adds markdown support (and test) - Fixes typo in `#annotate_one_file`
- Appends `_for` to match other regex method - Fixes check in non-bareword case to not capture the `.`. This would reduce the captures being returned instead of whether the line was matched overall
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR ended up being a bit bigger than I expected. Please let me know if it'd be useful to add PR comments to explain any tricky sections.
I'm interested in feedback on whether the new regular expressions are too rigid.
Initially, I liked the idea of taking advantage of generating different regular expressions for each format and creating more specific regular expressions to more closely check for the column syntax. Now, I'm less sure and worry it may end up being brittle.
# annotations | ||
def column_pattern_for(format_type) | ||
case format_type | ||
when :markdown then /^#\s+\*{2}`\w+`\*{2}(?:\s+\|\s`.*`)*$/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After revisiting this PR, I'm not sure how I feel about this. I'm sure if we just grabbing all lines in the annotation section would end up being a problem.
The previous implementation seemed to sort of be checking that the comment had an indication that it was the "column section" (e.g., # col_name
or # * col_name
). This PR goes a bit further and does some stricter checking based on the format.
If we pulled in any non-empty comment line, it seems it shouldn't cause a problem since we are essentially checking for any difference. If we pulled in non-column comments, we'd get them in both old_columns
and new_columns
, so it shouldn't be flagged as a change.
I think the situation that we are avoiding by doing it this way is if there are non-annotation comments in the annotation block since it looks like the header_pattern
grabs all groups comments after the Table name:
comment.
expect(File.read(@model_file_name)).to eq("#{@schema_info}#{@file_content}") | ||
end | ||
|
||
context 'when option "format_bare" is true' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started going down the shared examples route to reduce the noise here. This snowballed a bit since there are additional places where checking for all formats would be useful. I have a WIP branch that I'd like to pick up if it looks like the right direction.
This PR ended up being bigger than I expected, so I thought it would be best to separate additional changes and conversations.
end | ||
end | ||
|
||
context 'when option "format_markdown" is true' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There didn't appear to be a test for the markdown format, so this adds a test for format_markdown
and extracts some of the shared set up into before
s and let
s.
This resolves #780
Updates
column_pattern
inAnnotateModels.annotate_one_file
tosupport RDoc and Yard doc formats.
column_pattern
is responsible forsearching for existing annotations in the file - if the pattern is not
matched in the file, annotations are not updated.
Since the previous regular expression did not match the Yard
(
@!
) or RDoc (**<attributed>**::
), when attempting to updateannotations for a model, it would look like there were no changes since
parsing the annotation blocks with the regular expression would return
nothing.