File Coverage

blib/lib/Dist/Setup.pm
Criterion Covered Total %
statement 36 106 33.9
branch 0 50 0.0
condition 0 9 0.0
subroutine 12 15 80.0
pod 0 2 0.0
total 48 182 26.3


line stmt bran cond sub pod time code
1             package Dist::Setup;
2              
3 1     1   204975 use strict;
  1         2  
  1         40  
4 1     1   12 use warnings;
  1         4  
  1         85  
5 1     1   7 use utf8;
  1         2  
  1         6  
6 1     1   46 use feature ':5.24';
  1         4  
  1         232  
7 1     1   583 use version 0.77;
  1         2544  
  1         9  
8              
9 1     1   847 use Eval::Safe;
  1         22882  
  1         53  
10 1     1   10 use File::Basename 'basename', 'dirname';
  1         3  
  1         98  
11 1     1   637 use File::Copy;
  1         4627  
  1         73  
12 1     1   7 use File::Find;
  1         3  
  1         73  
13 1     1   6 use File::Spec::Functions 'abs2rel', 'catfile';
  1         2  
  1         47  
14 1     1   677 use Template;
  1         17948  
  1         31  
15 1     1   456 use Time::localtime;
  1         3731  
  1         1377  
16              
17             our $VERSION = '0.16';
18              
19             our %conf; # to be shared with the Eval::Safe object.
20             my $tt;
21             my $tt_raw;
22             my $target_dir;
23              
24             my $footer_marker = '# End of the template. You can add custom content below this line.';
25              
26             sub setup {
27 0     0 0   my ($data_dir, $target_dir_local) = @_;
28 0           $target_dir = $target_dir_local;
29              
30 0           my $conf_file_name = 'dist_setup.conf';
31 0           my $conf_file = catfile($target_dir, $conf_file_name);
32 0 0         if (!-e $conf_file) {
33 0           print STDERR "No ${conf_file_name} in target directory.\n";
34 0 0         copy(catfile($data_dir, $conf_file_name), $conf_file)
35             or die "Cannot copy ${conf_file_name}: $!\n";
36 0           print STDERR "Created a new configuration file. Modify it then run this tool again.\n";
37 0           exit 0;
38             }
39              
40 0           my $eval = Eval::Safe->new();
41 0 0         %conf = %{$eval->do($conf_file)}
  0            
42             or die "Cannot parse the ${conf_file_name} configuration: $@\n";
43 0           $eval->share('%conf');
44              
45 0           $conf{auto}{date}{year} = localtime->year() + 1900; ## no critic (ProhibitMagicNumbers)
46 0   0       $conf{dist_name} //= $conf{name} =~ s/::/-/gr;
47 0   0       $conf{dist_package} //= $conf{name} =~ s/::/\//gr; # Undocumented for now, used only by the `make exe` target
48 0   0       $conf{base_package} //= 'lib/'.($conf{name} =~ s{::}{/}gr).'.pm';
49 0           $conf{footer_marker} = $footer_marker;
50             $conf{short_min_perl_version} =
51 0           version->parse($conf{min_perl_version})->normal =~ s/^v(\d+\.\d+)\..*$/$1/r;
52             $conf{dotted_min_perl_version} =
53 0           version->parse($conf{min_perl_version})->normal =~ s/^v(\d+(?:\.\d+)*).*$/$1/r;
54              
55 0 0         if ($conf{github}{use_ci}) {
56 0 0         $conf{github}{use_ci} = {} unless ref $conf{github}{use_ci};
57             $conf{github}{use_ci}{runners} = [qw(ubuntu windows macos)]
58 0 0         unless exists $conf{github}{use_ci}{runners};
59             }
60              
61 0           $tt = Template->new({
62             INCLUDE_PATH => $data_dir,
63             OUTPUT_PATH => $target_dir,
64             ENCODING => 'utf8',
65             EVAL_PERL => 1,
66             PRE_PROCESS => 'tt_header',
67             POST_PROCESS => 'tt_footer',
68             });
69 0           $tt_raw = Template->new({
70             INCLUDE_PATH => $data_dir,
71             OUTPUT_PATH => $target_dir,
72             ENCODING => 'utf8',
73             EVAL_PERL => 1,
74             });
75              
76             find({
77             no_chdir => 1,
78             wanted => sub {
79 0     0     my $f = basename($_);
80 0 0         if ($f =~ m/^\./) {
81 0           $File::Find::prune = 1;
82 0           return;
83             }
84 0 0         return if $f eq 'dist_setup.conf';
85 0 0         return if $f =~ m/^tt_/;
86 0 0         return if $f =~ m/\.cond$/;
87              
88 0           my $src = abs2rel($_, $data_dir);
89 0           my $out = $src;
90 0           $out =~ s/(^|\/)dot_/${1}./g;
91              
92 0 0         my $cond_file = -d $_ ? catfile($_, '.cond') : $_.'.cond';
93 0 0         if (-f $cond_file) {
94 0           my $ret = $eval->do($cond_file);
95 0 0         die "Cannot evaluate ${cond_file}: $@\n" if $@;
96 0 0         die "Cannot read ${cond_file}: $!\n" if $!;
97 0 0         if (!$ret) {
98 0           $File::Find::prune = 1;
99 0           print "Skipped ${out}\n";
100 0           return;
101             }
102             }
103 0 0         return if -d $_;
104 0 0         die "Cannot read $_: $!\n" unless -r $_;
105              
106 0           print "Processing ${out}\n";
107 0           setup_file($src, $out);
108             },
109             },
110 0           $data_dir);
111 0           return;
112             }
113              
114             sub setup_file {
115 0     0 0   my ($src_file, $target_file) = @_;
116 0           my $footer = q{};
117              
118 0           my $dest_tt;
119              
120 0 0         if ($src_file =~ m/\.raw$/) {
121 0           $dest_tt = $tt_raw;
122 0           $target_file =~ s/\.raw$//;
123             } else {
124 0           $dest_tt = $tt;
125 0           my $dest_file = catfile($target_dir, $target_file);
126 0 0         if (-e $dest_file) {
127 0 0         open my $f, '<:encoding(UTF-8)', $dest_file
128             or die "Cannot open '$dest_file': $!\n";
129 0           while (<$f>) {
130 0 0         last if /^${footer_marker}$/m;
131             }
132 0 0         $footer = do { local $/ = undef; <$f> } unless eof($f);
  0            
  0            
133 0           $footer =~ s/\n+$//;
134 0 0         $footer = "\n".$footer if $footer; # There is no new line before footer in the template.
135 0 0         close $f or die "Cannot close '$dest_file': $!\n";
136             }
137             }
138              
139 0 0         $dest_tt->process($src_file, {%conf, footer_content => $footer},
140             $target_file, {binmode => ':utf8'})
141             or die "Cannot process template ${src_file}: ".$dest_tt->error()."\n";
142              
143 0           return;
144             }
145              
146             1;
147              
148             __END__