-
Notifications
You must be signed in to change notification settings - Fork 7
AF-3102 AF-2797 AF-1943 Update codemod to match final transition boilerplate #6
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
Conversation
Security InsightsNo security relevant content was detected by automated scans. Action Items
Questions or Comments? Reach out on Slack: #support-infosec. |
Merge Requirements Met ✅Request Rosie to automerge this pull request by including @Workiva/release-management-p in a comment. General InformationTicket(s): Code Review(s): #6 Reviewers: corwinsheahan-wf, evanweible-wf, sebastianmalysa-wf Additional InformationWatchlist Notifications: None
Note: This is a shortened report. Click here to view Rosie's full evaluation. |
codemod.run_interactive(query) | ||
|
||
if check and num_changes_needed > 0: | ||
print('Failed: %d changes needed.' % num_changes_needed) |
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.
:nice:
|
||
if parent_library_uri: | ||
# This file is a part file and has a parent library referenced by uri. | ||
|
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.
#nit extra new line
if generated_part_filename in existing_part_paths: | ||
return | ||
|
||
# Not necessary if we use a path to reference this parent from the generated part. |
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 builder will determine if there's a library
directive, if not, it will use a part for it's part of
directive, so I think we can remove this code
line_number_to_insert_parts = util.get_line_number_to_insert_parts(lines) | ||
new_lines = [ | ||
'\n', | ||
'// ignore: uri_does_not_exist, uri_has_not_been_generated\n', |
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 don't think we need the uri_does_not_exist
tag here.
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.
Works fine without it in Dart 1.
return | ||
|
||
end = matches[-1].start() | ||
# -1 so a failed 'rfind' maps to the first line. |
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.
what is a failed 'rfind'?
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.
See lines 181-183. All this does is pre-populate the newline_table
with a mapping from -1 to 0 so that if the rfind()
call below returns -1 (i.e. it didn't find the string), it will just map to the 0th line.
over_react_codemod/updaters.py
Outdated
|
||
|
||
def insert_props_or_state_meta(lines, matches, prev_lines, next_lines): | ||
for line in next_lines[:3]: |
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.
looks like this function could break if the consumer sorts meta
anywhere other than below the class declaration?
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.
Yeah, that is correct. There isn't a good way to find it other than this because class bodies and function bodies both use curly braces
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 one where using the dart analyzer would be much more robust
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'd suggest we drop a comment to tell consumers not to move that line
over_react_codemod/updaters.py
Outdated
continue | ||
|
||
updated_line = line.replace( | ||
'class %s' % class_name, 'class _$%s' % class_name) |
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.
Does this handle already private props/state class, for example _FooProps
?
updated = re.sub(pattern, 'class $%s' % class_name, combined) | ||
updated_lines = util.split_lines_by_newline_but_retain_newlines(updated) | ||
updated_lines.insert( | ||
1, '// AF-3369 This will be made private once the transition to Dart 2 is complete.\n') |
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.
Are we 100% sure on that? I thought we would revisit the dart 2 final boilerplate at a later date. If we're not sure, we may want to not add this comment.
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.
My thought right now is that we leave this in because I don't have a better idea at the moment. If we come up with a better solution down the road, that's fine, it just means this comment will be outdated
over_react_codemod/updaters.py
Outdated
combined = ''.join(lines) | ||
factory_name = match.group(1) | ||
updated = combined.replace( | ||
'%s;' % factory_name, '%s = $%s;' % (factory_name, factory_name)) |
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.
We should decide how we want to handle a private factory. Discussion here
start_line_number=3, | ||
new_lines=[ | ||
'// ignore: undefined_identifier\n', | ||
'UiFactory<FooProps> Foo = $Foo;\n', |
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.
we should have a test for a private factory
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.
should that look like UiFactory<_FooProps> _Foo = _$Foo
? Or maybe _$_Foo
? Right now both the builder and this codemod script will output $_Foo
, which is probably not what we want, since we'll want it to be private.
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.
@greglittlefield-wf are there valid use cases for a private factory?
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've found at least this one in WSD: https://github.com/Workiva/web_skin_dart/blob/master/lib/src/ui_components/colorpicker/custom_color_input.dart#L8
- Support private factories (ensure generated initializer is also private) - Strip redundant underscore when renaming state and props classes - Add comment above static PropsMeta/StateMeta fields instructing users to leave them at the top of the class for regression checking - Remove unneeded `uri_does_not_exist` ignore comment - Remove code that handled adding a missing library directive - not needed
start_line_number=3, | ||
new_lines=[ | ||
'// ignore: undefined_identifier\n', | ||
'UiFactory<_PrivateFooProps> _PrivateFoo = _$PrivateFoo;\n', |
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.
Is this what you were thinking @corwinsheahan-wf? Will it require a change to the builder?
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.
Right now the builder generates the the private factory initialization as _$_PrivateFoo
, since it simply takes the name of the factory and adds a _$
prefix, so yes this would require a builder update. I think I'm fine with either approach.
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.
Ok, let's do that, I think it looks enough nicer to be worth it. _$_
is weird
end_line_number=4, | ||
new_lines=[ | ||
'@Props()\n', | ||
'class _$PrivateFooProps extends UiProps {\n', |
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.
@corwinsheahan-wf Same question here, is this what you were thinking for private state/props classes? And will it require a builder change?
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.
Here, I don't believe there would need to be a builder change. The builder will read the value of the props class and simply utilize that in it's generation. I'm fine with this as well. There will still be a _PrivateFooProps
class which will retain the original intention that this is a private class (since the _$PrivateFooProps
naming schema could have been from a public or private class).
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.
Just a couple of nits
new_lines=[ | ||
'\n', | ||
'// ignore: uri_does_not_exist, uri_has_not_been_generated\n', | ||
'// ignore: uri_has_not_been_generated\n', |
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.
#nit could DRY these new_lines
up
new_lines=[ | ||
'@PropsMixin()\n', | ||
'class FooPropsMixin implements UiProps {\n', | ||
' // To ensure the codemod regression checking works properly, please keep this\n', |
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.
#nit could DRY this up as well
QA +1
@Workiva/release-management-p |
@evanweible-wf I will not merge this because:
|
+1 from RM |
Description
Codemod for migrating to dart1+dart2 compatible boilerplate is complete with tests for all suggestors.
CI setup is complete as well, and the CI now uses PyInstaller to bundle the
bin/
scripts (just one for now) into single-file executables. These are defined as build artifacts and can be manually attached to the GitHub releases when we cut them.TODO
Testing
exe_dart1_and_dart2
build artifact runs successfully (download it,chmod +x
it, run it in a repo likeover_react
)@Workiva/app-frameworks