File Coverage

blib/lib/Dist/Zilla/Plugin/ShareEmbed.pm
Criterion Covered Total %
statement 26 71 36.6
branch 0 10 0.0
condition n/a
subroutine 9 15 60.0
pod 0 4 0.0
total 35 100 35.0


line stmt bran cond sub pod time code
1             package Dist::Zilla::Plugin::ShareEmbed 0.004;
2 1     1   103161 use 5.14.0;
  1         4  
3 1     1   6 use warnings;
  1         2  
  1         24  
4              
5 1     1   516 use File::pushd ();
  1         24103  
  1         24  
6 1     1   541 use MIME::Base64 ();
  1         643  
  1         27  
7 1     1   1271 use Moose;
  1         493601  
  1         9  
8 1     1   9941 use Path::Tiny ();
  1         12030  
  1         29  
9 1     1   539 use namespace::autoclean;
  1         9812  
  1         3  
10 1     1   64 use B ();
  1         7  
  1         218  
11              
12             with qw(
13             Dist::Zilla::Role::AfterBuild
14             Dist::Zilla::Role::FilePruner
15             );
16              
17             has module => (
18             is => 'rw',
19             isa => 'Str',
20             lazy => 1,
21             default => sub {
22             my $self = shift;
23             my $name = $self->zilla->name;
24             $name =~ s{-}{::}g;
25             "$name\::Share";
26             },
27             );
28              
29             has path => (
30             is => 'rw',
31             isa => 'Path::Tiny',
32             lazy => 1,
33             default => sub {
34             my $self = shift;
35             my $name = $self->zilla->name;
36             $name =~ s{-}{/}g;
37             Path::Tiny->new("lib/$name/Share.pm");
38             },
39             );
40              
41             has share => (
42             is => 'rw',
43             isa => 'Str',
44             lazy => 1,
45             default => 'share',
46             );
47              
48             if (exists $INC{"Dist/Zilla/Dist/Builder.pm"}) {
49             # XXX I don't know the best way to do this :)
50             package
51             Dist::Zilla::Dist::Builder;
52 1     1   8 no warnings 'redefine';
  1         2  
  1         712  
53             sub _build_share_dir_map {
54 0     0     return +{};
55             }
56             }
57              
58             sub has_share {
59 0     0 0   my $self = shift;
60 0           $self->zilla->root->child($self->share)->is_dir;
61             }
62              
63             sub after_build {
64 0     0 0   my $self = shift;
65 0 0         return unless $self->has_share;
66 0           $self->embed_share;
67             }
68              
69             sub prune_files {
70 0     0 0   my $self = shift;
71 0 0         return unless $self->has_share;
72              
73             # XXX This copy is needed.
74             # because $self->zilla->prune_file splices $self->zilla->files
75 0           my @file = @{ $self->zilla->files };
  0            
76              
77 0           for my $file (@file) {
78 0 0         if ($file->name =~ m{^share/}) {
79 0           $self->zilla->prune_file($file);
80             }
81             }
82 0           return;
83             }
84              
85             my $HEAD = <<'___';
86             use strict;
87             use warnings;
88             use MIME::Base64 ();
89              
90             my %file;
91              
92             sub file {
93             my $class = shift;
94             @_ ? $file{$_[0]} : \%file;
95             }
96              
97             ___
98              
99             sub embed_share {
100 0     0 0   my $self = shift;
101              
102 0           my $share = $self->zilla->root->child($self->share);
103 0           my %file;
104             {
105 0           my $guard = File::pushd::pushd("$share");
  0            
106             my $visit = sub {
107 0     0     my ($path, $state) = @_;
108 0 0         return if $path->is_dir;
109 0           my $content = $path->slurp_raw;
110 0           $file{ "$path" } = MIME::Base64::encode_base64($content);
111 0           };
112 0           Path::Tiny->new(".")->visit($visit, {recurse => 1});
113             }
114 0           my $path = $self->path;
115 0 0         $path->parent->mkpath unless $path->parent->is_dir;
116 0           $self->log(sprintf "Embedding %s/ to %s", $self->share, $path);
117 0           my $fh = $path->openw_raw;
118 0           print {$fh} "# This file was automatically generated by Dist::Zilla::Plugin::ShareEmbed\n";
  0            
119 0           print {$fh} "package " . $self->module . ";\n";
  0            
120 0           print {$fh} $HEAD;
  0            
121 0           for my $name (sort keys %file) {
122 0           my $quoted = B::perlstring($name);
123 0           print {$fh} "\$file{$quoted} = MIME::Base64::decode_base64(<<'___');\n";
  0            
124 0           print {$fh} $file{$name};
  0            
125 0           print {$fh} "___\n\n";
  0            
126             }
127 0           print {$fh} "1;\n";
  0            
128             }
129              
130             __PACKAGE__->meta->make_immutable;
131              
132             1;
133             __END__
134              
135             =encoding utf-8
136              
137             =for stopwords pm
138              
139             =head1 NAME
140              
141             Dist::Zilla::Plugin::ShareEmbed - Embed share files to .pm file
142              
143             =head1 SYNOPSIS
144              
145             In your dist.ini:
146              
147             [ShareEmbed]
148              
149             Then
150              
151             > dzil build
152              
153             > find lib -type f
154             lib/Your/Module.pm
155             lib/Your/Module/Share.pm <=== Created!
156              
157             =head1 DESCRIPTION
158              
159             Dist::Zilla::Plugin::ShareEmbed embeds share files to C<lib/Your/Module/Share.pm>,
160             so that you can use share files like:
161              
162             use Your::Module::Share;
163              
164             # returns content of share/foo/bar.txt
165             my $bar = Your::Module::Share->file("foo/bar.txt");
166              
167             # returns all contens of files in share directory
168             my $all = Your::Module::Share->file;
169              
170             This plugin may be useful when you intend to fatpack your modules.
171              
172             =head1 AUTHOR
173              
174             Shoichi Kaji <skaji@cpan.org>
175              
176             =head1 COPYRIGHT AND LICENSE
177              
178             Copyright 2016 Shoichi Kaji <skaji@cpan.org>
179              
180             This library is free software; you can redistribute it and/or modify
181             it under the same terms as Perl itself.
182              
183             =cut