Beispiel #1
0
        def command_template(context: click.Context, **kwargs: tp.Any) -> None:
            # extract common arguments and plot config from context
            plot_config: PlotConfig = PlotConfig(False)
            try:
                generator_instance = generator_cls(plot_config, **kwargs)
                plots = generator_instance.generate()
                plot = plots[0]
                if len(plots) > 1:

                    def set_plot(selected_plot: Plot) -> None:
                        nonlocal plot
                        plot = selected_plot

                    cli_list_choice(
                        "The given plot generator creates multiple plots"
                        " please select one:", plots, lambda p: p.name,
                        set_plot)
                cmap = create_lazy_commit_map_loader(context.obj['project'],
                                                     None, 'HEAD', None)()
                extend_with_smooth_revs(context.obj['case_study'], cmap,
                                        context.obj['boundary_gradient'],
                                        context.obj['ignore_blocked'], plot,
                                        context.obj['merge_stage'])
                store_case_study(context.obj['case_study'],
                                 context.obj['path'])
            except PlotGeneratorFailed as ex:
                print(f"Failed to create plot generator {generator_cls.NAME}: "
                      f"{ex.message}")
Beispiel #2
0
def __gen_sample(ctx: click.Context, distribution: str, end: str, start: str,
                 num_rev: int, only_code_commits: bool) -> None:
    """
    Add revisions based on a sampling Distribution.

    Distribution: The sampling method to use
    """
    sampling_method: NormalSamplingMethod = NormalSamplingMethod \
        .get_sampling_method_type(
        distribution
    )()

    project_repo_path = get_local_project_git_path(ctx.obj['project'])
    if end != "HEAD" and not is_commit_hash(end):
        end = get_commits_before_timestamp(end, project_repo_path)[0].hash

    if start is not None and not is_commit_hash(start):
        commits_before = get_commits_before_timestamp(start, project_repo_path)
        if commits_before:
            start = commits_before[0].hash
        else:
            start = get_initial_commit(project_repo_path).hash

    cmap = create_lazy_commit_map_loader(ctx.obj['project'], None, end,
                                         start)()
    extend_with_distrib_sampling(ctx.obj['case_study'], cmap, sampling_method,
                                 ctx.obj['merge_stage'], num_rev,
                                 ctx.obj['ignore_blocked'], only_code_commits)
    store_case_study(ctx.obj['case_study'], ctx.obj['path'])
Beispiel #3
0
    def gen(self) -> None:
        """Generate the case study using the selected strategy, project and
        strategy specific arguments."""
        cmap = create_lazy_commit_map_loader(self.selected_project, None,
                                             'HEAD', None)()
        version = self.cs_version.value()
        case_study = CaseStudy(self.revision_list_project, version)
        paper_config = vara_cfg()["paper_config"]["current_config"].value
        path = Path(vara_cfg()["paper_config"]["folder"].value) / (
            paper_config +
            f"/{self.revision_list_project}_{version}.case_study")

        if self.strategie_forms.currentIndex(
        ) == GenerationStrategie.SAMPLE.value:
            sampling_method = NormalSamplingMethod.get_sampling_method_type(
                self.sampling_method.currentText())
            extend_with_distrib_sampling(case_study, cmap, sampling_method(),
                                         0, self.num_revs.value(), True,
                                         self.code_commits.clicked)
        elif self.strategie_forms.currentIndex(
        ) == GenerationStrategie.SELECT_REVISION.value:
            selected_rows = self.revision_list.selectionModel().selectedRows(0)
            selected_commits = [row.data() for row in selected_rows]
            extend_with_extra_revs(case_study, cmap, selected_commits, 0)
            self.revision_list.clearSelection()
            self.revision_list.update()
        elif self.strategie_forms.currentIndex(
        ) == GenerationStrategie.REVS_PER_YEAR.value:
            extend_with_revs_per_year(
                case_study, cmap, 0, True,
                get_local_project_git_path(self.selected_project),
                self.revs_per_year.value(), self.seperate.checkState())
        store_case_study(case_study, path)
