Skip to content
This repository has been archived by the owner on Apr 22, 2021. It is now read-only.

Commit

Permalink
Merge pull request #41 from ajm188/allow-pattern-to-be-module
Browse files Browse the repository at this point in the history
Allow pattern to be module
  • Loading branch information
ajm188 committed Aug 30, 2016
2 parents 0e8257f + 7042f80 commit 916d504
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 5 deletions.
2 changes: 1 addition & 1 deletion docs/source/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Read it
optional arguments:
-h, --help show this help message and exit
--pattern PATH, -p PATH
paths to pattern definition files
paths to pattern definition files or modules
--verbose, -v
--dry-run, -d only print to stdout; do not overwrite files
Expand Down
10 changes: 10 additions & 0 deletions tests/cmd/main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,16 @@ def test_single_file():
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"]
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"]
with mock.patch("sys.argv", args):
Expand Down
30 changes: 30 additions & 0 deletions tests/pattern/interface_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@
from __future__ import print_function

import mock
import pytest

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.python import HEADER


def test_get_patterns_module_with_patterns():
Expand All @@ -32,3 +38,27 @@ def test_get_patterns_module_bad_format(mock_exit, mock_log):

assert mock_log.call_count == 1
mock_exit.assert_called_once_with(1)


def test_get_patterns():
# patterns = [[(grammar, replace), (HEADER, extra_replace)]]
patterns = get_patterns(attribute_to_function)
[patternset] = patterns
[pattern1, pattern2] = patternset
(grammar1, replace1) = pattern1
(grammar2, replace2) = pattern2
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')
2 changes: 1 addition & 1 deletion undebt/cmd/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def _handle_arguments():
)
parser.add_argument(
'--pattern', '-p', metavar='PATH', action='append', required=True,
help='paths to pattern definition files',
help='paths to pattern definition files or modules',
)
parser.add_argument(
'--verbose', '-v', action='store_true', default=False,
Expand Down
19 changes: 16 additions & 3 deletions undebt/pattern/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from __future__ import division
from __future__ import print_function

import imp
import os
import os.path
import sys

from pyparsing import _trim_arity
Expand Down Expand Up @@ -74,8 +74,21 @@ def patterns_from_files(pattern_files):

def load_module(path):
"""Loads a module from its path."""
pattern_name = os.path.splitext(os.path.basename(path))[0]
return imp.load_source(pattern_name, 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 create_find_and_replace(grammar, replace):
Expand Down

0 comments on commit 916d504

Please sign in to comment.