Skip to content

Commit

Permalink
Merge pull request #251 from Workiva/FED-570-unify-package-rename
Browse files Browse the repository at this point in the history
FED-570 Unify package rename codemod
  • Loading branch information
rmconsole3-wf authored Oct 31, 2023
2 parents 0b0083c + 80a9c4d commit 60ae76b
Show file tree
Hide file tree
Showing 21 changed files with 1,414 additions and 101 deletions.
15 changes: 15 additions & 0 deletions bin/unify_package_rename.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2023 Workiva Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

export 'package:over_react_codemod/src/executables/unify_package_rename.dart';
12 changes: 8 additions & 4 deletions lib/src/executables/mui_migration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ import 'package:logging/logging.dart';
import 'package:over_react_codemod/src/util.dart';
import 'package:over_react_codemod/src/ignoreable.dart';
import 'package:over_react_codemod/src/mui_suggestors/components.dart';
import 'package:over_react_codemod/src/mui_suggestors/mui_importer.dart';
import 'package:over_react_codemod/src/mui_suggestors/unused_wsd_import_remover.dart';
import 'package:over_react_codemod/src/util/package_util.dart';
import 'package:over_react_codemod/src/util/pubspec_upgrader.dart';
import 'package:over_react_codemod/src/util/logging.dart';

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

final _log = Logger('orcm.mui_migration');

const _componentOption = 'component';
Expand Down Expand Up @@ -188,8 +190,10 @@ void main(List<String> args) async {
// should only be handled by a single migrator, and shouldn't depend on the
// output of previous migrators.
[aggregate(migratorsToRun)],
[muiImporter],
[unusedWsdImportRemover],
[
importerSuggestorBuilder(importUri: rmuiImportUri, importNamespace: muiNs)
],
[unusedImportRemoverSuggestorBuilder('web_skin_dart')],
]);
if (exitCode != 0) return;

Expand Down
114 changes: 114 additions & 0 deletions lib/src/executables/unify_package_rename.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright 2023 Workiva Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import 'dart:io';

import 'package:args/args.dart';
import 'package:codemod/codemod.dart';
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 = """
To update your code, run the following commands in your repository:
dart pub global activate over_react_codemod
dart pub global run over_react_codemod:unify_package_rename
""";

class CodemodInfo {
CodemodInfo({required this.paths, required this.sequence});
Iterable<String> paths;
Iterable<Suggestor> sequence;
}

void main(List<String> args) async {
final parser = ArgParser.allowAnything();

final parsedArgs = parser.parse(args);

/// Runs a list of codemods one after the other and returns exit code 0 if any fail.
Future<int> runCodemods(
Iterable<CodemodInfo> codemods,
) async {
for (final sequence in codemods) {
final exitCode = await runInteractiveCodemodSequence(
sequence.paths,
sequence.sequence,
defaultYes: true,
args: parsedArgs.rest,
additionalHelpOutput: parser.usage,
changesRequiredOutput: _changesRequiredOutput,
);
if (exitCode != 0) return exitCode;
}

return 0;
}

exitCode = await runCodemods([
// Update RMUI bundle script in all HTML files (and templates) to Unify bundle.
CodemodInfo(paths: allHtmlPathsIncludingTemplates(), sequence: [
HtmlScriptUpdater(rmuiBundleDevUpdated, unifyBundleDev),
HtmlScriptUpdater(rmuiBundleProdUpdated, unifyBundleProd),
]),
// Update RMUI bundle script in all Dart files to Unify bundle.
CodemodInfo(paths: allDartPathsExceptHidden(), sequence: [
DartScriptUpdater(rmuiBundleDevUpdated, unifyBundleDev),
DartScriptUpdater(rmuiBundleProdUpdated, unifyBundleProd),
]),
]);

if (exitCode != 0) return;

final dartPaths = dartFilesToMigrate().toList();
// Work around parts being unresolved if you resolve them before their libraries.
// TODO - reference analyzer issue for this once it's created
sortPartsLast(dartPaths);

await pubGetForAllPackageRoots(dartPaths);
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.
CodemodInfo(paths: dartPaths, sequence: [
unusedImportRemoverSuggestorBuilder('react_material_ui'),
unusedImportRemoverSuggestorBuilder('unify_ui'),
]),
]);
if (exitCode != 0) return;
}
3 changes: 3 additions & 0 deletions lib/src/mui_suggestors/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@
/// is what `muiImporter` picks up on to add the react_material_ui import to
/// libraries only when it's needed.
const muiNs = 'mui';

/// The import uri for the main react_material_ui entrypoint.
const rmuiImportUri = 'package:react_material_ui/react_material_ui.dart';
55 changes: 0 additions & 55 deletions lib/src/mui_suggestors/unused_wsd_import_remover.dart

This file was deleted.

6 changes: 6 additions & 0 deletions lib/src/rmui_bundle_update_suggestors/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ const rmuiBundleDevUpdated =
const rmuiBundleProdUpdated =
'packages/react_material_ui/js/react-material-ui.browser.min.esm.js';

/// The script for the dev Unify bundle.
const unifyBundleDev = 'packages/unify_ui/js/unify-ui.browser.dev.esm.js';

