Source code for varats.experiments.szz.pydriller_szz_experiment

"""Implements the SZZUnleashed experiment."""

import typing as tp

import yaml
from benchbuild import Project, source
from benchbuild.experiment import ProjectT
from benchbuild.utils import actions
from pygit2 import Commit

from varats.base.version_header import VersionHeader
from varats.data.reports.szz_report import PyDrillerSZZReport, SZZTool
from varats.experiment.experiment_util import (
    get_varats_result_folder,
    VersionExperiment,
)
from varats.project.varats_project import VProject
from varats.provider.bug.bug_provider import BugProvider
from varats.report.report import FileStatusExtension as FSE
from varats.report.report import ReportSpecification


[docs] class CreatePyDrillerSZZReport(actions.ProjectStep): # type: ignore """ Create a SZZReport from the data collected by the. :class:`~varats.provider.bug.bug_provider.BugProvider`. """ NAME = "CreatePyDrillerSZZReport" DESCRIPTION = "Create a report from SZZ data" project: VProject def __init__(self, project: Project): super().__init__(project=project) def __call__(self) -> actions.StepResult: return self.create_report()
[docs] def create_report(self) -> actions.StepResult: """Create a report from SZZ data.""" bug_provider = BugProvider.get_provider_for_project(self.project) pygit_bugs = bug_provider.find_pygit_bugs() varats_result_folder = get_varats_result_folder(self.project) def commit_to_hash(commit: Commit) -> str: return str(commit.id) bugs: tp.Dict[str, tp.List[str]] = {} # entries are lists of the form [<fix>, <introducing>] for bug in pygit_bugs: bugs[commit_to_hash(bug.fixing_commit)] = sorted([ commit_to_hash(commit) for commit in bug.introducing_commits ]) raw_szz_report = { "szz_tool": SZZTool.PYDRILLER_SZZ.tool_name, "bugs": bugs } result_file = PyDrillerSZZReport.get_file_name( "PyDrSZZ", project_name=str(self.project.name), binary_name="none", # we don't rely on binaries in this experiment project_revision=self.project.version_of_primary, project_uuid=str(self.project.run_uuid), extension_type=FSE.SUCCESS ) with open(f"{varats_result_folder}/{result_file}", "w") as yaml_file: yaml_file.write( yaml.dump_all([ VersionHeader.from_version_number("SZZReport", 1).get_dict(), raw_szz_report ], explicit_start=True, explicit_end=True) ) return actions.StepResult.OK
[docs] class PyDrillerSZZExperiment(VersionExperiment, shorthand="PyDrillerSZZ"): """ Generates a PyDrillerSZZ report. This experiment should be run only on one (preferably the newest) revision of a project. """ NAME = "PyDrillerSZZ" REPORT_SPEC = ReportSpecification(PyDrillerSZZReport)
[docs] @classmethod def sample(cls, prj_cls: ProjectT) -> tp.List[source.Revision]: variants = list(source.enumerate_revisions(prj_cls)) return [variants[0]]
[docs] def actions_for_project(self, project: Project) -> tp.List[actions.Step]: """Returns the specified steps to run the project(s) specified in the call in a fixed order.""" analysis_actions = [ CreatePyDrillerSZZReport(project), actions.Clean(project) ] return analysis_actions