def test_find_java_invalid_java_home(mock_which): with unittest.mock.patch.dict('os.environ', {'JAVA_HOME': 'c:/path/to/java'}): mock_which.return_value = None java_path = find_java('1.7.0') assert java_path is None
def test_find_java_no_java_home(mock_which): with unittest.mock.patch.dict('os.environ'): del os.environ['JAVA_HOME'] mock_which.return_value = None java_path = find_java('1.7.0') assert java_path is None
def test_find_java_valid_java_home(mock_validate_java, mock_which): with unittest.mock.patch.dict('os.environ', {'JAVA_HOME': 'c:/path/to/java'}): mock_which.return_value = 'c:/path/to/java/bin/java.exe' mock_validate_java.return_value = True java_path = find_java('1.7.0') assert java_path == pathlib.Path('c:/path/to/java/bin/java.exe')
def test_find_java_on_path(mock_validate_java, mock_which): with unittest.mock.patch.dict('os.environ'): del os.environ['JAVA_HOME'] mock_which.return_value = 'c:/path/to/java/bin/java.exe' mock_validate_java.return_value = True java_path = find_java('1.7.0') assert java_path is not None
def run(self): """Performs all tasks necessary to generate ANTLR based parsers for all found grammars. This process is controlled by the user options passed on the command line or set internally to default values. """ java_exe = find_java(self._MIN_JAVA_VERSION) if not java_exe: raise distutils.errors.DistutilsExecError('no compatible JRE was found on the system') antlr_jar = self._find_antlr() if not antlr_jar: raise distutils.errors.DistutilsExecError('no ANTLR jar was found in lib directory') # find grammars and filter result if grammars are passed by user grammars = self._find_grammars() if self.grammars: grammars = filter(lambda g: g.name in self.grammars, grammars) # generate parser for each grammar for grammar in grammars: # build up ANTLR command line run_args = [str(java_exe), '-jar', str(antlr_jar)] if self.atn: run_args.append('-atn') if self.encoding: run_args.extend(['-encoding', self.encoding]) if self.message_format: run_args.extend(['-message-format', self.message_format]) if self.long_messages: run_args.append('-long-messages') run_args.append('-listener' if self.listener else '-no-listener') 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()]) if self.w_error: run_args.append('-Werror') if self.x_dbg_st: run_args.append('-XdbgST') if self.x_dbg_st_wait: run_args.append('-XdbgSTWait') if self.x_exact_output_dir: run_args.append('-Xexact-output-dir') if self.x_force_atn: run_args.append('-Xforce-atn') if self.x_log: run_args.append('-Xlog') # determine location of dependencies e.g. imported grammars and token files dependency_dirs = set(g.path.parent for g in grammar.walk()) 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' 'directory.'.format(grammar.name)) # build up package path grammar_dir = grammar.path.parent if grammar.name in self.output: output_dir = self.output[grammar.name] else: output_dir = self.output['default'] 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)) # create package directory package_dir.mkdir(parents=True, exist_ok=True) run_args.extend(['-o', str(package_dir.absolute())]) grammar_file = grammar.path.name run_args.append(str(grammar_file)) if self.depend: dependency_file = pathlib.Path(package_dir, 'dependencies.txt') 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, universal_newlines=True, cwd=str(grammar_dir)) with dependency_file.open('wt') as f: f.write(result.stdout) else: distutils.log.info('generating {} parser -> {}'.format(grammar.name, package_dir)) # create Python package init_file = pathlib.Path(package_dir, '__init__.py') if not init_file.exists(): init_file.open('wt').close() # call ANTLR for parser generation result = subprocess.run(run_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, 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)) # 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)) shutil.move(str(antlr_log_file), str(package_log_file)) else: distutils.log.warn('no logging info dumped out by ANTLR')
def run(self): """Performs all tasks necessary to generate ANTLR based parsers for all found grammars. This process is controlled by the user options passed on the command line or set internally to default values. """ java_exe = find_java(self._MIN_JAVA_VERSION) if not java_exe: raise distutils.errors.DistutilsExecError('no compatible JRE was found on the system') antlr_jar = self._find_antlr() if not antlr_jar: raise distutils.errors.DistutilsExecError('no ANTLR jar was found in lib directory') # find grammars and filter result if grammars are passed by user grammars = self._find_grammars() if self.grammars: grammars = filter(lambda g: g.name in self.grammars, grammars) # generate parser for each grammar for grammar in grammars: # build up ANTLR command line run_args = [str(java_exe), '-jar', str(antlr_jar)] if self.atn: run_args.append('-atn') if self.encoding: run_args.extend(['-encoding', self.encoding]) if self.message_format: run_args.extend(['-message-format', self.message_format]) if self.long_messages: run_args.append('-long-messages') run_args.append('-listener' if self.listener else '-no-listener') 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()]) if self.w_error: run_args.append('-Werror') if self.x_dbg_st: run_args.append('-XdbgST') if self.x_dbg_st_wait: run_args.append('-XdbgSTWait') if self.x_exact_output_dir: run_args.append('-Xexact-output-dir') if self.x_force_atn: run_args.append('-Xforce-atn') if self.x_log: run_args.append('-Xlog') # determine location of dependencies e.g. imported grammars and token files dependency_dirs = set(g.path.parent for g in grammar.walk()) 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 ' 'directory.'.format(grammar.name)) # build up package path grammar_dir = grammar.path.parent if grammar.name in self.output: output_dir = self.output[grammar.name] else: output_dir = self.output['default'] 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)) # create package directory package_dir.mkdir(parents=True, exist_ok=True) run_args.extend(['-o', str(package_dir.resolve())]) grammar_file = grammar.path.name run_args.append(str(grammar_file)) if self.depend: dependency_file = pathlib.Path(package_dir, 'dependencies.txt') 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, universal_newlines=True, cwd=str(grammar_dir)) with dependency_file.open('wt') as f: f.write(result.stdout) else: distutils.log.info('generating {} parser -> {}'.format(grammar.name, package_dir)) # create Python package if don't exist self._create_init_file(package_dir) # call ANTLR for parser generation result = subprocess.run(run_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, 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)) # 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)) shutil.move(str(antlr_log_file), str(package_log_file)) else: distutils.log.warn('no logging info dumped out by ANTLR')