From 023ef9aaf0fa078018d810694060f7befec596b2 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Fri, 2 Sep 2016 19:24:12 -0700 Subject: [PATCH 1/4] Removes support for path-like patterns --- tests/cmd/main_test.py | 37 ++++++++++++++++++++++++--------- tests/pattern/interface_test.py | 10 --------- undebt/cmd/main.py | 12 +++++------ undebt/pattern/interface.py | 26 +++++------------------ 4 files changed, 38 insertions(+), 47 deletions(-) diff --git a/tests/cmd/main_test.py b/tests/cmd/main_test.py index fe52b21..5b3ad9c 100644 --- a/tests/cmd/main_test.py +++ b/tests/cmd/main_test.py @@ -7,17 +7,18 @@ import mock +import undebt.examples.method_to_function from undebt.cmd.main import _exit_fail_upon_error from undebt.cmd.main import _load_text from undebt.cmd.main import _process_file from undebt.cmd.main import _write_result_text from undebt.cmd.main import main -from undebt.examples import method_to_function -tests_inputs_directory = os.path.join(os.path.dirname(os.path.dirname(__file__)), "inputs") +method_to_function = undebt.examples.method_to_function + -method_to_function_path = os.path.splitext(method_to_function.__file__)[0] + ".py" +tests_inputs_directory = os.path.join(os.path.dirname(os.path.dirname(__file__)), "inputs") method_to_function_input_path = os.path.join(tests_inputs_directory, "method_to_function_input.txt") with open(method_to_function_input_path, "r") as f: @@ -109,31 +110,47 @@ def test_process_file_raises_exception(mock_process, mock_load_text): @mock.patch('undebt.cmd.main._file_processor') def test_no_file(mock_file_processor): - args = ['undebt', '-p', method_to_function_path] + args = ['undebt', '-p', method_to_function.__name__] with mock.patch('sys.argv', args): main() mock_file_processor().assert_called_once_with(None) def test_single_file(): - args = ["undebt", "-p", method_to_function_path, method_to_function_input_path, "--verbose"] + args = [ + "undebt", + "-p", + method_to_function.__name__, + method_to_function_input_path, + "--verbose", + ] with mock.patch("sys.argv", args): main() assert _read_input_file() == method_to_function_output_contents == _read_output_file() def test_loading_pattern_with_module_name(): - # Need full module name here - import undebt.examples.method_to_function - module_name = undebt.examples.method_to_function.__name__ - args = ["undebt", "-p", module_name, method_to_function_input_path, "--verbose"] + args = [ + "undebt", + "-p", + method_to_function.__name__, + method_to_function_input_path, + "--verbose", + ] with mock.patch("sys.argv", args): main() assert _read_input_file() == method_to_function_output_contents == _read_output_file() def test_dry_run(capsys): - args = ["undebt", "-p", method_to_function_path, "--dry-run", method_to_function_input_path, "--verbose"] + args = [ + "undebt", + "-p", + method_to_function.__name__, + "--dry-run", + method_to_function_input_path, + "--verbose", + ] with mock.patch("sys.argv", args): main() out, err = capsys.readouterr() diff --git a/tests/pattern/interface_test.py b/tests/pattern/interface_test.py index ef503b7..7146960 100644 --- a/tests/pattern/interface_test.py +++ b/tests/pattern/interface_test.py @@ -9,7 +9,6 @@ from undebt.examples import attribute_to_function from undebt.pattern.interface import get_patterns from undebt.pattern.interface import load_module -from undebt.pattern.interface import maybe_path_to_module_name from undebt.pattern.interface import _get_patterns from undebt.pattern.lang.python import HEADER @@ -50,15 +49,6 @@ def test_get_patterns(): assert grammar2 is HEADER -def test_maybe_path_to_module_name(): - assert 'foo.bar' == maybe_path_to_module_name('foo.bar') - assert 'foo.bar' == maybe_path_to_module_name('foo/bar.py') - assert 'foo.bar' == maybe_path_to_module_name('foo/bar') - - with pytest.raises(ValueError): - maybe_path_to_module_name('../relative/path.py') - - def test_load_module_on_non_existant(): with pytest.raises(ImportError): load_module('foo.bar.baz') diff --git a/undebt/cmd/main.py b/undebt/cmd/main.py index a82bd41..2ca6494 100644 --- a/undebt/cmd/main.py +++ b/undebt/cmd/main.py @@ -10,7 +10,7 @@ from undebt.cmd import logger from undebt.cmd.logger import log from undebt.cmd.logic import process -from undebt.pattern.interface import patterns_from_files +from undebt.pattern.interface import patterns_from_modules def _exit_fail_upon_error(func): @@ -58,8 +58,8 @@ def _handle_arguments(): help='files to be modified; uses stdin if not passed', ) parser.add_argument( - '--pattern', '-p', metavar='PATH', action='append', required=True, - help='paths to pattern definition files or modules', + '--pattern', '-p', metavar='MODULE', action='append', required=True, + help='pattern definition modules', ) parser.add_argument( '--verbose', '-v', action='store_true', default=False, @@ -91,13 +91,13 @@ def _process_file(patterns, text_file, dry_run): class _file_processor(object): """Must be a class so it is pickleable.""" - def __init__(self, pattern_files, dry_run): - self.pattern_files = pattern_files + def __init__(self, pattern_modules, dry_run): + self.pattern_modules = pattern_modules self.dry_run = dry_run @_exit_fail_upon_error def patterns(self): - return patterns_from_files(self.pattern_files) + return patterns_from_modules(self.pattern_modules) def __call__(self, text_file): return _process_file(self.patterns(), text_file, self.dry_run) diff --git a/undebt/pattern/interface.py b/undebt/pattern/interface.py index 38c3ef9..d5a2fbb 100644 --- a/undebt/pattern/interface.py +++ b/undebt/pattern/interface.py @@ -3,8 +3,6 @@ from __future__ import division from __future__ import print_function -import os -import os.path import sys from pyparsing import _trim_arity @@ -67,28 +65,14 @@ def extra_replace(tokens): return HEADER, extra_replace -def patterns_from_files(pattern_files): +def patterns_from_modules(pattern_modules): """Returns patterns for pattern files.""" - return get_patterns(*(load_module(pattern_file) for pattern_file in pattern_files)) + return get_patterns(*(load_module(pattern_module) for pattern_module in pattern_modules)) -def load_module(path): - """Loads a module from its path.""" - return __import__(maybe_path_to_module_name(path), fromlist=['']) - - -def maybe_path_to_module_name(maybe_path): - relpath = os.path.relpath(maybe_path) - if relpath.startswith('..'): - raise ValueError( - "Relative file paths not allowed: {}".format(relpath), - ) - name = relpath.replace(os.sep, '.') - name_parts = name.split('.') - if name_parts[-1] == 'py': - name_parts = name_parts[:-1] - - return '.'.join(name_parts) +def load_module(module): + """Loads a module from its name.""" + return __import__(module, fromlist=['']) def create_find_and_replace(grammar, replace): From e0cd2484b92ed7312955006f1950474734c2ba69 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Fri, 2 Sep 2016 19:26:04 -0700 Subject: [PATCH 2/4] Updates docs to latest CLI --- docs/source/cli.rst | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/docs/source/cli.rst b/docs/source/cli.rst index 1fc690b..a1ae251 100644 --- a/docs/source/cli.rst +++ b/docs/source/cli.rst @@ -19,28 +19,27 @@ Read it .. code-block:: bash $ undebt --help - usage: undebt [-h] --pattern PATH [--verbose] [--dry-run] + usage: undebt [-h] --pattern MODULE [--verbose] [--dry-run] [FILE [FILE...]] positional arguments: FILE [FILE...] - paths to files or directories (searched recursively - for extension) to be modified (if not passed uses + paths to files to be modified (if not passed uses stdin) optional arguments: - -h, --help show this help message and exit - --pattern PATH, -p PATH - paths to pattern definition files or modules + -h, --help show this help message and exit + --pattern MODULE, -p MODULE + pattern definition modules --verbose, -v - --dry-run, -d only print to stdout; do not overwrite files + --dry-run, -d only print to stdout; do not overwrite files Try it out ---------- .. code-block:: bash - $ undebt -p ./undebt/examples/method_to_function.py ./tests/inputs/method_to_function_input.txt + $ undebt -p undebt.examples.method_to_function ./tests/inputs/method_to_function_input.txt $ git diff diff --git a/tests/inputs/method_to_function_input.txt b/tests/inputs/method_to_function_input.txt index f268ab9..7681c63 100644 @@ -87,17 +86,17 @@ Using with ``grep``/``git grep`` to find files .. code-block:: bash - grep -l **/*.css | xargs undebt -p + grep -l **/*.css | xargs undebt -p # Use git grep if you only want to search tracked files - git grep -l | xargs undebt -p + git grep -l | xargs undebt -p Using ``find`` to limit to a particular extension ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: bash - find -name '*.js' | xargs grep -l | xargs undebt -p + find -name '*.js' | xargs grep -l | xargs undebt -p Using ``xargs`` to work in parallel ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -107,4 +106,4 @@ to use. .. code-block:: bash - git grep -l | xargs -P undebt -p + git grep -l | xargs -P undebt -p From 88279df82a3e57e37b39a58ddff7516c8d963824 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Fri, 2 Sep 2016 19:26:49 -0700 Subject: [PATCH 3/4] Bumps version --- undebt/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/undebt/__init__.py b/undebt/__init__.py index d6cc80e..e7dbcf1 100644 --- a/undebt/__init__.py +++ b/undebt/__init__.py @@ -6,4 +6,4 @@ # this should be the only place where the version is kept, if you # need to know the version somewhere else just import it from here -__version__ = "0.5.0" +__version__ = "0.6.0" From 3b72259c2e0e9148bf99e2be194896b7ef991c11 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Wed, 7 Sep 2016 15:02:20 -0700 Subject: [PATCH 4/4] Directly imports the method_to_function pattern module --- tests/cmd/main_test.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/cmd/main_test.py b/tests/cmd/main_test.py index 5b3ad9c..95d2406 100644 --- a/tests/cmd/main_test.py +++ b/tests/cmd/main_test.py @@ -7,15 +7,12 @@ import mock -import undebt.examples.method_to_function from undebt.cmd.main import _exit_fail_upon_error from undebt.cmd.main import _load_text from undebt.cmd.main import _process_file from undebt.cmd.main import _write_result_text from undebt.cmd.main import main - - -method_to_function = undebt.examples.method_to_function +from undebt.examples import method_to_function tests_inputs_directory = os.path.join(os.path.dirname(os.path.dirname(__file__)), "inputs")