Skip to content

Commit

Permalink
Restricted max line length 100 characters
Browse files Browse the repository at this point in the history
  • Loading branch information
ferraith committed Jul 27, 2018
1 parent 81c4d06 commit c49d0c4
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 45 deletions.
5 changes: 4 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ directory = coverage_report
format = pylint
statistics = True
show-source = True
max-line-length = 120
max-line-length = 100
max-complexity = 10
import-order-style = pep8

[pep8]
ignore = E501
51 changes: 30 additions & 21 deletions setuptools_antlr/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ class AntlrCommand(setuptools.Command):
"""A setuptools command for generating ANTLR based parsers.
An extra command for setuptools to generate ANTLR based parsers, lexers, listeners and visitors.
The antlr command wraps the Java based generator provided by ANTLR developers. It
searches for all grammar files and generates a Python package containing a modules specified in
the user options. Please keep in mind that only grammars are generated which aren't included by
other grammars. This prevents generation of shared content like common terminals.
The antlr command wraps the Java based generator provided by ANTLR developers. It searches for
all grammar files and generates a Python package containing a modules specified in the user
options. Please keep in mind that only grammars are generated which aren't included by other
grammars. This prevents generation of shared content like common terminals.
:cvar _MIN_JAVA_VERSION: Minimal version of java required by ANTLR
:cvar _EXT_LIB_DIR: Relative path to external libs directory
Expand Down Expand Up @@ -129,8 +129,9 @@ class AntlrCommand(setuptools.Command):
('x-log', None, 'dump lots of logging info to antlr-<timestamp>.log')
]

boolean_options = ['atn', 'long-messages', 'listener', 'no-listener', 'visitor', 'no-visitor', 'depend', 'w-error',
'x-dbg-st', 'x-dbg-st-wait', 'x-exact-output-dir', 'x-force-atn', 'x-log']
boolean_options = ['atn', 'long-messages', 'listener', 'no-listener', 'visitor', 'no-visitor',
'depend', 'w-error', 'x-dbg-st', 'x-dbg-st-wait', 'x-exact-output-dir',
'x-force-atn', 'x-log']

negative_opt = {'no-listener': 'listener', 'no-visitor': 'visitor'}

Expand Down Expand Up @@ -181,16 +182,17 @@ def finalize_options(self):
# sanity check in case target language is explicitly passed by user
if 'language' in self.grammar_options:
if self.grammar_options['language'] != 'Python3':
raise distutils.errors.DistutilsOptionError('{} isn\'t a supported language. Only Python3 code can be '
'generated.'.format(self.grammar_options['language']))
raise distutils.errors.DistutilsOptionError('{} isn\'t a supported language. Only '
'Python3 code can be generated.'.format(
self.grammar_options['language']))
else:
self.grammar_options['language'] = 'Python3'

# sanity check for debugging options
if not self.x_dbg_st and self.x_dbg_st_wait:
distutils.log.warn('Waiting for StringTemplate visualizer (x_dbg_st_wait) without launching it on '
'generated code is enabled (x_dbg_st). Launching of StringTemplate visualizer will be '
'forced.')
distutils.log.warn('Waiting for StringTemplate visualizer (x_dbg_st_wait) without '
'launching it on generated code is enabled (x_dbg_st). Launching of '
'StringTemplate visualizer will be forced.')
self.x_dbg_st = 1

def _find_antlr(self) -> pathlib.Path:
Expand Down Expand Up @@ -279,8 +281,9 @@ def get_grammar(name: str) -> AntlrGrammar:
e.parent = grammar
raise
except ImportGrammarError as e:
raise distutils.errors.DistutilsFileError('Imported grammar "{}" in file "{}" isn\'t present in package '
'source directory.'.format(str(e), str(e.parent.path)))
raise distutils.errors.DistutilsFileError('Imported grammar "{}" in file "{}" isn\'t '
'present in package source directory.'.format(
str(e), str(e.parent.path)))
else:
# remove all grammars which aren't the root of a dependency tree
grammar_tree[:] = filter(lambda r: all(r not in g.dependencies for g in grammars),
Expand Down Expand Up @@ -336,7 +339,8 @@ def run(self):
run_args.append('-visitor' if self.visitor else '-no-visitor')
if self.depend:
run_args.append('-depend')
run_args.extend(['-D{}={}'.format(option, value) for option, value in self.grammar_options.items()])
run_args.extend(['-D{}={}'.format(option, value) for option, value in
self.grammar_options.items()])
if self.w_error:
run_args.append('-Werror')
if self.x_dbg_st:
Expand All @@ -355,9 +359,10 @@ def run(self):
if len(dependency_dirs) == 1:
run_args.extend(['-lib', str(dependency_dirs.pop().absolute())])
elif len(dependency_dirs) > 1:
raise distutils.errors.DistutilsOptionError('Imported grammars of \'{}\' are located in more than one '
'directory. This isn\'t supported by ANTLR. Move all '
'imported grammars into one'
raise distutils.errors.DistutilsOptionError('Imported grammars of \'{}\' are '
'located in more than one directory. '
'This isn\'t supported by ANTLR. Move '
'all imported grammars into one '
'directory.'.format(grammar.name))

# build up package path
Expand All @@ -369,7 +374,8 @@ def run(self):
if self.x_exact_output_dir:
package_dir = pathlib.Path(output_dir)
else:
package_dir = pathlib.Path(output_dir, grammar_dir, camel_to_snake_case(grammar.name))
package_dir = pathlib.Path(output_dir, grammar_dir,
camel_to_snake_case(grammar.name))

# create package directory
package_dir.mkdir(parents=True, exist_ok=True)
Expand All @@ -380,7 +386,8 @@ def run(self):

if self.depend:
dependency_file = pathlib.Path(package_dir, 'dependencies.txt')
distutils.log.info('generating {} file dependencies -> {}'.format(grammar_file, dependency_file))
distutils.log.info('generating {} file dependencies -> {}'.format(grammar_file,
dependency_file))

# call ANTLR for file dependency generation
result = subprocess.run(run_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
Expand All @@ -405,14 +412,16 @@ def run(self):
universal_newlines=True, cwd=str(grammar_dir))
if result.returncode:
raise distutils.errors.DistutilsExecError('{} parser couldn\'t be generated\n'
'{}'.format(grammar.name, result.stdout))
'{}'.format(grammar.name,
result.stdout))

# move logging info into build directory
if self.x_log:
antlr_log_file = self._find_antlr_log(grammar_dir)
if antlr_log_file:
package_log_file = pathlib.Path(package_dir, antlr_log_file.name)
distutils.log.info('dumping logging info of {} -> {}'.format(grammar_file, package_log_file))
distutils.log.info('dumping logging info of {} -> {}'.format(grammar_file,
package_log_file))
shutil.move(str(antlr_log_file), str(package_log_file))
else:
distutils.log.warn('no logging info dumped out by ANTLR')
10 changes: 6 additions & 4 deletions setuptools_antlr/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ def camel_to_snake_case(s):
:param s: a camel cased string
:return: a snake cased string
"""
snake_cased = re.sub('([a-z0-9])([A-Z])', r'\1_\2', re.sub('(.)([A-Z][a-z]+)', r'\1_\2', s)).lower()
snake_cased = re.sub('([a-z0-9])([A-Z])', r'\1_\2', re.sub('(.)([A-Z][a-z]+)', r'\1_\2',
s)).lower()
return snake_cased.replace('__', '_')


