ktcodeshift View on GitHub
ktcodeshift is a toolkit for running codemods over multiple Kotlin files inspired by jscodeshift. It provides:
- A runner, which executes the provided transform for each file passed to it. It also outputs a summary of how many files have (not) been transformed.
- A wrapper around ktast, providing a different API. ktast is a Kotlin AST library and also tries to preserve the style of original code as much as possible.
Setup
Prerequisites
- Java 11 or later is required.
macOS
brew install orangain/tap/ktcodeshift
Other platforms
Download the latest archive from
releases
and extract it. ktcodeshift
command is available in the
bin
directory.
Usage
Usage: ktcodeshift [-dhV] [--extensions=EXT] -t=TRANSFORM_PATH PATH...
Apply transform logic in TRANSFORM_PATH (recursively) to every PATH.
PATH... Search target files in these paths.
-d, --dry dry run (no changes are made to files)
--extensions=EXT Target file extensions to be transformed (comma
separated list)
(default: kt)
-h, --help Show this help message and exit.
-t, --transform=TRANSFORM_PATH
Transform file
-V, --version Print version information and exit.
For example:
ktcodeshift -t RenameVariable.transform.kts src/main/kotlin
Transform file
A transform file is a Kotlin script file that defines a lambda function
transform: (FileInfo) -> String?
. The
transform
function will be called for each file on the
target paths by the ktcodeshift.
The transform
function takes an argument
FileInfo, which has source: String
and
path: String
of the target file, and must return the
modified source code or null. When the transform function return the
null or the same source code as the input, the ktcodeshift does not
modify the target file.
The script filename should end with .transform.kts
.
import ktast.ast.Node
import ktcodeshift.*
transform { fileInfo ->
Ktcodeshift
.parse(fileInfo.source)
.find<Node.Expression.NameExpression>()
.filter { n ->
parent is Node.Variable && n.text == "foo"
}
.replaceWith { n ->
n.copy(text = "bar")
}
.toSource()
}
The following API documents will be helpful to write a transform file.
Examples
Example transform files are available under the ktcodeshift-cli/src/test/resources/examples/ directory. The __testfixtures__ directory also contains pairs of their input and output.
Development Tips
Dumping AST
You can dump the AST of a Kotlin file using the ktast.ast.Dumper. This is useful to understand the structure of the AST. For example:
import ktast.ast.*
import ktcodeshift.*
transform { fileInfo ->
Ktcodeshift
.parse(fileInfo.source)
.also { println(Dumper.dump(it)) } // This line dumps the AST.
.toSource()
}
Builder Functions
The
ktcodeshift
package provides a number of builder functions to create AST nodes. The
function name corresponds to the class name of the AST node, i.e.
Node.Expression.NameExpression
is created by
nameExpression()
function. Unlike the parameters of the
constructor of the AST node class, many of the parameters of the builder
functions are optional and have sensible default values.