The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Devel::Git::MultiBisect::BuildTransitions - Gather build-time output where it changes over a range of git commits

SYNOPSIS

    use Devel::Git::MultiBisect::BuildTransitions;

    $self = Devel::Git::MultiBisect::BuildTransitions->new(\%parameters);

    $commit_range = $self->get_commits_range();

    $self->multisect_builds();

    $multisected_outputs = $self->get_multisected_outputs();

    $transitions = $self->inspect_transitions();
}

DESCRIPTION

Whereas Devel::Git::MultiBisect::Transitions is concerned with test-time failures, Devel::Git::MultiBisect::BuildTransitions is concerned with build-time phenomena: exceptions and warnings. We can identify three such cases:

  • Build-time failures: probe => 'error'

    While running your C-compiler over C source code via make, an exception may be thrown which causes the build to fail. Over a large number of commits, different exceptions may be thrown at various commits. Identify those commits.

  • Build-time C-level warnings: probe => 'warning'

    Your C-compiler may identify sub-optimal C source code and emit warnings. Over a large number of commits, different warnings may be thrown at various commits. Identify the commits where the warnings changed.

  • Build-time non-C-level warnings: probe => 'stderr'

    At build time make is not limited to running a C compiler; it may also execute statements in Perl, shell or other languages. Those statements may themselves generate warnings. Identify the commits where the STDERR output from make changes.

These three cases are distinguished by the probe key-value pair passed to new(), the constructor, or to the multisect_builds() method described below. The default value for probe is 'error', i.e., to multisect for build-time exceptions.

METHODS

new()

  • Purpose

    Constructor.

  • Arguments

        $self = Devel::Git::MultiBisect::BuildTransitions->new(\%params);

    Reference to a hash, typically the return value of Devel::Git::MultiBisect::Opts::process_options(). Example:

        %args = (
            gitdir              => "~/gitwork/perl",
            outputdir           => tempdir(),
            first               => 'd4bf6b07402c770d61a5f8692f24fe944655d99f',
            last                => '9be343bf32d0921e5c792cbaa2b0038f43c6e463',
            branch              => 'blead',
            configure_command   => 'sh ./Configure -des -Dusedevel',
            verbose             => 1,
            probe               => 'stderr,
        );
        $params = Devel::Git::MultiBisect::opts::process_options(%args);
        $self = Devel::Git::MultiBisect::BuildTransitions->new($params);
  • Return Value

    Object of Devel::Git::MultiBisect child class.

multisect_builds()

  • Purpose

    With a given set of configuration options and a specified range of git commits, identify the points where the output of the "build command" -- typically, make -- materially changed.

    A material change would be either (a) the emergence or correction of C-level exceptions (error); (b) the emergence or correction of C-level warnings (warning); (c) the emergence or correction of STDERR output emitted during make by Perl, shell or other non-C code (stderr).

  • NOTICE OF CHANGE OF INTERFACE

    Up through version 0.19 of Devel::Git::MultiBisect::BuildTransitions, the recommended (indeed, only) way to select among error, warning and stderr was to pass your choice as the value of a hash reference keyed on probe to the multisect_builds() method. As of version 0.20, the recommended way is to provide the probe => 'value' key-value pair as one of the elements passed to new(), the constructor (typically via Devel::Git::MultiBisect::opts::process_options(%params)). Beginning in January 2022, multisect_builds() will no longer do anything with arguments passed to it.

  • Arguments

        $self->multisect_builds();
    
        $self->multisect_builds({ probe => 'error' });      # DEPRECATED
    
        $self->multisect_builds({ probe => 'warning' });    # DEPRECATED
    
        $self->multisect_builds({ probe => 'stderr' });     # DEPRECATED
  • Return Value

    Returns true value upon success.

  • Comment

    As multisect_builds() runs it does two kinds of things:

    • It stores results data within the object which you can subsequently access through method calls.

    • Depending on the value assigned to probe, the method captures build-time error messages (error) or warnings (warning) from each commit run and writes them to a file on disk for later human inspection. If you have selected probe => 'stderr', all content directed to STDERR is written to that file.

  • If you are using Devel::Git::Multisect::BuildTransitions to diagnose problems in the Perl 5 core distribution, multisect_builds() will take some time to run, as perl will have to be configured and built for each commit run.

get_multisected_outputs()

  • Purpose

    Get results of multisect_builds() (other than test output files created) reported on a per commit basis.

  • Arguments

        my $multisected_outputs = $self->get_multisected_outputs();

    None; all data needed is already present in the object.

  • Return Value

    Reference to an array with one element for each commit in the commit range.

    • If a particular commit was not visited in the course of multisect_builds(), then the array element is undefined. (The point of multisection, of course, is to not have to visit every commit in the commit range in order to figure out the commits at which test output changed.)

    • If a particular commit was visited in the course of multisect_builds(), then the array element is a hash reference whose elements have the following keys:

          commit
          commit_short
          file
          md5_hex

inspect_transitions()

  • Purpose

    Get a data structure which reports on the most meaningful results of multisect_builds(), namely, the first commit, the last commit and all transitional commits.

  • Arguments

        my $transitions = $self->inspect_transitions();

    None; all data needed is already present in the object.

  • Return Value

    Reference to a hash with 3 key-value pairs. Each element's value is another hash reference. The elements of the top-level hash are:

    • oldest

      Value is reference to hash keyed on idx, md5_hex and file, whose values are, respectively, the index position of the very first commit in the commit range, the digest of that commit's test output and the path to the file holding that output.

    • newest

      Value is reference to hash keyed on idx, md5_hex and file, whose values are, respectively, the index position of the very last commit in the commit range, the digest of that commit's test output and the path to the file holding that output.

    • transitions

      Value is reference to an array with one element for each transitional commit. Each such element is a reference to a hash with keys older and newer. In this context older refers to the last commit in a sub-sequence with a particular digest; newer refers to the next immediate commit which is the first commit in a new sub-sequence with a new digest.

      The values of older and newer are, in turn, references to hashes with keys idx, md5_hex and file. Their values are, respectively, the index position of the particular commit in the commit range, the digest of that commit's test output and the path to the file holding that output.

    Example:

  • Comment

    The return value of inspect_transitions() should be useful to the developer trying to determine the various points in a long series of commits where a target's test output changed in meaningful ways. Hence, it is really the whole point of Devel::Git::MultiBisect::BuildTransitions.