Skip to content

qaware/refactobot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Refactobot - Automate code reorganizations in large Java codebases.

Build Status Coverage Status License

Moving or renaming individual classes is a no-brainer in today’s IDEs. But what if you want to rename thousands of classes in hundreds of packages? What if you want to reorganize a large codebase into a new module structure?

Refactobot takes a codebase and some transformations, and applies them to the codebase fully automatically, adapting all references. Transformations may include:

  • Changing class and package names

  • Moving classes between packages and modules (in a multi-module build)

Features

Automated and fast

Transforming a codebase just means running a script, and processes thousands of classes within seconds. This means you can reliably reproduce the transformation as many times as needed, as the codebase is still undergoing changes.

Fully preserves formatting, whitespace, and comments

Refactobot only touches references to classes, when they are renamed or moved. All other code and formatting remains as it is.

Declarative and powerful transformation language

Transformations are expressed declaratively in a Kotlin-based DSL. From simple move commands, to regex-based matching, to custom scripting (in Kotlin), refactoring scripts usually are just a few lines of simple code.

Structure101 class map import

If you use Structure 101 for planning your refactoring, you can directly export a class map and apply it using Refactobot.

Battle-tested

Refactobot was used successfully to establish a completely revamped module structure for a 200kloc codebase, which involved moving almost every class to a new place, and introduce uniform naming and packaging conventions. Of course, every project is different, so it may need some tweaking to work

Hackable

Since every codebase is different, some adaptation may be needed in some cases. Refactobot is easily extensible due to its modular design. On the other hand, do not expect a polished product-like experience. This is for developers!

Examples

Uniformly rename classes, to establish or change some naming conventions:

val refactobot = Refactobot.configure {

    refactor {
        renameFile("""(.*)DaoBean\.java""" to "(.*)DaoImpl.java")
    }
}

refactobot.run("/path/to/codebase")

Fix the base package:

val oldBasePackage = "org/example/legacybasepackage/"
val newBasePackage = "org/example/newbasepackage/"

val refactobot = Refactobot.configure {

    refactor {

        if (this.path.startsWith(oldBasePackage)) {
            this.path = newBasePackage + this.path.removePrefix(oldBasePackage)
        }
    }
}

refactobot.run("/path/to/codebase")

If you have a map with fully qualified class names, you can apply it like this:

val refactobot = Refactobot.configure {

    refactor {
        applyClassMap(mapOf(
            "org.example.codebase.SomeClass" to "org.example.codebase.NewClassName",
            "org.example.codebase.SomeOtherClass" to "org.example.codebase.ShinyNewOtherClassName"
        ))
    }
}

refactobot.run("/path/to/codebase")

Assumptions and Limitations

Build-tool-agnostic

TBD

Releases

No releases published

Packages

No packages published