Skip to content

Add way to run codemods non-interactively #51

@evanweible-wf

Description

@evanweible-wf

At Workiva, we've used this library to build codemods that we run in large batches in order to update our whole package ecosystem at once. When we do this, we use a tool that runs the codemods across all applicable projects and opens pull requests with the resulting changes. All of this happens from our CI system, so we have no need for running the codemods interactively - we always pass the --yes-to-all flag in.

For this use case, it'd be nice to have an alternative to runInteractiveCodemod() like runCodemod() (and runCodemodSequence()) that would skip all the interactivity between the terminal user and the codemod.

There are a few benefits to this:

  • Simplified consumption (and implementation) for use cases that don't need the interactivity. Instead of having to pass in args: ['--yes-to-all'], you would just use runCodemod().
  • Easier logging and capturing of logs from CI systems because the terminal would not be cleared in order to display the interactive diff for each patch. Currently, with runInteractiveCodemod(), you have to redirect stderr to a separate file to capture/monitor it.
  • Could support a dry-run mode like runInteractiveCodemod() does via its --fail-on-changes flag. This would be a more natural spot for a dry-run mode, since using --fail-on-changes with the interactive codemod effectively makes it non-interactive anyway. Bonus is that this mode would be able to show all of the changes it would have made, and could be paired with a same-named flag --fail-on-changes (or maybe --set-exit-if-changed to mirror dart format) to produce a check mode to be used in CI systems.

Note that since we already suggest a pattern of writing your own executable that calls runInteractiveCodemod(), this would allow codemod authors to support both interactive and non-interactive modes, probably behind a flag. For example, they could define a -i | --interactive flag that decides whether the codemod is run via runInteractiveCodemod() or via runCodemod(). And a --dry-run flag could be used similarly; when enabled, it would run via runCodemod(dryRun: true).

After typing that last paragraph, I'm realizing that if we were to implement this, it would probably also be nice to export a basic CodemodCommandRunner class that would handle the above interactive/non-interactive/dry-run logic for simple use cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions