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