/// The script for the prod Unify bundle.
const unifyBundleProd = 'packages/unify_ui/js/unify-ui.browser.min.esm.js';

/// The type attribute that needs to be added to script tags for the new RMUI bundles.
final typeModuleAttribute = 'type="module"';

Expand Down
141 changes: 141 additions & 0 deletions lib/src/unify_package_rename_suggestors/constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Copyright 2023 Workiva Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// Info on a unify_ui import.
class UnifyImportInfo {
UnifyImportInfo(this.uri,
{this.rmuiUri,
this.namespace,
this.possibleMuiNamespaces,
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;

/// Additional show / hide information used in [importRenamerSuggestorBuilder] to add to updated imports.
String? showHideInfo;
}

/// A list of the standard imports for unify_ui that should be updated.
///
/// Only adds namespace information if the import is commonly used with a namespace.
/// Only adds RMUI uri information if it is different from a simple package name swap.
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',
rmuiUri: 'package:react_material_ui/components/mui_list.dart',
),
UnifyImportInfo(
'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'])
];

/// A map of RMUI component names to their new names in unify_ui.
///
/// This is based on the list of changes in the migration guide: https://github.com/Workiva/react_material_ui/tree/master/react_material_ui#how-to-migrate-from-reactmaterialui-to-unifyui
const rmuiToUnifyIdentifierRenames = {
// Components
'Alert': 'WsdAlert',
'AlertPropsMixin': 'WsdAlertPropsMixin',
'LinkButton': 'WsdLinkButton',
'LinkButtonPropsMixin': 'WsdLinkButtonPropsMixin',
'MuiList': 'UnifyList',
'MuiListPropsMixin': 'UnifyListPropsMixin',
'WorkivaMuiThemeProvider': 'UnifyThemeProvider',
'WorkivaMuiThemeProviderPropsMixin': 'UnifyThemeProviderPropsMixin',
// Alert objects
'AlertIconMappingObject': 'WsdAlertIconMappingObject',
// Autocomplete objects
'AutocompleteFilterOptionsObject': 'AutocompleteFilterOptionsState',
'AutocompleteOnChangeObject': 'AutocompleteChangeDetails',
'AutocompleteRenderOptionObject': 'AutocompleteRenderOptionState',
// Backdrop objects
'BackdropTimeoutObject': 'BackdropObject',
'BackdropTransitionDurationObject': 'BackdropObject',
// Badge objects
'BadgeAnchorOriginObject': 'BadgeOrigin',
'BadgeAnchorOriginObjectVertical': 'BadgeOriginVertical',
'BadgeAnchorOriginObjectHorizontal': 'BadgeOriginHorizontal',
// Breadcrumb objects
'BreadcrumbNavCrumbsObject': 'BreadcrumbNavBreadcrumbModel',
// CSSTransition objects
'CSSTransitionClassNamesObject': 'CSSTransitionClassNames',
// DropdownButton objects
'DropdownButtonOnPlacementUpdate': 'DropdownButtonPlacement',
// Menu objects
'MenuAnchorOriginObject': 'MenuPopoverOrigin',
'MenuTransformOriginObject': 'MenuPopoverOrigin',
'MenuAnchorOriginObjectVertical': 'MenuPopoverOriginVertical',
'MenuTransformOriginObjectVertical': 'MenuPopoverOriginVertical',
'MenuAnchorOriginObjectHorizontal': 'MenuPopoverOriginHorizontal',
'MenuTransformOriginObjectHorizontal': 'MenuPopoverOriginHorizontal',
'MenuAnchorPositionObject': 'MenuPopoverPosition',
// Popover objects
'PopoverAnchorOriginObject': 'PopoverOrigin',
'PopoverTransformOriginObject': 'PopoverOrigin',
'PopoverAnchorOriginObjectVertical': 'PopoverOriginVertical',
'PopoverTransformOriginObjectVertical': 'PopoverOriginVertical',
'PopoverAnchorOriginObjectHorizontal': 'PopoverOriginHorizontal',
'PopoverTransformOriginObjectHorizontal': 'PopoverOriginHorizontal',
'PopoverAnchorPositionObject': 'PopoverPosition',
// Popper objects
'PopperAnchorElObject': 'PopperVirtualElement',
'PopperModifiersObject': 'PopperModifier',
'PopperModifiersObjectPhase': 'PopperModifierPhases',
'PopperPopperOptionsObject': 'PopperOptionsGeneric',
'PopperPopperOptionsObjectPlacement': 'PopperPlacement',
'PopperPopperOptionsObjectStrategy': 'PopperPositioningStrategy',
// Slider objects
'SliderMarksObject': 'SliderMark',
// Snackbar objects
'SnackbarAnchorOriginObject': 'SnackbarOrigin',
'SnackbarAnchorOriginObjectVertical': 'SnackbarOriginVertical',
'SnackbarAnchorOriginObjectHorizontal': 'SnackbarOriginHorizontal',
// TablePagination objects
'TablePaginationLabelDisplayedRowsObject':
'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';
Loading

0 comments on commit 60ae76b

Please sign in to comment.