Beispiel #4
0
def __gen_specific(ctx: click.Context, revisions: tp.List[str]) -> None:
    """
    Adds a list of specified revisions to the CS.

    Revisions: Revisions to add
    """
    cmap = create_lazy_commit_map_loader(ctx.obj['project'], None, 'HEAD',
                                         None)()
    extend_with_extra_revs(ctx.obj['case_study'], cmap, revisions,
                           ctx.obj['merge_stage'])
    store_case_study(ctx.obj['case_study'], ctx.obj['path'])
Beispiel #5
0
def __gen_release(ctx: click.Context, release_type: ReleaseType) -> None:
    """
    Extend a case study with revisions marked as a release. This relies on the
    project to determine appropriate revisions.

    release_type: Release type to consider
    """
    cmap = create_lazy_commit_map_loader(ctx.obj['project'], None, 'HEAD',
                                         None)()
    extend_with_release_revs(ctx.obj['case_study'], cmap, release_type,
                             ctx.obj['ignore_blocked'], ctx.obj['merge_stage'])
    store_case_study(ctx.obj['case_study'], ctx.obj['path'])
Beispiel #6
0
def __gen_bug_commits(ctx: click.Context,
                      report_type: tp.Type['BaseReport']) -> None:
    """
    Extend a case study with revisions that either introduced or fixed a bug as
    determined by the given SZZ tool.

    REPORT_TYPE: report to use for determining bug regions
    """
    cmap = create_lazy_commit_map_loader(ctx.obj['project'], None, 'HEAD',
                                         None)()
    extend_with_bug_commits(ctx.obj['case_study'], cmap, report_type,
                            ctx.obj['merge_stage'], ctx.obj['ignore_blocked'])
    store_case_study(ctx.obj['case_study'], ctx.obj['path'])
Beispiel #7
0
def __gen_per_year(ctx: click.Context, revs_per_year: int,
                   separate: bool) -> None:
    """
    Add a number of revisions per year.

    revs-per-year: number of revisions to generate per year
    """
    cmap = create_lazy_commit_map_loader(ctx.obj['project'], None, 'HEAD',
                                         None)()
    extend_with_revs_per_year(ctx.obj['case_study'], cmap,
                              ctx.obj['merge_stage'],
                              ctx.obj['ignore_blocked'], ctx.obj['git_path'],
                              revs_per_year, separate)
    store_case_study(ctx.obj['case_study'], ctx.obj['path'])
def draw_cves(
    axis: axes.Axes, project: tp.Type[Project],
    revisions: tp.List[FullCommitHash], cve_line_width: int, cve_color: str,
    label_size: int, vertical_alignment: str
) -> None:
    """
    Annotates CVEs for a project in an existing plot.

    Args:
        axis: the axis to use for the plot
        project: the project to add CVEs for
        revisions: a list of revisions included in the plot in the order they
                   appear on the x-axis
        cve_line_width: the line width of CVE annotations
        cve_color: the color of CVE annotations
        label_size: the label size of CVE annotations
        vertical_alignment: the vertical alignment of CVE annotations
    """
    cmap = create_lazy_commit_map_loader(project.NAME)()
    revision_time_ids = [cmap.time_id(rev) for rev in revisions]

    cve_provider = CVEProvider.get_provider_for_project(project)
    for revision, cves in cve_provider.get_revision_cve_tuples():
        cve_time_id = cmap.time_id(revision)
        if cve_time_id in revision_time_ids:
            index = float(revisions.index(revision))
        else:
            # revision not in sample; draw line between closest samples
            index = len([x for x in revision_time_ids if x < cve_time_id]) - 0.5

        transform = axis.get_xaxis_transform()
        for cve in cves:
            axis.axvline(
                index,
                label=cve.cve_id,
                linewidth=cve_line_width,
                color=cve_color
            )
            axis.text(
                index + 0.1,
                0,
                cve.cve_id,
                transform=transform,
                rotation=90,
                size=label_size,
                color=cve_color,
                va=vertical_alignment
            )
