Skip to content
/ pyjami Public

Python library which helps to automate the migration of Java classes/enums/interfaces.

License

Notifications You must be signed in to change notification settings

eBay/pyjami

Python-based Java code migration helper (Pyjami)

pre-commit Code style: black Code Coverage CodeQL PyPI version HitCount

Python library which helps to automate the migration of Java classes/enums/interfaces.

Scenario

When would you want to use this?

You have a Java project. You want to migrate 99+ classes/enums/interfaces in it. Let's say it contains a com.foo.bar.MyClass, and you want to replace all its usages with those of org.example.newPackage.MyClass.

Your first instinct is a find-and-replace, but you'd have to deal with wildcard imports and partially-qualified references at each level of the package.

You thought of IntelliJ IDEA. It offers a Refactor > Migrate Packages and Classes feature, but:

  • You have a more complicated mapping to specify. Perhaps you want to migrate lorem.Foo to ipsum.Foo, but for lorem.Bar, you want to migrate it to dolor.Bar. To do so in IntelliJ IDEA, you'd have to manually punch in each mapping rule.
  • You don't want to migrate all of them in one transaction. Maybe you want to run unit tests after migrating each, committing the changes to a separate revision only if the tests all pass. IntelliJ IDEA doesn't offer such fine-grained control.
  • Or you simply can't use / would avoid IntelliJ IDEA for some reason.

That's when this toolkit comes to help.

Usage

Migrate one symbol

Please ensure that you've installed these executable programs:

  • gnu-sed (installed by default on most Linux distros; a manual step on macOS). This is because the BSD edition of sed does not support word boundaries ("\b").
  • ripgrep, a line-oriented search tool that recursively searches the current directory for a regex pattern.

To migrate usages of com.foo.bar.MyClass to org.example.newPackage.MyClass, use migrate(...) in java_symbol_migration_helpers.py:

from pathlib import Path
from pyjami.java_symbol_migration_helpers import find_suitable_sed_command, migrate
migrate(
    symbol="MyClass",
    path="src/main/com/foo/bar",
    old_package="com.foo.bar",
    new_package="org.example.newPackage",
    repo_dir=Path("repo/"),
    pom_dependency="""
        <dependency>
            <!-- New home for MyClass. -->
            <groupId>org.example</groupId>
            <artifactId>newPackage</artifactId>
        </dependency>
    """,
    sed_executable=find_suitable_sed_command(),
)

Gather information for a list of symbols to migrate

We provide a make_table() function that gathers information about the symbols that are required in the migration process to follow.

Given an iterable (preferably a Pandas Series) of string, each of which being a symbol to migrate, this function returns a Pandas Dataframe with each line indicating the name, the java file path, and the package name of that symbol in the given directory.

For example, if you have MyProject/Lorem.java containing:

package com.example.MyProject;

class Lorem {...}

and you run:

make_table(
    symbols_to_migrate=("Lorem",),