Skip to content

Commit

Permalink
Merge pull request #305 from Workiva/update-rename-codemod
Browse files Browse the repository at this point in the history
FED-3281 Update rename codemod
  • Loading branch information
rm-astro-wf authored Nov 1, 2024
2 parents 8b4e889 + 2f61fe1 commit 4a741ba
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 324 deletions.
11 changes: 0 additions & 11 deletions lib/src/executables/unify_package_rename.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,10 @@ import 'package:over_react_codemod/src/executables/mui_migration.dart';
import 'package:over_react_codemod/src/rmui_bundle_update_suggestors/constants.dart';
import 'package:over_react_codemod/src/rmui_bundle_update_suggestors/dart_script_updater.dart';
import 'package:over_react_codemod/src/rmui_bundle_update_suggestors/html_script_updater.dart';
import 'package:over_react_codemod/src/unify_package_rename_suggestors/constants.dart';
import 'package:over_react_codemod/src/unify_package_rename_suggestors/import_renamer.dart';
import 'package:over_react_codemod/src/unify_package_rename_suggestors/unify_rename_suggestor.dart';
import 'package:over_react_codemod/src/util.dart';

import '../util/importer.dart';
import '../util/unused_import_remover.dart';

const _changesRequiredOutput = """
Expand Down Expand Up @@ -88,20 +86,11 @@ void main(List<String> args) async {
exitCode = await runCodemods([
// Make main rename updates.
CodemodInfo(paths: dartPaths, sequence: [UnifyRenameSuggestor()]),
// Add WSD entrypoint imports as needed.
CodemodInfo(paths: dartPaths, sequence: [
importerSuggestorBuilder(
importUri: unifyWsdUri,
importNamespace: unifyWsdNamespace,
)
]),
// Update rmui imports to unify.
CodemodInfo(paths: dartPaths, sequence: [
importRenamerSuggestorBuilder(
oldPackageName: 'react_material_ui',
newPackageName: 'unify_ui',
oldPackageNamespace: 'mui',
newPackageNamespace: 'unify',
)
]),
// Remove any left over unused imports.
Expand Down
25 changes: 6 additions & 19 deletions lib/src/unify_package_rename_suggestors/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,14 @@

/// Info on a unify_ui import.
class UnifyImportInfo {
UnifyImportInfo(this.uri,
{this.rmuiUri,
this.namespace,
this.possibleMuiNamespaces,
this.showHideInfo});
UnifyImportInfo(this.uri, {this.rmuiUri, this.namespace, this.showHideInfo});

/// Unify import URI.
String uri;

/// Recommended Unify version of the import namespace, if applicable.
String? namespace;

/// List of common RMUI versions of the namespace for the import, if applicable.
List<String>? possibleMuiNamespaces;

/// Previous RMUI import URI (if it's different from the unify_ui path).
String? rmuiUri;

Expand All @@ -44,15 +37,11 @@ final rmuiImportsToUpdate = [
UnifyImportInfo(
'package:unify_ui/unify_ui.dart',
rmuiUri: 'package:react_material_ui/react_material_ui.dart',
namespace: 'unify',
possibleMuiNamespaces: ['mui', 'rmui'],
),
UnifyImportInfo(
'package:unify_ui/z_alpha_may_break_at_runtime_do_not_release_to_customers.dart',
rmuiUri:
'package:react_material_ui/z_alpha_may_break_at_runtime_do_not_release_to_customers.dart',
namespace: 'alpha_unify',
possibleMuiNamespaces: ['alpha_mui', 'mui_alpha'],
),
UnifyImportInfo(
'package:unify_ui/components/list.dart',
Expand All @@ -62,10 +51,11 @@ final rmuiImportsToUpdate = [
'package:unify_ui/styles/styled.dart',
rmuiUri: 'package:react_material_ui/for_cp_use_only/styled.dart',
),
UnifyImportInfo('package:unify_ui/styles/theme_provider.dart',
rmuiUri: 'package:react_material_ui/styles/theme_provider.dart',
namespace: 'unify_theme',
possibleMuiNamespaces: ['mui_theme'])
UnifyImportInfo(
'package:unify_ui/components/usage_must_be_approved_by_unify_team_for_legal_reasons/data_grid_premium.dart',
rmuiUri:
'package:react_material_ui/components/usage_must_be_approved_by_unify_team_for_legal_reasons_rmui/data_grid_premium.dart',
)
];

/// A map of RMUI component names to their new names in unify_ui.
Expand Down Expand Up @@ -134,8 +124,5 @@ const rmuiToUnifyIdentifierRenames = {
'TablePaginationLabelDisplayedRowsArgs',
};

/// The namespace that will be used for the `unify_ui/components/wsd.dart` import that is added.
const unifyWsdNamespace = 'unify_wsd';

/// The uri for the `unify_ui/components/wsd.dart` import that is added.
const unifyWsdUri = 'package:unify_ui/components/wsd.dart';
22 changes: 4 additions & 18 deletions lib/src/unify_package_rename_suggestors/import_renamer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import 'constants.dart';
Suggestor importRenamerSuggestorBuilder({
required String oldPackageName,
required String newPackageName,
required String oldPackageNamespace,
required String newPackageNamespace,
}) {
return (context) async* {
final libraryResult = await context.getResolvedLibrary();
Expand Down Expand Up @@ -52,33 +50,21 @@ Suggestor importRenamerSuggestorBuilder({
final namespace = import.prefix?.name;
var newImportUri = importUri?.replaceFirst(
'package:$oldPackageName/', 'package:$newPackageName/');
var newNamespace =
namespace == oldPackageNamespace ? newPackageNamespace : namespace;

// Check for special cases where the unify_ui import path does not match the previous RMUI path.
final specialCaseRmuiImport =
rmuiImportsToUpdate.where((i) => importUri == i.rmuiUri);
if (specialCaseRmuiImport.isNotEmpty) {
newImportUri = specialCaseRmuiImport.single.uri;

final specialCaseNamespace = specialCaseRmuiImport.single.namespace;
if (namespace != null &&
specialCaseNamespace != null &&
(specialCaseRmuiImport.single.possibleMuiNamespaces
?.contains(namespace) ??
false)) {
newNamespace = specialCaseNamespace;
}
}

if (newImportUri != null) {
// Collect info on new imports to add.
newImportsInfo.add(UnifyImportInfo(newImportUri,
namespace: newNamespace,
showHideInfo: import.combinators
.map((c) => c.toSource())
.toList()
.join(' ')));
namespace: namespace,
showHideInfo: import.combinators.isEmpty
? null
: import.combinators.map((c) => c.toSource()).join(' ')));
}

final prevTokenEnd = import.beginToken.previous?.end;
Expand Down
88 changes: 35 additions & 53 deletions lib/src/unify_package_rename_suggestors/unify_rename_suggestor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:codemod/codemod.dart';
import 'package:collection/collection.dart';
import 'package:logging/logging.dart';

import '../util.dart';
import '../util/class_suggestor.dart';
import '../util/element_type_helpers.dart';
import '../util/importer.dart';
import 'constants.dart';

final _log = Logger('UnifyRenameSuggestor');
Expand All @@ -30,38 +30,14 @@ final _log = Logger('UnifyRenameSuggestor');
///
/// - Rename specific components and objects
/// - Update WSD ButtonColor usages
/// - Rename import namespaces 'mui' => 'unify'
/// - Add fix me comments for manual checks
///
/// Also see migration guide: https://github.com/Workiva/react_material_ui/tree/master/react_material_ui#how-to-migrate-from-reactmaterialui-to-unifyui
class UnifyRenameSuggestor extends GeneralizingAstVisitor with ClassSuggestor {
UnifyRenameSuggestor();

@override
visitMethodInvocation(MethodInvocation node) {
super.visitMethodInvocation(node);

// Replace 'mui' namespaces usage with 'unify' for method invocations.
final uri = node.methodName.staticElement?.source?.uri;
if (uri != null &&
(isUriWithinPackage(uri, 'react_material_ui') ||
isUriWithinPackage(uri, 'unify_ui'))) {
final importNamespace = node.target;
if (importNamespace != null) {
final newImportNamespace = rmuiImportsToUpdate
.where((import) =>
import.possibleMuiNamespaces
?.contains(importNamespace.toSource()) ??
false)
.singleOrNull
?.namespace;
if (newImportNamespace != null) {
yieldPatch(
newImportNamespace, importNamespace.offset, importNamespace.end);
}
}
}
}
/// Whether or not to add [unifyWsdUri] import.
late bool needsWsdImport;

@override
visitIdentifier(Identifier node) {
Expand All @@ -82,13 +58,11 @@ class UnifyRenameSuggestor extends GeneralizingAstVisitor with ClassSuggestor {
isUriWithinPackage(uri, 'unify_ui'))) {
// Update components and objects that were renamed in unify_ui.
final newName = rmuiToUnifyIdentifierRenames[identifier?.name];
var isFromWsdEntrypoint = newName?.startsWith('Wsd') ?? false;
if (identifier != null && newName != null) {
if (isFromWsdEntrypoint) {
// Overwrite or add import namespace for components that will be imported from the separate
// unify_ui/components/wsd.dart entrypoint so we can keep the namespace of the import
// we add consistent with the components that use it.
yieldPatch('$unifyWsdNamespace.$newName', node.offset, node.end);
if (newName.startsWith('Wsd')) {
needsWsdImport = true;
// Overwrite namespace as well because wsd import will be added with no namespace.
yieldPatch(newName, node.offset, node.end);
} else {
yieldPatch(newName, identifier.offset, identifier.end);
}
Expand All @@ -99,21 +73,21 @@ class UnifyRenameSuggestor extends GeneralizingAstVisitor with ClassSuggestor {
// Update WSD constant properties objects to use the WSD versions if applicable.
yieldWsdRenamePatchIfApplicable(
Expression node, String? objectName, String? propertyName) {
const alertConstantNames = [
const wsdConstantNames = [
'AlertSize',
'AlertColor',
'AlertVariant',
'AlertSeverity'
'AlertSeverity',
'LinkButtonType',
'LinkButtonSize',
];
if (objectName == 'ButtonColor' &&
(propertyName?.startsWith('wsd') ?? false)) {
isFromWsdEntrypoint = true;
yieldPatch('$unifyWsdNamespace.WsdButtonColor.$propertyName',
node.offset, node.end);
} else if (alertConstantNames.contains(objectName)) {
isFromWsdEntrypoint = true;
yieldPatch('$unifyWsdNamespace.Wsd$objectName.$propertyName',
node.offset, node.end);
needsWsdImport = true;
yieldPatch('WsdButtonColor.$propertyName', node.offset, node.end);
} else if (wsdConstantNames.contains(objectName)) {
needsWsdImport = true;
yieldPatch('Wsd$objectName.$propertyName', node.offset, node.end);
}
}

Expand All @@ -127,21 +101,17 @@ class UnifyRenameSuggestor extends GeneralizingAstVisitor with ClassSuggestor {
}
}

// Replace 'mui' namespaces usage with 'unify'.
final newNamespace = rmuiImportsToUpdate
.where((import) =>
import.possibleMuiNamespaces?.contains(prefix?.name) ?? false)
.singleOrNull
?.namespace;
if (prefix != null && newNamespace != null && !isFromWsdEntrypoint) {
yieldPatch(newNamespace, prefix.offset, prefix.end);
}

// Add comments for components that need manual verification.
if (identifier?.name == 'Badge' || identifier?.name == 'LinearProgress') {
yieldInsertionPatch(
lineComment(
'FIXME(unify_package_rename) Check what theme provider is wrapping this component: if it is a UnifyThemeProvider, remove this FIXME - no action is required; otherwise, migrate this component back to Web Skin Dart.'),
'FIXME(unify_package_rename) Check what theme provider is wrapping this component: if it is a UnifyThemeProvider, manually QA this component and remove this FIXME; otherwise, migrate this component back to Web Skin Dart.'),
node.offset);
} else if (identifier?.name == 'Alert' ||
identifier?.name == 'AlertPropsMixin') {
yieldInsertionPatch(
lineComment(
'FIXME(unify_package_rename) Check what theme provider is wrapping this component: if it is a UnifyThemeProvider, update this to `${identifier?.name}` from `unify_ui/components/alert.dart`, manually QA this component, and remove this FIXME; otherwise, remove this FIXME.'),
node.offset);
}
}
Expand All @@ -156,7 +126,19 @@ class UnifyRenameSuggestor extends GeneralizingAstVisitor with ClassSuggestor {
throw Exception(
'Could not get resolved result for "${context.relativePath}"');
}
needsWsdImport = false;
result.unit.visitChildren(this);

if (needsWsdImport) {
final insertInfo = insertionLocationForPackageImport(
unifyWsdUri, result.unit, result.lineInfo);
yieldPatch(
insertInfo.leadingNewlines +
"import '$unifyWsdUri';" +
insertInfo.trailingNewlines,
insertInfo.offset,
insertInfo.offset);
}
}

@override
Expand Down
28 changes: 14 additions & 14 deletions test/unify_package_rename_suggestors/import_renamer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ void main() {
importRenamerSuggestorBuilder(
oldPackageName: 'react_material_ui',
newPackageName: 'unify_ui',
oldPackageNamespace: 'mui',
newPackageNamespace: 'unify',
),
);

Expand Down Expand Up @@ -79,9 +77,9 @@ void main() {
''',
expectedOutput: '''
import 'package:'''
'''unify_ui/styles/styled.dart' as unify;
'''unify_ui/styles/styled.dart' as mui;
import 'package:'''
'''unify_ui/unify_ui.dart' as unify;
'''unify_ui/unify_ui.dart' as mui;
content() => Dom.div()();
''',
Expand All @@ -98,7 +96,9 @@ void main() {
import 'package:web_skin_dart/ui_components.dart';
import 'package:react_material_ui/for_cp_use_only/styled.dart';
import 'package:react_material_ui/components/mui_list.dart';
import 'package:react_material_ui/components/usage_must_be_approved_by_unify_team_for_legal_reasons_rmui/data_grid_premium.dart';
import 'package:react_material_ui/styles/styled.dart';
content() => Dom.div()();
''',
Expand All @@ -107,6 +107,8 @@ void main() {
import 'package:'''
'''unify_ui/components/list.dart';
import 'package:'''
'''unify_ui/components/usage_must_be_approved_by_unify_team_for_legal_reasons/data_grid_premium.dart';
import 'package:'''
'''unify_ui/styles/styled.dart';
import 'package:'''
'''unify_ui/styles/styled.dart';
Expand Down Expand Up @@ -141,15 +143,15 @@ void main() {
import 'package:'''
'''unify_ui/components/alert.dart' as something_else;
import 'package:'''
'''unify_ui/components/badge.dart' as unify;
'''unify_ui/components/badge.dart' as mui;
import 'package:'''
'''unify_ui/styles/theme_provider.dart' as unify_theme show UnifyThemeProvider;
'''unify_ui/styles/theme_provider.dart' as mui_theme show UnifyThemeProvider;
import 'package:'''
'''unify_ui/unify_ui.dart' as unify;
'''unify_ui/unify_ui.dart' as mui;
import 'package:'''
'''unify_ui/z_alpha_may_break_at_runtime_do_not_release_to_customers.dart' as alpha_unify;
'''unify_ui/z_alpha_may_break_at_runtime_do_not_release_to_customers.dart' as alpha_mui;
import 'package:'''
'''unify_ui/z_alpha_may_break_at_runtime_do_not_release_to_customers.dart' as alpha_unify;
'''unify_ui/z_alpha_may_break_at_runtime_do_not_release_to_customers.dart' as mui_alpha;
content() => Dom.div()();
''',
Expand All @@ -173,11 +175,11 @@ void main() {
import 'package:'''
'''unify_ui/components/badge.dart' show Badge hide BadgeColor;
import 'package:'''
'''unify_ui/styles/theme_provider.dart' as unify_theme show UnifyThemeProvider;
'''unify_ui/styles/theme_provider.dart' as mui_theme show UnifyThemeProvider;
import 'package:'''
'''unify_ui/unify_ui.dart' hide Alert;
import 'package:'''
'''unify_ui/z_alpha_may_break_at_runtime_do_not_release_to_customers.dart' as alpha_unify hide Alert show LinearProgress;
'''unify_ui/z_alpha_may_break_at_runtime_do_not_release_to_customers.dart' as mui_alpha hide Alert show LinearProgress;
content() => Dom.div()();
''',
Expand Down Expand Up @@ -210,8 +212,6 @@ void main() {
importRenamerSuggestorBuilder(
oldPackageName: 'old',
newPackageName: 'new',
oldPackageNamespace: 'o',
newPackageNamespace: 'n',
),
);
await testSuggestor(
Expand All @@ -228,7 +228,7 @@ void main() {
import 'package:'''
'''new/components/badge.dart';
import 'package:'''
'''new/old.dart' as n;
'''new/old.dart' as o;
import 'package:over_react/over_react.dart';
content() => Dom.div()();
Expand Down
Loading

0 comments on commit 4a741ba

Please sign in to comment.