File Coverage

blib/lib/Exherbo/Packager.pm
Criterion Covered Total %
statement 89 96 92.7
branch 15 30 50.0
condition 6 9 66.6
subroutine 18 18 100.0
pod 2 4 50.0
total 130 157 82.8


line stmt bran cond sub pod time code
1             package Exherbo::Packager;
2              
3             # ABSTRACT: Generates exheres for perl modules
4              
5             =pod
6              
7             =head1 NAME
8              
9             Exherbo::Packager
10              
11             =head1 SYNOPSIS
12              
13             use Exherbo::Packager qw/init_config gen_template/;
14             my $config_loc = "/etc/exherbo-packager.yml"
15             init_config($config_loc);
16             gen_template("Exherbo::Packager");
17              
18             =head1 DESCRIPTION
19              
20             This module exports two functions, one to initialize the configuration of the
21             packager, and the other to generate the exheres. Currently, this package only
22             generates Exheres for Perl modules, but support for other languages is coming
23             soon.
24              
25             An OO version of this module is also planned, since exporting things into the
26             global namespace is icky.
27              
28             =head2 gen_template($modname)
29              
30             gen_template takes one argument, and that is the name of the perl module you
31             wish to generate. It will output the exheres in your current directory, in a
32             subdirectory named by the category it chooses.
33              
34             This will B<die> with an error if the exheres already exists.
35              
36             =head2 init_config
37              
38             =head2 init_config($config_loc)
39              
40             init_config can optionally take one argument, that being the location of the
41             config file you wish to use for this run of the packager. Once run, it will get
42             all of the configuration information for calls to C<gen_template()>.
43              
44             =head1 BUGS
45              
46             =over 1
47             =item No OO interface
48             =item Not very generic or extendable
49             =item Little error checking
50             =back
51              
52             =head1 AUTHOR
53              
54             William Orr <will@worrbase.com>
55              
56             =cut
57              
58              
59 2     2   254157 use strict;
  2         6  
  2         72  
60 2     2   11 use warnings;
  2         3  
  2         51  
61 2     2   62 use 5.010;
  2         10  
  2         180  
62              
63 2     2   2738 use DateTime;
  2         470760  
  2         77  
64 2     2   25 use Exporter;
  2         3  
  2         92  
65 2     2   923 use MetaCPAN::API;
  2         152843  
  2         68  
66 2     2   1796 use Ouch;
  2         2667  
  2         161  
67 2     2   861 use YAML::Any qw/LoadFile DumpFile/;
  2         1183  
  2         17  
68              
69             our @ISA = qw/Exporter/;
70             our @EXPORT_OK = qw/init_config gen_template/;
71              
72 2     2   12033 use constant CONFIG_LOC => $ENV{HOME}."/.exherbo-packager.yml";
  2         6  
  2         2052  
