1package File::ShareDir::Tarball;
2BEGIN {
3  $File::ShareDir::Tarball::AUTHORITY = 'cpan:YANICK';
4}
5{
6  $File::ShareDir::Tarball::VERSION = '0.2.2';
7}
8# ABSTRACT: Deal transparently with shared files distributed as tarballs
9
10
11use strict;
12use warnings;
13
14use parent qw/ Exporter /;
15
16use Carp;
17
18use File::ShareDir;
19use Archive::Tar;
20use File::Temp qw/ tempdir /;
21use File::chdir;
22
23our @EXPORT_OK   = qw{
24    dist_dir dist_file
25};
26our %EXPORT_TAGS = (
27    all => [ @EXPORT_OK ],
28);
29
30my $shared_files_tarball = 'shared-files.tar.gz';
31
32# we don't want to extract the same dirs again and
33# again within a single program
34my %DIR_CACHE;
35
36sub dist_dir {
37    my $dist = shift;
38
39    return $DIR_CACHE{$dist} if $DIR_CACHE{$dist};
40
41    my $dir = File::ShareDir::dist_dir($dist);
42
43    # no tarball? Assume regular shared dir
44    return $DIR_CACHE{$dist} = $dir
45        unless -f "$dir/$shared_files_tarball";
46
47    my $archive = Archive::Tar->new;
48    $archive->read("$dir/$shared_files_tarball");
49
50    # because that would be a veeery bad idea
51    croak "archive '$shared_files_tarball' contains files with absolute path, aborting"
52        if grep { m#^/# } $archive->list_files;
53
54    my $tmpdir = tempdir( CLEANUP => 1 );
55    local $CWD = $tmpdir;
56
57    $archive->extract;
58
59    return $DIR_CACHE{$dist} = $tmpdir;
60}
61
62sub dist_file {
63    my $dist = File::ShareDir::_DIST(shift);
64    my $file = File::ShareDir::_FILE(shift);
65
66    my $path = dist_dir($dist).'/'.$file;
67
68	return undef unless -e $path;
69
70    croak("Found dist_file '$path', but not a file")
71        unless -f $path;
72
73    croak("File '$path', no read permissions")
74        unless -r $path;
75
76	return $path;
77}
78
79
801;
81
82__END__
83
84=pod
85
86=head1 NAME
87
88File::ShareDir::Tarball - Deal transparently with shared files distributed as tarballs
89
90=head1 VERSION
91
92version 0.2.2
93
94=head1 SYNOPSIS
95
96    use File::ShareDir::Tarball ':all';
97
98    # use exactly like File::ShareDir
99    $dir = dist_dir('File-ShareDir');
100
101=head1 DESCRIPTION
102
103If the shared files of a distribution are contained in a
104tarball (see L<Dist::Zilla::Plugin::ShareDir::Tarball> for
105why you would want to do that), automatically
106extract the archive in a temporary
107directory and return the path to that directory. If called for a regular distribution without a bundle file
108(C<shared-files.tar.gz>), it'll return the original shared dir.
109In other words,
110from the consumer point of view, it'll behave just like L<File::ShareDir>.
111
112=head1 EXPORT TAGS
113
114=head2 :all
115
116Exports C<dist_dir()> and C<dist_file()>.
117
118=head1 EXPORTABLE FUNCTIONS
119
120=head2 dist_dir( $distribution )
121
122Behaves just like C<dist_dir()> from L<File::ShareDir>.
123
124=head2 dist_file( $distribution, $file )
125
126Behaves just like C<dist_file()> from L<File::ShareDir>.
127
128=head1 SEE ALSO
129
130=over
131
132=item L<Test::File::ShareDir>
133
134To test or use a shared dir that is not deployed yet.
135
136=item L<Dist::Zilla::Plugin::ShareDir::Tarball>
137
138L<Dist::Zilla> plugin to create the tarball effortlessly.
139
140=item L<Module::Build::CleanInstall>
141
142Provides an alternative to this module by subclassing L<Module::Build> and,
143upon installation, remove the files from previous installations as given in
144the I<packlist>.
145
146=back
147
148=head1 AUTHOR
149
150Yanick Champoux <yanick@babyl.dyndns.org>
151
152=head1 COPYRIGHT AND LICENSE
153
154This software is copyright (c) 2012 by Yanick Champoux.
155
156This is free software; you can redistribute it and/or modify it under
157the same terms as the Perl 5 programming language system itself.
158
159=cut
160