Skip to content

Toolkit for running codemods over multiple Kotlin files inspired by jscodeshift.

License

Notifications You must be signed in to change notification settings

orangain/ktcodeshift

Repository files navigation

ktcodeshift Java CI

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: java.nio.file.Path 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.

About

Toolkit for running codemods over multiple Kotlin files inspired by jscodeshift.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages