#!/usr/bin/env perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
  if 0;    # not running under some shell
use strict;
use warnings;
use Data::Dump qw( dd pp );
use Carp;
use Path::Tiny;
use JSON;

=head1 NAME

dump-parsed-cpanm-build-logs - pretty-print logs stored in JSON

=head1 USAGE

Multiple files:

    dump-parsed-cpanm-build-logs \
        /path/to/tad/results/perl-5.27.6/analysis/01/CPANID.Some-Distro-0.008.log.json \
        /path/to/tad/results/perl-5.27.6/analysis/01/OTHERCPANID.Some-Other-Distro-0.001.log.json

or a single file on F<STDIN>:

    cat /path/to/tad/results/perl-5.27.6/analysis/01/CPANID.Some.Distro-.log.json | \
        dump-parsed-cpanm-build-logs

NOTE:  This program's name is long.  You may wish to create a shorter alias for it
provided that alias does not clash with any other program whose name indicates
it "dumps JSON."

=head1 DESCRIPTION

This is a helper program for use with Perl extension
L<CPAN-cpanminus-reporter-RetainReports|http://search.cpan.org/dist/CPAN-cpanminus-reporter-RetainReports/>.

When you call that module's C<run()> method, a F<build.log> created by
F<cpanm> is parsed to create individual files on disk for each module which
received a grade such as C<PASS>, C<FAIL>, C<NA> or C<UNKNOWN>.  Those files
are written in compact JSON for use as input into other programs.  But compact
JSON is not very human-readable.  Use this program to pretty-print the report
to F<STDOUT>.

=head2 Sample Output