Beispiel #9
0
def draw_bugs(axis: axes.Axes, project: tp.Type[Project],
              revisions: tp.List[FullCommitHash], bug_line_width: int,
              bug_color: str, label_size: int,
              vertical_alignment: str) -> None:
    """
    Annotates bugs for a project in an existing plot.

    Args:
        axis: the axis to use for the plot
        project: the project to add bugs for
        revisions: a list of revisions included in the plot in the order they
                   appear on the x-axis
        bug_line_width: the line width of bug annotations
        bug_color: the color of bug annotations
        label_size: the label size of bug annotations
        vertical_alignment: the vertical alignment of bug annotations
    """
    cmap = create_lazy_commit_map_loader(project.NAME)()
    revision_time_ids = [cmap.time_id(rev) for rev in revisions]

    bug_provider = BugProvider.get_provider_for_project(project)
    for rawbug in bug_provider.find_raw_bugs():
        bug_time_id = cmap.time_id(rawbug.fixing_commit)
        if bug_time_id in revision_time_ids:
            index = float(revisions.index(rawbug.fixing_commit))
        else:
            # revision not in sample; draw line between closest samples
            index = len([x
                         for x in revision_time_ids if x < bug_time_id]) - 0.5

        label = " ".join([f"#{rawbug.issue_id}"])

        transform = axis.get_xaxis_transform()
        axis.axvline(index,
                     label=label,
                     linewidth=bug_line_width,
                     color=bug_color)
        axis.text(index + 0.1,
                  0,
                  label,
                  transform=transform,
                  rotation=90,
                  size=label_size,
                  color=bug_color,
                  va=vertical_alignment)
Beispiel #10
0
def get_status(
    case_study: CaseStudy,
    experiment_type: tp.Type[VersionExperiment],
    longest_cs_name: int,
    sep_stages: bool,
    sort: bool,
    use_color: bool = False,
    total_status_occurrences: tp.Optional[tp.DefaultDict[
        FileStatusExtension, tp.Set[ShortCommitHash]]] = None
) -> str:
    """
    Return a string representation that describes the current status of the case
    study.

    Args:
        case_study: to print the status for
        experiment_type: experiment type to print files for
        longest_cs_name: amount of chars that should be considered for
        sep_stages: print each stage separeted
        sort: sort the output order of the case studies
        use_color: add color escape sequences for highlighting
        total_status_occurrences: mapping from all occured status to a set of
                                  all revisions (total amount of revisions)

    Returns:
        a full string representation of all case studies
    """
    status = get_short_status(case_study, experiment_type, longest_cs_name,
                              use_color, total_status_occurrences) + "\n"

    if sort:
        cmap = create_lazy_commit_map_loader(case_study.project_name)()

    def rev_time(rev: tp.Tuple[ShortCommitHash, FileStatusExtension]) -> int:
        return cmap.short_time_id(rev[0])

    if sep_stages:
        stages = case_study.stages
        for stage_num in range(0, case_study.num_stages):
            status += f"  Stage {stage_num}"
            stage_name = stages[stage_num].name
            if stage_name:
                status += f" ({stage_name})"
            status += "\n"
            tagged_revs = _combine_tagged_revs_for_experiment(
                case_study, experiment_type, stage_num)
            if sort:
                tagged_revs = sorted(tagged_revs, key=rev_time, reverse=True)
            for tagged_rev_state in tagged_revs:
                status += f"    {tagged_rev_state[0].hash} " \
                          f"[{tagged_rev_state[1].get_colored_status()}]\n"
    else:
        tagged_revs = list(
            dict.fromkeys(
                _combine_tagged_revs_for_experiment(case_study,
                                                    experiment_type)))
        if sort:
            tagged_revs = sorted(tagged_revs, key=rev_time, reverse=True)
        for tagged_rev_state in tagged_revs:
            status += f"    {tagged_rev_state[0].hash} " \
                      f"[{tagged_rev_state[1].get_colored_status()}]\n"

    return status