def create_configuration_file(project_directory: Path, configuration_file_name: str): root = ET.Element("module") root.set("name", "Checker") module_JavadocPackage = ET.SubElement(root, "module") module_JavadocPackage.set("name", "JavadocPackage") module_TreeWalker = ET.SubElement(root, "module") module_TreeWalker.set("name", "TreeWalker") # Metrics modules modules = [ "BooleanExpressionComplexity", "ClassDataAbstractionCoupling", "ClassFanOutComplexity", "CyclomaticComplexity", "JavaNCSS", "NPathComplexity", ] for module in modules: elem = ET.SubElement(module_TreeWalker, "module") elem.set("name", module) xml_str = minidom.parseString(ET.tostring(root)).toprettyxml(indent=" ") configuration_file = open(project_directory / configuration_file_name, "w+") configuration_file.write( "<!DOCTYPE module PUBLIC \"-//Puppy Crawl//DTD Check Configuration 1.3//EN\" " "\"http://www.puppycrawl.com/dtds/configuration_1_3.dtd\">" ) configuration_file.write(xml_str.split("\n", 1)[1]) configuration_file.close()
def add_checkstyle_plugin(pom: Path, target: Path, configuration_file_name: str): pom = ET.parse(pom) root = pom.getroot() plugins_element = pom.find("./pom:reporting/pom:plugins", POM_NSMAP) # Create reporting/plugins node if nonexistent if plugins_element is None: reporting_element = ET.SubElement(root, "reporting") plugins_element = ET.SubElement(reporting_element, "plugins") plugins_element.append(checkstyle_plugin_element(configuration_file_name)) indent(pom, space=" " * 4) pom.write(target)
def pitest_plugin_element(class_to_mutate, test_to_run, mutator='ALL', threads=4) -> ET.Element: plugin = ET.Element('plugin') plugin_elements = { "groupId": "org.pitest", "artifactId": "pitest-maven", "version": PIT_VERSION, "configuration": { "failWhenNoMutations": "false", "targetClasses": dict(param=class_to_mutate), "targetTests": dict(param=test_to_run), "mutators": dict(mutator=mutator), "threads": threads, "avoidCallsTo": [ dict(avoidCallsTo="java.util.logging"), dict(avoidCallsTo="org.apache.log4j"), dict(avoidCallsTo="org.slf4j"), dict(avoidCallsTo="org.apache.commons.logging"), ], }, } return obj_to_xml(plugin, plugin_elements)
def checkstyle_plugin_element(config_location: str) -> ET.Element: plugin = ET.Element('plugin') plugin_elements = { "groupId": "org.apache.maven.plugins", "artifactId": "maven-checkstyle-plugin", "version": CHECKSTYLE_PLUGIN_VERSION, "configuration": {"configLocation": config_location}, } return obj_to_xml(plugin, plugin_elements)
def add_pitest_plugin(pom: Path, target: Path, *, class_to_mutate: str, test_to_run: str, mutator='ALL'): pom = ET.parse(pom) plugins = pom.find(".//pom:build//pom:plugins", POM_NSMAP) plugins.append(pitest_plugin_element(class_to_mutate, test_to_run, mutator)) indent(pom, space=" " * 4) pom.write(target)
def look_for_tag(poms: List[Path], tag: str, *, children_of: str = None, direct_children_of: str = None) -> Optional[str]: """Return string content of a tag in one of the supplied poms""" for pom in poms: pom = ET.parse(pom).getroot() if children_of: pattern = f".//pom:{children_of}//pom:{tag}" elif direct_children_of: pattern = f".//pom:{direct_children_of}/pom:{tag}" else: pattern = f".//pom:{tag}" element = pom.find(pattern, POM_NSMAP) if element is not None: return re.sub("[$@*}?].*[$@*}?]", "", element.text) return None
def get_submodules(project_path: Path) -> List[str]: """ Analyzes the structure of the project and detect whether more modules are present Returns: list of submodules """ pom_path = project_path / 'pom.xml' assert pom_path.exists() pom_parsed = ET.parse(pom_path) modules = pom_parsed.find('pom:modules', POM_NSMAP) modules_list = [] if modules: for module in modules.findall('pom:module', POM_NSMAP): detected_module = module.text if 'xml' not in detected_module: modules_list.append(detected_module) logging.info(f'Found {len(modules_list)} module(s):\n', modules_list) return filter_submodule_exceptions(project_path.name, modules_list)
def search_module_tests( project_path: Path, project_name: str, module_path: Path, module_name: str = None, results_dir: Path = SCAN_PROJECT_DIR, ) -> List[CutPair]: """Scan a project and save CUTs with their tests to a file""" pom = module_path / 'pom.xml' if not pom.exists(): return [] if module_name: full_name = f"{project_name}/{module_name}" else: full_name = project_name print(f"* Scanning {full_name}") print(f"* * Found pom: {pom}") tree = ET.parse(pom) root = tree.getroot() include_patterns = [] exclude_patterns = [] surefire_plugin = root.find( ".//pom:plugin/[pom:artifactId='maven-surefire-plugin']", POM_NSMAP) if surefire_plugin is None: if module_path != project_path: print("* * * Couldn't find maven-surefire-plugin in pom") print("* * * Searching parent pom") parent_pom = project_path / 'pom.xml' if parent_pom.exists(): print(f"* * * Found parent pom: {parent_pom}") surefire_plugin = (ET.parse(parent_pom).getroot().find( ".//pom:plugin/[pom:artifactId='maven-surefire-plugin']", POM_NSMAP)) if surefire_plugin is None: print("* * * Couldn't find maven-surefire-plugin in any pom") else: print("* * maven-surefire-plugin found") includes = surefire_plugin.findall('.//pom:include', POM_NSMAP) for include in includes: include_patterns.append(include.text) excludes = surefire_plugin.findall('.//pom:exclude', POM_NSMAP) for exclude in excludes: exclude_patterns.append(exclude.text) DEFAULT_INCLUDES = [ "**/*Test.java", "**/Test*.java", "**/*Tests.java", "**/*TestCase.java", ] print("* * Found include patterns:", include_patterns) if not include_patterns: include_patterns = DEFAULT_INCLUDES else: for i in reversed(range(len(include_patterns))): pat = include_patterns[i] if pat.endswith("AllTests.java"): # TODO: parse AllTests.java print("* * * AllTests.java file found in includes!") if len(include_patterns) == 1: include_patterns = DEFAULT_INCLUDES break else: del include_patterns[i] include_patterns = list(set(include_patterns)) print("* * Adjusted include patterns:", include_patterns) source_directory, test_source_directory = get_source_directories( module_path, project_name, module_name, ) module = PomModule(project_name, module_name, include_patterns, exclude_patterns) # special case for guava if project_name == 'guava' and not module_path.endswith('gwt'): tests_path = module_path.parent / test_source_directory else: tests_path = module_path / test_source_directory main_path = module_path / source_directory print("* * Main path:", main_path) print("* * Tests path:", tests_path) # TODO: remove duplicate test entries test_pairs = list(module.find_cut_pairs(tests_path, main_path)) print(f"* * - {full_name}: Found {len(test_pairs)} class-test pairs") cut_pairs_to_csv(test_pairs, module_path, module, results_dir) # TODO: move to separate file pairs_to_tsdetect_csv(test_pairs, project_name, results_dir) tsdetect_analyze_project(project_name, input_dir=results_dir) merge_tsdetect_files() return test_pairs