1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
========
Codemods
========
LibCST defines a codemod as an automated refactor that can be applied to a codebase
of arbitrary size. Codemods are provided as a framework for writing higher-order
transforms that consist of other, simpler transforms. It includes provisions for
quickly creating a command-line interface to execute a codemod.
.. _libcst-codemod-base:
------------
Codemod Base
------------
All codemods derive from a common base, :class:`~libcst.codemod.Codemod`. This class
includes a context, automatic metadata resolution and multi-pass transform support.
Codemods are intended to be executed using the :func:`~libcst.codemod.transform_module`
interface.
.. autoclass:: libcst.codemod.Codemod
.. autoclass:: libcst.codemod.CodemodContext
As a convenience, LibCST-compatible visitors are provided which extend the feature-set
of :class:`~libcst.codemod.Codemod` to LibCST visitors and transforms. Remember that
:class:`~libcst.codemod.ContextAwareTransformer` is still a
:class:`~libcst.codemod.Codemod`, so you should still execute it using
:func:`~libcst.codemod.transform_module`.
.. autoclass:: libcst.codemod.ContextAwareTransformer
:exclude-members: transform_module_impl
.. autoclass:: libcst.codemod.ContextAwareVisitor
It is often necessary to bail out of a codemod mid-operation when you realize that
you do not want to operate on a module. This can be for any reason such as realizing
the module includes some operation that you do not support. If you wish to skip a
module, you can raise the :class:`~libcst.codemod.SkipFile` exception. For codemods
executed using the :func:`~libcst.codemod.transform_module` interface, all warnings
emitted up to the exception being thrown will be preserved in the result.
.. autoclass:: libcst.codemod.SkipFile
Finally, its often easier to test codemods by writing verification tests instead of
running repeatedly on your project. LibCST makes this easy with
:class:`~libcst.codemod.CodemodTest`. Often you can develop the majority of your
codemod using just tests, augmenting functionality when you run into an unexpected
edge case when running it against your repository.
.. autoclass:: libcst.codemod.CodemodTest
:inherited-members:
:exclude-members: addCleanup, addTypeEqualityFunc, assertAlmostEqual, assertAlmostEquals, assertCountEqual, assertDictContainsSubset, assertDictEqual, assertEqual, assertEquals, assertFalse, assertGreater, assertGreaterEqual, assertIn, assertIs, assertIsInstance, assertIsNone, assertIsNot, assertIsNotNone, assertLess, assertLessEqual, assertListEqual, assertLogs, assertMultiLineEqual, assertNotAlmostEqual, assertNotAlmostEquals, assertNotEqual, assertNotEquals, assertNotIn, assertNotIsInstance, assertNotRegex, assertNotRegexpMatches, assertRaises, assertRaisesRegex, assertRaisesRegexp, assertRegex, assertRegexpMatches, assertSequenceEqual, assertSetEqual, assertTrue, assertTupleEqual, assertWarns, assertWarnsRegex, assert_, countTestCases, debug, defaultTestResult, doCleanups, fail, failIf, failIfAlmostEqual, failIfEqual, failUnless, failUnlessAlmostEqual, failUnlessEqual, failUnlessRaises, failureException, id, longMessage, maxDiff, run, setUp, classmethod, setUpClass, shortDescription, skipTest, subTest, tearDown, tearDownClass
-------------------
Execution Interface
-------------------
As documented in the Codemod Base section above, codemods are meant to be
programmatically executed using :func:`~libcst.codemod.transform_module`. Executing
in this manner handles all of the featureset of codemods, including metadata calculation
and exception handling.
.. autofunction:: libcst.codemod.transform_module
.. autoclass:: libcst.codemod.TransformResult
.. autoclass:: libcst.codemod.TransformSuccess
.. autoclass:: libcst.codemod.TransformFailure
.. autoclass:: libcst.codemod.TransformSkip
.. autoclass:: libcst.codemod.SkipReason
.. autoclass:: libcst.codemod.TransformExit
--------------------
Command-Line Support
--------------------
LibCST includes additional support to facilitate faster development of codemods which
are to be run at the command-line. This is achieved through the
:class:`~libcst.codemod.CodemodCommand` class and the ``codemod`` utility which lives
inside ``libcst.tool``. The :class:`~libcst.codemod.CodemodCommand` class provides a
codemod description and an interface to add arguments to the command-line. This is
translated to a custom help message and command-line options that a user can provide
when running a codemod at the command-line.
For a brief overview of supported universal options, run the ``codemod`` utility like so::
python3 -m libcst.tool codemod --help
The utility provides support for gathering up and parallelizing codemods across a
series of files or directories, auto-formatting changed code according to a configured
formatter, generating a unified diff of changes instead of applying them to files,
taking code from stdin and codemodding it before returning to stdout, and printing
progress and warnings to stderr during execution of a codemod.
Help is auto-customized if a codemod class is provided, including any added options
and the codemod description. For an example, run the ``codemod`` utility like so::
python3 -m libcst.tool codemod noop.NOOPCommand --help
A second utility, ``list``, can list all available codemods given your configuration.
Run it like so::
python3 -m libcst.tool list
Finally, to set up a directory for codemodding using these tools, including additional
directories where codemods can be found, use the ``initialize`` utility. To see help
for how to use this, run the ``initialize`` utility like so::
python3 -m libcst.tool initialize --help
The above tools operate against any codemod which subclasses from
:class:`~libcst.codemod.CodemodCommand`. Remember that :class:`~libcst.codemod.CodemodCommand`
is a subclass of :class:`~libcst.codemod.Codemod`, so all of the features documented
in the :ref:`libcst-codemod-base` section are available in addition to command-line
support. Any command-line enabled codemod can also be programmatically instantiated
and invoked using the above-documented :func:`~libcst.codemod.transform_module`
interface.
.. autoclass:: libcst.codemod.CodemodCommand
:exclude-members: transform_module
Additionally, a few convenience classes have been provided which take the boilerplate
out of common types of codemods:
.. autoclass:: libcst.codemod.VisitorBasedCodemodCommand
.. autoclass:: libcst.codemod.MagicArgsCodemodCommand
:exclude-members: transform_module_impl
--------------------
Command-Line Toolkit
--------------------
Several helpers for constructing a command-line interface are provided. These are used
in the ``codemod`` utility to provide LibCST's de-facto command-line interface but they
are also available to be used directly in the case that circumstances demand a custom
command-line tool.
.. autofunction:: libcst.codemod.gather_files
.. autofunction:: libcst.codemod.exec_transform_with_prettyprint
.. autofunction:: libcst.codemod.parallel_exec_transform_with_prettyprint
.. autoclass:: libcst.codemod.ParallelTransformResult
.. autofunction:: libcst.codemod.diff_code
---------------------
Library of Transforms
---------------------
LibCST additionally includes a library of transforms to reduce the need for boilerplate
inside codemods. As of now, the list includes the following helpers.
.. autoclass:: libcst.codemod.visitors.GatherImportsVisitor
:no-undoc-members:
.. autoclass:: libcst.codemod.visitors.GatherExportsVisitor
:no-undoc-members:
.. autoclass:: libcst.codemod.visitors.AddImportsVisitor
:no-undoc-members:
.. autoclass:: libcst.codemod.visitors.RemoveImportsVisitor
:no-undoc-members:
.. autoclass:: libcst.codemod.visitors.ApplyTypeAnnotationsVisitor
:no-undoc-members:
.. autoclass:: libcst.codemod.visitors.GatherUnusedImportsVisitor
:no-undoc-members:
.. autoclass:: libcst.codemod.visitors.GatherCommentsVisitor
:no-undoc-members:
.. autoclass:: libcst.codemod.visitors.GatherNamesFromStringAnnotationsVisitor
:no-undoc-members:
|