277cf849131cbd3b2ca43621d8b5b16a11211c6d
[p5sagit/App-FatPacker.git] / lib / App / FatPacker / Trace.pm
1 package App::FatPacker::Trace;
2
3 use strict;
4 use warnings FATAL => 'all';
5 use B ();
6
7 my $trace_file;
8 my %initial_inc;
9
10 sub import {
11   my (undef, $file, @extras) = @_;
12
13   $trace_file = $file || '>>fatpacker.trace';
14   # For filtering out our own deps later.
15   # (Not strictly required as these are core only and won't have packlists, but 
16   # looks neater.)
17   %initial_inc = %INC;
18
19   # Use any extra modules specified
20   eval "use $_" for @extras;
21
22   B::minus_c;
23 }
24
25 CHECK {
26   return unless $trace_file; # not imported
27
28   open my $trace, $trace_file
29       or die "Couldn't open $trace_file to trace to: $!";
30
31   for my $inc (keys %INC) {
32     next if exists $initial_inc{$inc};
33     next unless $INC{$inc} =~ /\Q${inc}\E\Z/;
34     print $trace "$inc\n";
35   }
36 }
37
38 1;
39
40 __END__
41
42 =head1 NAME
43
44 App::FatPacker::Trace - Tracing module usage using compilation checking
45
46 =head1 SYNOPSIS
47
48     # open STDERR for writing
49     # will be like: open my $fh, '>', '&STDERR'...
50     perl -MApp::FatPacker::Trace=>&STDERR myscript.pl
51
52     # open a file for writing
53     # will be like: open my $fh, '>>', 'fatpacker.trace'
54     perl -MApp::FatPacker::Trace=>>fatpacker.trace myscript.pl
55
56 =head1 DESCRIPTION
57
58 This module allows tracing the modules being used by your code. It does that
59 using clever trickery using the C<import> method, the C<CHECK> block and
60 L<B>'s C<minus_c> function.
61
62 When App::FatPacker::Trace is being used, the import() method will call
63 C<B::minus_c> in order to set up the global compilation-only flag perl
64 (the interpreter) has. This will prevent any other code from being run.
65
66 Then in the C<CHECK> block which is reached at the end of the compilation
67 phase (see L<perlmod>), it will gather all modules that have been loaded,
68 using C<%INC>, and will write it to a file or to STDERR, determined by
69 parameters sent to the C<import> method.
70
71 =head1 METHODS
72
73 =head2 import
74
75 This method gets run when you just load L<App::FatPacker::Trace>. It will
76 note the current C<%INC> and will set up the output to be written to, and
77 raise the compilation-only flag, which will prevent anything from being
78 run past that point. This flag cannot be unset, so this is most easily run
79 from the command line as such:
80
81     perl -MApp::FatPacker::Trace [...]
82
83 You can control the parameters to the import using an equal sign, as such:
84
85     # send the parameter "hello"
86     perl -MApp::FatPacker::Trace=hello [...]
87
88     # send the parameter ">&STDERR"
89     perl -MApp::FatPacker::Trace=>&STDERR [...]
90
91 The import method accepts a first parameter telling it which output to open
92 and how. These are both sent in a single parameter.
93
94     # append to mytrace.txt
95     perl -MApp::FatPacker::Trace=>>mytrace.txt myscript.pl
96
97     # write to STDERR
98     perl -MApp::FatPacker::Trace=>&STDERR myscript.pl
99
100 The import method accepts additional parameters of extra modules to load.
101 It will then add these modules to the trace. This is helpful if you want
102 to explicitly indicate additional modules to trace, even if they aren't
103 used in your script. Perhaps you're conditionally using them, perhaps
104 they're for additional features, perhaps they're loaded lazily, whatever
105 the reason.
106
107     # Add Moo to the trace, even if you don't trace it in myscript.pl
108     perl -MApp::FatPacker::Trace=>&STDERR,Moo myscript.pl
109