Running the program on the two files in the F<examples/> directory in this distribution generates:

    {
      author => "DAGOLDEN",
      dist => "Sub-Uplevel",
      distname => "Sub-Uplevel-0.2800",
      distversion => "0.2800",
      grade => "PASS",
      prereqs => undef,
      test_output => [
        "Building and testing Sub-Uplevel-0.2800",
        "cp lib/Sub/Uplevel.pm blib/lib/Sub/Uplevel.pm",
        "PERL_DL_NONLAZY=1 \"/home/jkeenan/var/tad/testing/perl-5.27.6/bin/perl\" \"-MExtUtils::Command::MM\" \"-MTest::Harness\" \"-e\" \"undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')\" t/*.t",
        "# ",
        "# Versions for all modules listed in MYMETA.json (including optional ones):",
        "# ",
        "# === Configure Requires ===",
        "# ",
        "#     Module              Want Have",
        "#     ------------------- ---- ----",
        "#     ExtUtils::MakeMaker 6.17 7.30",
        "# ",
        "# === Build Requires ===",
        "# ",
        "#     Module              Want Have",
        "#     ------------------- ---- ----",
        "#     ExtUtils::MakeMaker  any 7.30",
        "# ",
        "# === Test Requires ===",
        "# ",
        "#     Module              Want     Have",
        "#     ------------------- ---- --------",
        "#     Exporter             any     5.72",
        "#     ExtUtils::MakeMaker  any     7.30",
        "#     File::Spec           any     3.69",
        "#     Test::More           any 1.302111",
        "#     lib                  any     0.64",
        "# ",
        "# === Test Recommends ===",
        "# ",
        "#     Module         Want     Have",
        "#     ---------- -------- --------",
        "#     CPAN::Meta 2.120900 2.150010",
        "# ",
        "# === Runtime Requires ===",
        "# ",
        "#     Module   Want Have",
        "#     -------- ---- ----",
        "#     Carp      any 1.44",
        "#     constant  any 1.33",
        "#     strict    any 1.11",
        "#     warnings  any 1.38",
        "# ",
        "t/00-report-prereqs.t ........ ok",
        "t/01_die_check.t ............. ok",
        "t/02_uplevel.t ............... ok",
        "t/03_nested_uplevels.t ....... ok",
        "t/04_honor_later_override.t .. ok",
        "t/05_honor_prior_override.t .. ok",
        "t/06_db_args.t ............... ok",
        "t/07_uplevel_too_high.t ...... ok",
        "t/08_exporter.t .............. ok",
        "t/09_emptylist.t ............. ok",
        "All tests successful.",
        "Files=10, Tests=158,  1 wallclock secs ( 0.06 usr  0.00 sys +  0.68 cusr  0.07 csys =  0.81 CPU)",
        "Result: PASS",
      ],
      via => "App::cpanminus::reporter 0.17 (1.7043)",
    }
    {
      author => "DAGOLDEN",
      dist => "Test-API",
      distname => "Test-API-0.008",
      distversion => 0.008,
      grade => "FAIL",
      prereqs => undef,
      test_output => [
        "Building and testing Test-API-0.008",
        "cp lib/Test/API.pm blib/lib/Test/API.pm",
        "PERL_DL_NONLAZY=1 \"/home/jkeenan/var/tad/testing/perl-5.27.6/bin/perl\" \"-MExtUtils::Command::MM\" \"-MTest::Harness\" \"-e\" \"undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')\" t/*.t",
        "# ",
        "# Versions for all modules listed in MYMETA.json (including optional ones):",
        "# ",
        "# === Configure Requires ===",
        "# ",
        "#     Module              Want Have",
        "#     ------------------- ---- ----",
        "#     ExtUtils::MakeMaker 6.17 7.30",
        "# ",
        "# === Build Requires ===",
        "# ",
        "#     Module              Want Have",
        "#     ------------------- ---- ----",
        "#     ExtUtils::MakeMaker  any 7.30",
        "# ",
        "# === Test Requires ===",
        "# ",
        "#     Module                Want     Have",
        "#     --------------------- ---- --------",
        "#     Carp                   any     1.44",
        "#     Exporter               any     5.72",
        "#     ExtUtils::MakeMaker    any     7.30",
        "#     File::Spec             any     3.69",
        "#     Test::Builder::Tester 1.18 1.302120",
        "#     Test::More             any 1.302120",
        "#     lib                    any     0.64",
        "# ",
        "# === Test Recommends ===",
        "# ",
        "#     Module         Want     Have",
        "#     ---------- -------- --------",
        "#     CPAN::Meta 2.120900 2.150010",
        "# ",
        "# === Runtime Requires ===",
        "# ",
        "#     Module                Want     Have",
        "#     --------------------- ---- --------",
        "#     Symbol                 any     1.08",
        "#     Test::Builder::Module 0.86 1.302120",
        "#     strict                 any     1.11",
        "#     warnings               any     1.38",
        "# ",
        "t/00-report-prereqs.t .. ok",
        "Not a GLOB reference at /home/jkeenan/var/tad/testing/perl-5.27.6/.cpanm/work/1513444048.14516/Test-API-0.008/blib/lib/Test/API.pm line 176.",
        "t/02-public.t .......... ",
        "Dubious, test returned 255 (wstat 65280, 0xff00)",
        "Failed 4/11 subtests ",
        "Not a GLOB reference at /home/jkeenan/var/tad/testing/perl-5.27.6/.cpanm/work/1513444048.14516/Test-API-0.008/blib/lib/Test/API.pm line 176.",
        "t/03-export.t .......... ",
        "Dubious, test returned 255 (wstat 65280, 0xff00)",
        "Failed 8/14 subtests ",
        "Not a GLOB reference at /home/jkeenan/var/tad/testing/perl-5.27.6/.cpanm/work/1513444048.14516/Test-API-0.008/blib/lib/Test/API.pm line 176.",
        "t/04-class-ok.t ........ ",
        "Dubious, test returned 255 (wstat 65280, 0xff00)",
        "Failed 3/5 subtests ",
        "",
        "Test Summary Report",
        "-------------------",
        "t/02-public.t        (Wstat: 65280 Tests: 7 Failed: 0)",
        "  Non-zero exit status: 255",
        "  Parse errors: Bad plan.  You planned 11 tests but ran 7.",
        "t/03-export.t        (Wstat: 65280 Tests: 6 Failed: 0)",
        "  Non-zero exit status: 255",
        "  Parse errors: Bad plan.  You planned 14 tests but ran 6.",
        "t/04-class-ok.t      (Wstat: 65280 Tests: 2 Failed: 0)",
        "  Non-zero exit status: 255",
        "  Parse errors: Bad plan.  You planned 5 tests but ran 2.",
        "Files=4, Tests=16,  1 wallclock secs ( 0.03 usr  0.00 sys +  0.36 cusr  0.03 csys =  0.42 CPU)",
        "Result: FAIL",
      ],
      via => "App::cpanminus::reporter 0.17 (1.7043)",
    }

=head1 PREREQUISITES

CPAN::cpanminus::reporter::RetainReports and its prerequisites.  Data::Dump.

=head1 AUTHOR

    James E Keenan
    CPAN Id:  JKEENAN
    jkeenan [at] cpan [dot] org

=head1 COPYRIGHT

Copyright (c) 2017 James E Keenan.  All rights reserved.
This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.

=head1 SEE ALSO

perl(1). CPAN::cpanminus::reporter::RetainReports(3). JSON(3).

=cut

my $decoded;
if (@ARGV) {
    for my $lfile (@ARGV) {
        croak "Cannot locate $lfile" unless (-f $lfile);
        my $f = Path::Tiny::path($lfile);
        $decoded = decode_json($f->slurp_utf8);
        display_text($decoded);
    }
}
else {
    $decoded = decode_json(<STDIN>);
    display_text($decoded);
}
exit 0;

sub display_text {
    my $decoded = shift;
    my $reworked = { map { $_ => $decoded->{$_} } sort grep { $_ ne 'test_output' } keys %{$decoded} };
    $reworked->{test_output} = [ split(/\n/, $decoded->{test_output}) ];
    dd($reworked);
    return 1;
}