Expand All @@ -24,16 +25,17 @@ def validate_java(executable: str, min_java_version: str) -> bool:
:param min_java_version: minimum acceptable version of Java
:return: flag whether JRE is at minimum required version
"""
result = subprocess.run([executable, '-version'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
universal_newlines=True)
result = subprocess.run([executable, '-version'], stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, universal_newlines=True)

if result.returncode == 0:
version_regex = re.compile('"([1-9]\d*(?:(\.0)|(\.[1-9]\d*))*(?:_\d+)?)"')
version_match = version_regex.search(result.stdout)

if version_match:
# create normalized versions containing only valid chars
validated_version = distutils.version.LooseVersion(version_match.group(1).replace('_', '.'))
validated_version = distutils.version.LooseVersion(version_match.group(1).
replace('_', '.'))
min_version = distutils.version.LooseVersion(min_java_version.replace('_', '.'))

return validated_version >= min_version
Expand Down
41 changes: 24 additions & 17 deletions test/test_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,16 @@ def command(self):

@pytest.fixture()
def configured_command(self, monkeypatch, tmpdir, command):
command._find_antlr = unittest.mock.Mock(return_value=pathlib.Path('antlr-4.5.3-complete.jar'))
command._find_antlr = unittest.mock.Mock(return_value=pathlib.Path(
'antlr-4.5.3-complete.jar'))
command._find_grammars = unittest.mock.Mock(return_value=[
AntlrGrammar(pathlib.Path('standalone/SomeGrammar.g4'))
])
command.output['default'] = str(tmpdir.mkdir('gen'))

monkeypatch.setattr(setuptools_antlr.command, 'find_java',
unittest.mock.Mock(return_value=pathlib.Path('c:/path/to/java/bin/java.exe')))
unittest.mock.Mock(return_value=pathlib.Path(
'c:/path/to/java/bin/java.exe')))

return command

Expand All @@ -88,14 +90,15 @@ def test_find_antlr(self, tmpdir, command, available_antlr_jars, expected_antlr_
with unittest.mock.patch.object(AntlrCommand, '_EXT_LIB_DIR', str(ext_lib_dir)):
found_antlr_jar = command._find_antlr()

assert found_antlr_jar == (pathlib.Path(str(ext_lib_dir), expected_antlr_jar) if expected_antlr_jar
else None)
assert found_antlr_jar == (pathlib.Path(str(ext_lib_dir), expected_antlr_jar)
if expected_antlr_jar else None)

test_ids_find_antlr_log = ['single', 'multiple', 'none', 'invalid']

test_data_find_antlr_log = [
({'antlr-2016-12-19-16.01.43.log'}, 'antlr-2016-12-19-16.01.43.log'),
({'antlr-2016-12-18-16.01.43.log', 'antlr-2016-12-19-16.01.43.log'}, 'antlr-2016-12-19-16.01.43.log'),
({'antlr-2016-12-18-16.01.43.log', 'antlr-2016-12-19-16.01.43.log'},
'antlr-2016-12-19-16.01.43.log'),
({}, None),
({'foobar-2016-12-19-16.01.43.log'}, None)
]
Expand All @@ -111,8 +114,8 @@ def test_find_antlr_log(self, tmpdir, command, available_antlr_logs, expected_an

found_antlr_log = command._find_antlr_log(pathlib.Path(str(package_dir)))

assert found_antlr_log == (pathlib.Path(str(package_dir), expected_antlr_log) if expected_antlr_log
else None)
assert found_antlr_log == (pathlib.Path(str(package_dir), expected_antlr_log)
if expected_antlr_log else None)

def test_find_grammars_empty(self, tmpdir, command):
dsl_dir = tmpdir.mkdir('dsl')
Expand Down Expand Up @@ -280,7 +283,8 @@ def test_run_java_not_found(self, mock_find_java, command):
@unittest.mock.patch.object(AntlrCommand, '_find_antlr')
@unittest.mock.patch('subprocess.run')
@unittest.mock.patch.object(AntlrCommand, '_find_grammars')
def test_run_antlr_found(self, mock_find_grammars, mock_run, mock_find_antlr, mock_find_java, tmpdir, command):
def test_run_antlr_found(self, mock_find_grammars, mock_run, mock_find_antlr, mock_find_java,
tmpdir, command):
java_exe = pathlib.Path('c:/path/to/java/bin/java.exe')
antlr_jar = pathlib.Path('antlr-4.5.3-complete.jar')

Expand Down Expand Up @@ -694,7 +698,8 @@ def test_run_x_force_atn_disabled(self, mock_run, configured_command):
@unittest.mock.patch('subprocess.run')
@unittest.mock.patch.object(AntlrCommand, '_find_antlr_log')
@unittest.mock.patch('shutil.move')
def test_run_x_log_enabled(self, mock_move, mock_find_antlr_log, mock_run, capsys, configured_command):
def test_run_x_log_enabled(self, mock_move, mock_find_antlr_log, mock_run, capsys,
configured_command):
log_file = 'antlr-2016-12-19-16.01.43.log'
mock_run.return_value = unittest.mock.Mock(returncode=0)
mock_find_antlr_log.return_value = pathlib.Path(log_file)
Expand Down Expand Up @@ -760,8 +765,8 @@ def test_run_parser_generation_failed(self, mock_run, configured_command):
@unittest.mock.patch.object(AntlrCommand, '_find_antlr')
@unittest.mock.patch('subprocess.run')
@unittest.mock.patch.object(AntlrCommand, '_find_grammars')
def test_run_package_not_exists(self, mock_find_grammars, mock_run, mock_find_antlr, mock_find_java, tmpdir,
command):
def test_run_package_not_exists(self, mock_find_grammars, mock_run, mock_find_antlr,
mock_find_java, tmpdir, command):
java_exe = pathlib.Path('c:/path/to/java/bin/java.exe')
antlr_jar = pathlib.Path('antlr-4.5.3-complete.jar')
mock_find_java.return_value = java_exe
Expand Down Expand Up @@ -790,7 +795,8 @@ def test_run_package_not_exists(self, mock_find_grammars, mock_run, mock_find_an
@unittest.mock.patch.object(AntlrCommand, '_find_antlr')
@unittest.mock.patch('subprocess.run')
@unittest.mock.patch.object(AntlrCommand, '_find_grammars')
def test_run_package_exists(self, mock_find_grammars, mock_run, mock_find_antlr, mock_find_java, tmpdir, command):
def test_run_package_exists(self, mock_find_grammars, mock_run, mock_find_antlr, mock_find_java,
tmpdir, command):
java_exe = pathlib.Path('c:/path/to/java/bin/java.exe')
antlr_jar = pathlib.Path('antlr-4.5.3-complete.jar')
mock_find_java.return_value = java_exe
Expand Down Expand Up @@ -823,8 +829,8 @@ def test_run_package_exists(self, mock_find_grammars, mock_run, mock_find_antlr,
@unittest.mock.patch.object(AntlrCommand, '_find_antlr')
@unittest.mock.patch('subprocess.run')
@unittest.mock.patch.object(AntlrCommand, '_find_grammars')
def test_run_one_library_location(self, mock_find_grammars, mock_run, mock_find_antlr, mock_find_java, tmpdir,
command):
def test_run_one_library_location(self, mock_find_grammars, mock_run, mock_find_antlr,
mock_find_java, tmpdir, command):
java_exe = pathlib.Path('c:/path/to/java/bin/java.exe')
antlr_jar = pathlib.Path('antlr-4.5.3-complete.jar')
mock_find_java.return_value = java_exe
Expand All @@ -849,8 +855,8 @@ def test_run_one_library_location(self, mock_find_grammars, mock_run, mock_find_
@unittest.mock.patch.object(AntlrCommand, '_find_antlr')
@unittest.mock.patch('subprocess.run')
@unittest.mock.patch.object(AntlrCommand, '_find_grammars')
def test_run_multiple_library_location(self, mock_find_grammars, mock_run, mock_find_antlr, mock_find_java, tmpdir,
command):
def test_run_multiple_library_location(self, mock_find_grammars, mock_run, mock_find_antlr,
mock_find_java, tmpdir, command):
java_exe = pathlib.Path('c:/path/to/java/bin/java.exe')
antlr_jar = pathlib.Path('antlr-4.5.3-complete.jar')
mock_find_java.return_value = java_exe
Expand All @@ -868,4 +874,5 @@ def test_run_multiple_library_location(self, mock_find_grammars, mock_run, mock_

with pytest.raises(distutils.errors.DistutilsOptionError) as excinfo:
command.run()
assert excinfo.match('Imported grammars of \'SomeGrammar\' are located in more than one directory.')
assert excinfo.match('Imported grammars of \'SomeGrammar\' are located in more than one '
'directory.')
5 changes: 3 additions & 2 deletions test/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ def test_find_java_on_path(mock_validate_java, mock_which):
assert java_path is not None


test_ids_validate_java = ['valid_current_schema_1', 'valid_current_schema_2', 'valid_legacy_schema_1',
'valid_legacy_schema_2', 'invalid', 'deprecated', 'corrupt']
test_ids_validate_java = ['valid_current_schema_1', 'valid_current_schema_2',
'valid_legacy_schema_1', 'valid_legacy_schema_2', 'invalid', 'deprecated',
'corrupt']

test_data_validate_java = [
(subprocess.CompletedProcess(['java.exe', '-version'], 0, stdout="""
Expand Down

0 comments on commit c49d0c4

Please sign in to comment.