Devel-Cover
view release on metacpan or search on metacpan
lib/Devel/Cover.pm view on Meta::CPAN
return if $Initialised;
my $class = shift;
# Die tainting
# Anyone using this module can do worse things than messing with tainting
my $options = ($ENV{DEVEL_COVER_OPTIONS} || "") =~ /(.*)/ ? $1 : "";
my @o = (@_, split /,/, $options);
defined or $_ = "" for @o;
# print STDERR __PACKAGE__, ": Parsing options from [@o]\n";
my $blib = -d "blib";
@Inc = () if "@o" =~ /-inc /;
@Ignore = () if "@o" =~ /-ignore /;
@Select = () if "@o" =~ /-select /;
while (@o) {
local $_ = shift @o;
/^-silent/ && do { $Silent = shift @o; next };
/^-dir/ && do { $Dir = shift @o; next };
/^-db/ && do { $DB = shift @o; next };
/^-loose_perms/ && do { $Loose_perms = shift @o; next };
/^-merge/ && do { $Merge = shift @o; next };
/^-summary/ && do { $Summary = shift @o; next };
/^-blib/ && do { $blib = shift @o; next };
/^-subs_only/ && do { $Subs_only = shift @o; next };
/^-replace_ops/ && do { $Replace_ops = shift @o; next };
/^-coverage/
&& do { $Coverage{ +shift @o } = 1 while @o && $o[0] !~ /^[-+]/; next };
/^[-+]ignore/
&& do { push @Ignore, shift @o while @o && $o[0] !~ /^[-+]/; next };
/^[-+]inc/ && do { push @Inc, shift @o while @o && $o[0] !~ /^[-+]/; next };
/^[-+]select/
&& do { push @Select, shift @o while @o && $o[0] !~ /^[-+]/; next };
warn __PACKAGE__ . ": Unknown option $_ ignored\n";
}
if ($blib) {
eval "use blib";
for (@INC) { $_ = $1 if ref $_ ne 'CODE' && /(.*)/ } # Die tainting
push @Ignore, "^t/", '\\.t$', '^test\\.pl$';
}
my $ci = $^O eq "MSWin32";
@Select_re = map qr/$_/, @Select;
@Ignore_re = map qr/$_/, @Ignore;
@Inc_re = map $ci ? qr/^\Q$_\//i : qr/^\Q$_\//, @Inc;
bootstrap Devel::Cover $VERSION;
if (defined $Dir) {
$Dir = $1 if $Dir =~ /(.*)/; # Die tainting
} else {
$Dir = $1 if Cwd::getcwd() =~ /(.*)/;
}
$DB = File::Spec->rel2abs($DB, $Dir);
unless (mkdir $DB) {
my $err = $!;
die "Can't mkdir $DB as EUID $>: $err" unless -d $DB;
}
chmod 0777, $DB if $Loose_perms;
$DB = $1 if abs_path($DB) =~ /(.*)/; ## no critic (CaptureWithoutTest)
Devel::Cover::DB->delete($DB) unless $Merge;
%Files = (); # start gathering file information from scratch
for my $c (Devel::Cover::DB->new->criteria) {
my $func = "coverage_$c";
no strict "refs";
$Criteria{$c} = $func->();
}
for (keys %Coverage) {
my @c = split /-/;
if (@c > 1) {
$Coverage{ shift @c } = \@c;
delete $Coverage{$_};
}
delete $Coverage{$_} unless length;
}
%Coverage = (all => 1) unless keys %Coverage;
# print STDERR "Coverage: ", Dumper \%Coverage;
%Coverage_options = %Coverage;
$Initialised = 1;
if ($ENV{MOD_PERL}) {
eval "BEGIN {}";
check();
set_first_init_and_end();
}
}
sub populate_run {
my $self = shift;
$Run{OS} = $^O;
$Run{perl} = sprintf "%vd", $^V;
$Run{dir} = $Dir;
$Run{run} = $0;
$Run{name} = $Dir;
$Run{version} = "unknown";
my $mymeta = "$Dir/MYMETA.json";
if (-e $mymeta) {
eval {
require CPAN::Meta;
my $json = CPAN::Meta->load_file($mymeta)->as_struct;
$Run{$_} = $json->{$_} for qw( name version abstract );
}
} elsif ($Dir =~ m|.*/([^/]+)$|) {
my $filename = $1;
eval {
require CPAN::DistnameInfo;
my $dinfo = CPAN::DistnameInfo->new($filename);
$Run{name} = $dinfo->dist;
$Run{version} = $dinfo->version;
}
}
$Run{start} = get_elapsed() / 1e6;
lib/Devel/Cover.pm view on Meta::CPAN
$Structure->read_all;
$Structure->add_criteria(@collected);
# print STDERR "Start structure: ", Dumper $Structure;
# print STDERR "Processing cover data\n@Inc\n";
$Coverage = coverage(1) || die "No coverage data available.\n";
# print STDERR Dumper $Coverage;
check_files();
unless ($Subs_only) {
get_cover(main_cv, main_root);
get_cover_progress("BEGIN block",
B::begin_av()->isa("B::AV") ? B::begin_av()->ARRAY : ());
if (exists &B::check_av) {
get_cover_progress("CHECK block",
B::check_av()->isa("B::AV") ? B::check_av()->ARRAY : ());
}
# get_ends includes INIT blocks
get_cover_progress("END/INIT block",
get_ends()->isa("B::AV") ? get_ends()->ARRAY : ());
}
# print STDERR "--- @Cvs\n";
get_cover_progress("CV", @Cvs);
my %files;
$files{$_}++ for keys %{ $Run{count} }, keys %{ $Run{vec} };
for my $file (sort keys %files) {
# print STDERR "looking at $file\n";
unless (use_file($file)) {
# print STDERR "deleting $file\n";
delete $Run{count}->{$file};
delete $Run{vec}->{$file};
$Structure->delete_file($file);
next;
}
# $Structure->add_digest($file, \%Run);
for my $run (keys %{ $Run{vec}{$file} }) {
delete $Run{vec}{$file}{$run} unless $Run{vec}{$file}{$run}{size};
}
$Structure->store_counts($file);
}
# print STDERR "End structure: ", Dumper $Structure;
my $run = time . ".$$." . sprintf "%05d", rand 2**16;
my $cover = Devel::Cover::DB->new(
base => $DB,
runs => { $run => \%Run },
structure => $Structure,
loose_perms => $Loose_perms
);
my $dbrun = "$DB/runs";
unless (mkdir $dbrun) {
die "Can't mkdir $dbrun $!" unless -d $dbrun;
}
chmod 0777, $dbrun if $Loose_perms;
$dbrun .= "/$run";
print OUT __PACKAGE__, ": Writing coverage database to $dbrun\n"
unless $Silent;
$cover->write($dbrun);
$Digests->write;
$cover->print_summary if $Summary && !$Silent;
if ($Self_cover && !$Self_cover_run) {
$cover->delete;
delete $Run{vec};
}
chdir $starting_dir if $starting_dir;
}
sub add_subroutine_cover {
my ($op) = @_;
get_location($op);
return unless $File;
# print STDERR "Subroutine $Sub_name $File:$Line: ", $op->name, "\n";
my $key = get_key($op);
my $val = $Coverage->{statement}{$key} || 0;
my ($n, $new) = $Structure->add_count("subroutine");
# print STDERR "******* subroutine $n - $new\n";
$Structure->add_subroutine($File, [ $Line, $Sub_name ]) if $new;
$Run{count}{$File}{subroutine}[$n] += $val;
my $vec = $Run{vec}{$File}{subroutine};
vec($vec->{vec}, $n, 1) = $val ? 1 : 0;
$vec->{size} = $n + 1;
}
sub add_statement_cover {
my ($op) = @_;
get_location($op);
return unless $File;
# print STDERR "Stmt $File:$Line: $op $$op ", $op->name, "\n";
$Run{digests}{$File} ||= $Structure->set_file($File);
my $key = get_key($op);
my $val = $Coverage->{statement}{$key} || 0;
my ($n, $new) = $Structure->add_count("statement");
# print STDERR "Stmt $File:$Line - $n, $new\n";
$Structure->add_statement($File, $Line) if $new;
$Run{count}{$File}{statement}[$n] += $val;
my $vec = $Run{vec}{$File}{statement};
vec($vec->{vec}, $n, 1) = $val ? 1 : 0;
$vec->{size} = $n + 1;
no warnings "uninitialized";
$Run{count}{$File}{time}[$n] += $Coverage->{time}{$key}
if $Coverage{time}
&& exists $Coverage->{time}
&& exists $Coverage->{time}{$key};
}
sub add_branch_cover {
( run in 3.366 seconds using v1.01-cache-2.11-cpan-cdf2f3d4e48 )