Skip Menu |

This queue is for tickets about the App-FatPacker CPAN distribution.

Report information
The Basics
Id: 60622
Status: resolved
Priority: 0/
Queue: App-FatPacker

People
Owner: Nobody in particular
Requestors: dgl@dgl.cx (no email address)
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Packing modules that attempt conditial loading
Date: Sun, 22 Aug 2010 22:51:35 +0100
To: bugs-App-FatPacker [...] rt.cpan.org
From: David Leadbeater <dgl [...] dgl.cx>
Hi, I found an issue when trying to fatpack trace an app that uses Encode. It tries to pack Encode::ConfigLocal which Encode tries to load within an eval block (although anything that tries that sort of thing could fail). Here's an attempt to fix it. Note using CHECK blocks means the test can't even C<require App::FatPacker::Trace> anymore. David --- a/lib/App/FatPacker/Trace.pm +++ b/lib/App/FatPacker/Trace.pm @@ -4,14 +4,36 @@ use strict; use warnings FATAL => 'all'; use B (); +my %seen; +my $trace_file = "fatpacker.trace"; + sub import { - my $open = $_[1] || '>>fatpacker.trace'; - open my $trace, $open - or die "Couldn't open ${open} to trace to: $!"; + $trace_file = $_[1] if defined $_[1]; + unshift @INC, sub { - print $trace "$_[1]\n"; + $seen{$_[1]}++; + return; # false in case someone messed with %INC + }; + + my $remover; + push @INC, $remover = sub { + # Ensure this stays at the end + if($INC[-1] ne $remover) { + @INC = ((grep { !ref || $_ != $remover } @INC), $remover); + return; + } + + delete $seen{$_[1]}; + return; }; + B::minus_c; } +CHECK { + open my $trace, ">", $trace_file + or die "Couldn't open ${trace_file} to trace to: $!"; + print $trace "$_\n" for keys %seen; +} + 1; diff --git a/t/basic.t b/t/basic.t index 6e97616..9da7609 100644 --- a/t/basic.t +++ b/t/basic.t @@ -3,6 +3,5 @@ use warnings FATAL => 'all'; use Test::More qw(no_plan); require App::FatPacker; -require App::FatPacker::Trace; pass "Didn't blow up";
On Sun Aug 22 17:51:46 2010, dgl@dgl.cx wrote: Show quoted text
> + open my $trace, ">", $trace_file > + or die "Couldn't open ${trace_file} to trace to: $!";
That should be ">>".
Had a chat with mst on IRC, we decided this approach isn't the best. I'll aim for a revised patch in a few days time.
CC: David Leadbeater <dgl [...] dgl.cx>
Subject: [PATCH] [rt.cpan.org #60622] Handle conditional loading
Date: Mon, 20 Dec 2010 18:12:36 +0000
To: bugs-App-FatPacker [...] rt.cpan.org
From: dgl [...] dgl.cx
From: David Leadbeater <dgl@dgl.cx> This patch uses a CHECK block to see what is actually loaded, rather than using a @INC hook which sees what might be loaded. Also add some basic tests for tracing module loading. --- lib/App/FatPacker/Trace.pm | 26 ++++++++++++++++++++------ t/basic.t | 1 - t/mod/a.pm | 3 +++ t/mod/b.pm | 3 +++ t/mod/c.pm | 2 ++ t/mod/cond.pm | 3 +++ t/trace.t | 29 +++++++++++++++++++++++++++++ 7 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 t/mod/a.pm create mode 100644 t/mod/b.pm create mode 100644 t/mod/c.pm create mode 100644 t/mod/cond.pm create mode 100644 t/trace.t diff --git a/lib/App/FatPacker/Trace.pm b/lib/App/FatPacker/Trace.pm index 6d1f68a..1da5943 100644 --- a/lib/App/FatPacker/Trace.pm +++ b/lib/App/FatPacker/Trace.pm @@ -4,14 +4,28 @@ use strict; use warnings FATAL => 'all'; use B (); +my $trace_file; +my %initial_inc; + sub import { - my $open = $_[1] || '>>fatpacker.trace'; - open my $trace, $open - or die "Couldn't open ${open} to trace to: $!"; - unshift @INC, sub { - print $trace "$_[1]\n"; - }; + $trace_file = $_[1] || '>>fatpacker.trace'; + # For filtering out our own deps later. + # (Not strictly required as these are core only and won't have packlists, but + # looks neater.) + %initial_inc = %INC; B::minus_c; } +CHECK { + return unless $trace_file; # not imported + + open my $trace, $trace_file + or die "Couldn't open $trace_file to trace to: $!"; + + for my $inc(keys %INC) { + next if exists $initial_inc{$inc}; + print $trace "$inc\n"; + } +} + 1; diff --git a/t/basic.t b/t/basic.t index 6e97616..9da7609 100644 --- a/t/basic.t +++ b/t/basic.t @@ -3,6 +3,5 @@ use warnings FATAL => 'all'; use Test::More qw(no_plan); require App::FatPacker; -require App::FatPacker::Trace; pass "Didn't blow up"; diff --git a/t/mod/a.pm b/t/mod/a.pm new file mode 100644 index 0000000..c119640 --- /dev/null +++ b/t/mod/a.pm @@ -0,0 +1,3 @@ +package t::mod::a; +use t::mod::b; +1; diff --git a/t/mod/b.pm b/t/mod/b.pm new file mode 100644 index 0000000..9127201 --- /dev/null +++ b/t/mod/b.pm @@ -0,0 +1,3 @@ +package t::mod::b; +use t::mod::c; +1; diff --git a/t/mod/c.pm b/t/mod/c.pm new file mode 100644 index 0000000..09f8b20 --- /dev/null +++ b/t/mod/c.pm @@ -0,0 +1,2 @@ +package t::mod::c; +1; diff --git a/t/mod/cond.pm b/t/mod/cond.pm new file mode 100644 index 0000000..d4af160 --- /dev/null +++ b/t/mod/cond.pm @@ -0,0 +1,3 @@ +package t::mod::cond; +eval { require t::mod::nothere }; +1; diff --git a/t/trace.t b/t/trace.t new file mode 100644 index 0000000..154e83c --- /dev/null +++ b/t/trace.t @@ -0,0 +1,29 @@ +#!perl +use Test::More; + +test_trace("t/mod/a.pm" => ("t/mod/b.pm", "t/mod/c.pm")); +test_trace("t/mod/b.pm" => ("t/mod/c.pm")); +test_trace("t/mod/c.pm" => ()); + +# Attempts to conditionally load a module that isn't present +test_trace("t/mod/cond.pm" => ()); + +done_testing; + +sub test_trace { + my($file, @loaded) = @_; + local $Test::Builder::Level = $Test::Builder::Level + 1; + + system($^X, "-Mblib", "-MApp::FatPacker::Trace", $file); + + open my $trace, "<", "fatpacker.trace"; + while(<$trace>) { + chomp; + my $load = $_; + @loaded = grep { $load ne $_ } @loaded; + } + + ok !@loaded, "All expected modules loaded for $file"; + unlink "fatpacker.trace"; +} + -- 1.7.3.3
Fixed in 0.9.5.