73              
74             my $mcpan;
75             my $config;
76              
77              
78             sub gen_template {
79 1     1 1 4 my ($name, $fh) = @_;
80              
81 1         5 my $mod = _get_module_info($name);
82 1         5 my $release = _get_release_info($mod);
83 1         16 my $dt = DateTime->now();
84            
85 1 50       788 if (not $config) { $config = _get_config(); }
  0         0  
86 1         7 my $year = $dt->year;
87              
88 1 50       14 unless ($mod->{description}) {
89 0         0 bleep("No description available");
90 0         0 $mod->{description} = "Describe me!";
91 0         0 $mod->{abstract} = "A nifty little abstract should go here!";
92             }
93              
94 1         6 $mod->{description} = sanitize($mod->{description});
95 1         6 $mod->{abstract} = sanitize($mod->{abstract});
96              
97 1         35 print $fh <<EOF
98             # Copyright $year $config->{name} <$config->{email}>
99             # Distributed under the terms of the GNU General Public License v2
100              
101             require perl-module [ module_author=$mod->{author} ]
102              
103             SUMMARY="$mod->{abstract}"
104             DESCRIPTION="
105             $mod->{description}
106             "
107              
108             SLOT="0"
109             PLATFORMS="$config->{platforms}"
110             MYOPTIONS=""
111              
112             DEPENDENCIES="
113             build+run:
114             EOF
115             ;
116 1         7 my $deps = _gen_deps($release->{dependency});
117 1         20 foreach my $k (sort { uc $a cmp uc $b } keys %$deps) {
  69         262  
118 22         66 say $fh " dev-perl/$deps->{$k}"
119             }
120 1         184 print $fh <<EOF
121             "
122              
123             BUGS_TO="$config->{email}"
124              
125             EOF
126             ;
127             }
128              
129             sub _get_module_info {
130 30     30   98 my ($name) = @_;
131              
132 30   66     170 $mcpan //= MetaCPAN::API->new();
133 30         351 my $mod = $mcpan->module($name);
134              
135 30 50       975466 ouch(404, "Module $name not found") if (not $mod);
136 30         176 return $mod;
137             }
138              
139             sub _get_release_info {
140 29     29   43371 my ($mod) = @_;
141              
142 29         315 my $rel = $mcpan->release(distribution => $mod->{distribution}, release => $mod->{release});
143 29 50       713914 barf("Release $mod->{distribution} not found") if (not $rel);
144 29         180 return $rel;
145             }
146              
147             sub _get_config {
148 1     1   8 my $lconfig = CONFIG_LOC;
149 1 50       6 $lconfig = shift if (@_);
150 1 50       2 eval {
151 1   33     13 return $config //= LoadFile($lconfig);
152             } or barf("Could not read config");
153             }
154              
155             sub get_outfile_name {
156 2     2 0 1474 my $mod = shift;
157              
158 2 50       11 if (ref($mod) ne "HASH") {
159 0         0 $mod = _get_module_info($mod);
160             }
161              
162 2         19 return "$mod->{release}.exheres-0";
163              
164             }
165              
166             sub _gen_deps {
167 2     2   5444 my ($deps) = @_;
168 2         7 my $rel_deps = {};
169              
170 2         5 foreach my $dep (@{$deps}) {
  2         7  
171 37 100 100     511 if ($dep->{relationship} eq 'requires' and $dep->{module} ne 'perl') {
172 27         145 my $rel = _get_release_info(_get_module_info($dep->{module}));
173 27 50       1031 next if ($rel->{distribution} eq 'perl');
174 27         1360 $rel_deps->{$rel->{distribution}} = $rel->{name};
175             }
176             }
177              
178 2         19 return $rel_deps;
179             }
180              
181             sub init_config {
182 1     1 1 4 my $lconfig = CONFIG_LOC;
183 1 50       6 $lconfig = shift if (@_);
184              
185 1 50       18 if ( -f $lconfig ) {
186 1         57 print "Are you sure you want to overwrite your config? ";
187 1 50       52 return if (*STDIN->getline !~ /^y$/i);
188             }
189              
190 1         74 my $conf_info = { };
191 1         36 print "What's your name? ";
192 1         29 $conf_info->{name} = _sane_chomp(*STDIN->getline);
193              
194 1         30 print "What's your email address? ";
195 1         31 $conf_info->{email} = _sane_chomp(*STDIN->getline);
196              
197 1         33 print "Give me a valid arch string to use by default for new packages: ";
198 1         32 $conf_info->{platforms} = _sane_chomp(*STDIN->getline);
199 1         214 print "\n";
200              
201 1 50       3 eval {
202 1 50       18 if ( not -f $lconfig ) {
203 0 0       0 open(my $fh, '>', $lconfig) or die;
204 0         0 close($fh);
205             }
206 1         7 DumpFile($lconfig, $conf_info)
207             } or ouch 400, "Could not open config file for writing";
208             }
209              
210             sub sanitize {
211 2     2 0 3 my $in = shift;
212 2         15 $in =~ s/"/\"/g;
213 2         6 return $in;
214             }
215              
216             sub _sane_chomp {
217 3     3   89 my $str = shift;
218 3         7 chomp $str;
219 3         12 return $str;
220             }
221              
222             1;