Skip to content

Conversation

evanweible-wf
Copy link
Contributor

@evanweible-wf evanweible-wf commented Nov 2, 2018

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

  • General cleanup
  • Finish tests
  • Update readme with contributing instructions
    • Will do this separately
  • Add CI

Testing

  • CI passes
  • Verify that the executable produced as the exe_dart1_and_dart2 build artifact runs successfully (download it, chmod +x it, run it in a repo like over_react)

@Workiva/app-frameworks

@aviary2-wf
Copy link

aviary2-wf commented Nov 2, 2018

Security Insights

No security relevant content was detected by automated scans.

Action Items

  • Review PR for security impact; comment "security review required" if needed or unsure
  • Verify aviary.yaml coverage of security relevant code

Questions or Comments? Reach out on Slack: #support-infosec.

@rmconsole-wf
Copy link

rmconsole-wf commented Nov 2, 2018

Merge Requirements Met ✅

Request Rosie to automerge this pull request by including @Workiva/release-management-p in a comment.

General Information

Ticket(s):

Code Review(s): #6
Release Image Tags:

Reviewers: corwinsheahan-wf, evanweible-wf, sebastianmalysa-wf

Additional Information

Watchlist Notifications: None

	When this pull is merged I will add it to the following release:
	Version: over_react_codemod 0.1.0
	Release Ticket(s): None


Note: This is a shortened report. Click here to view Rosie's full evaluation.
Last updated on Thursday, December 13 11:14 AM CST

@evanweible-wf evanweible-wf changed the title AF-2797 AF-1943 Update codemod to match final transition boilerplate AF-3102 AF-2797 AF-1943 Update codemod to match final transition boilerplate Nov 30, 2018
codemod.run_interactive(query)

if check and num_changes_needed > 0:
print('Failed: %d changes needed.' % num_changes_needed)
Copy link
Contributor

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.

Copy link
Contributor

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.
Copy link
Contributor

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',
Copy link
Contributor

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.

Copy link
Contributor

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.
Copy link
Contributor

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'?

Copy link
Contributor Author

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.



def insert_props_or_state_meta(lines, matches, prev_lines, next_lines):
for line in next_lines[:3]:
Copy link
Contributor

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?

Copy link
Contributor Author

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

Copy link
Contributor Author

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

Copy link
Contributor

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

continue

updated_line = line.replace(
'class %s' % class_name, 'class _$%s' % class_name)
Copy link
Contributor

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')
Copy link
Contributor

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.

Copy link
Contributor Author

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

combined = ''.join(lines)
factory_name = match.group(1)
updated = combined.replace(
'%s;' % factory_name, '%s = $%s;' % (factory_name, factory_name))
Copy link
Contributor

@corwinsheahan-wf corwinsheahan-wf Nov 30, 2018

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',
Copy link
Contributor

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

Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- 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',
Copy link
Contributor Author

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?

Copy link
Contributor

@corwinsheahan-wf corwinsheahan-wf Dec 10, 2018

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.

Copy link
Contributor Author

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',
Copy link
Contributor Author

@evanweible-wf evanweible-wf Dec 10, 2018

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?

Copy link
Contributor

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).

Copy link
Contributor

@corwinsheahan-wf corwinsheahan-wf left a 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',
Copy link
Contributor

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',
Copy link
Contributor

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

@evanweible-wf
Copy link
Contributor Author

QA +1

  • Tested in over_react and web_skin_dart

@Workiva/release-management-p

@rmconsole-wf
Copy link

@evanweible-wf I will not merge this because:

  • 'No major decrease to number of internal dependencies' is False

@rmconsole-wf
Copy link

+1 from RM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants