File Coverage

blib/lib/Rex/Apache/Build/deb.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4             # vim: set ts=3 sw=3 tw=0:
5             # vim: set expandtab:
6              
7             =head1 NAME
8              
9             Rex::Apache::Build::deb - Build deb packages
10              
11             =head1 DESCRIPTION
12              
13             With this module you can build Debian packages to distribute your application.
14              
15             =head1 SYNOPSIS
16              
17             build "my-software",
18             type => "deb",
19             version => "1.0",
20             source => "/path/to/your/software",
21             path => "/path/to/deploy/target",
22             # below this, it is all optional
23             description => "some description of your package",
24             url => "website of the package",
25             depends => [qw/apache2 perl/],
26             release => 1,
27             epoch => 1,
28             vendor => "some vendor",
29             license => "your license for ex. GPL2",
30             section => "some/section",
31             conflicts => [qw/somepkg/],
32             provides => "some-package-name",
33             arch => "amd64",
34             target => "linux / the platform",
35             post_install => "filename or script to run after installation",
36             pre_install => "filename or script to run before installation",
37             post_uninstall => "filename or script to run after uninstall",
38             pre_uninstall => "filename or script to run before uninstall",
39             exclude => [qw/file1 file2/],
40             maintainer => "your name",
41             priority => "optional",
42             config_files => [qw/special files for configuration mostly for etc directory/];
43              
44              
45             =cut
46              
47             package Rex::Apache::Build::deb;
48              
49 1     1   2059 use strict;
  1         3  
  1         35  
50 1     1   5 use warnings;
  1         1  
  1         24  
51 1     1   140440 use attributes;
  1         6938  
  1         10  
52              
53 1     1   91 use Cwd qw(getcwd);
  1         4  
  1         66  
54 1     1   7 use Digest::MD5;
  1         4  
  1         56  
55 1     1   1051 use Rex -base;
  0            
  0            
56             use Rex::Template;
57             use Data::Dumper;
58              
59             $Rex::Template::DO_CHOMP = TRUE;
60              
61             use Rex::Apache::Build::Base;
62             use base qw(Rex::Apache::Build::Base);
63              
64             sub new {
65             my $that = shift;
66             my $proto = ref($that) || $that;
67             my $self = $proto->SUPER::new(@_);
68              
69             bless($self, $proto);
70              
71             if($self->{arch} eq "x86_64") {
72             $self->{arch} = "amd64";
73             }
74              
75             $self->{priority} ||= "optional";
76             $self->{exclude} ||= [];
77              
78             push(@{ $self->{exclude} }, qr{^Rexfile$}, qr{^Rexfile\.lock$}, qr{^\.git}, qr{^\.svn}, qr{.*~$}, qr{\.sw[a-z]$}, qr{\.deb$});
79              
80             return $self;
81             }
82              
83             sub build {
84             my ($self, $name) = @_;
85              
86             $name ||= $self->{name};
87             my $version = $self->version;
88              
89             my $old_dir = getcwd;
90              
91             mkdir "temp-deb-build";
92             mkdir "temp-deb-build/control";
93             mkdir "temp-deb-build/tree";
94              
95             $self->copy_files_to_tmp;
96              
97             file "temp-deb-build/debian-binary",
98             content => "2.0\n";
99              
100              
101             file "temp-deb-build/control/control",
102             content => template('@control.file', pkg => $self);
103              
104             file "temp-deb-build/control/md5sums",
105             content => $self->get_md5sums;
106              
107             $self->create_config_files;
108             $self->create_scripts;
109              
110             $self->package_data;
111             $self->package_control;
112              
113             rmdir "temp-deb-build/tree";
114             rmdir "temp-deb-build/control";
115              
116             chdir "temp-deb-build";
117              
118             my $arch = $self->{arch};
119             my $package_name = "${name}_${version}_${arch}.deb";
120             run "ar -qc ../$package_name debian-binary control.tar.gz data.tar.gz";
121             chdir "..";
122              
123             rmdir "temp-deb-build";
124              
125             Rex::Logger::info("Your build is now available: $package_name");
126              
127             return $package_name;
128             }
129              
130             sub create_config_files {
131             my ($self) = @_;
132              
133             if($self->{config_files}) {
134             file "temp-deb-build/control/conffiles",
135             content => join("\n", @{ $self->{config_files} });
136             }
137             }
138              
139             sub create_scripts {
140             my ($self) = @_;
141              
142             if($self->{post_install}) {
143             my $post_install = $self->{post_install};
144             if($post_install !~ m/\n/sim && -f $post_install) {
145             $post_install = eval { local(@ARGV, $/) = ($post_install); <>; };
146             }
147              
148             file "temp-deb-build/control/postinst",
149             content => $post_install,
150             mode => 755;
151             }
152              
153             if($self->{pre_install}) {
154             my $pre_install = $self->{pre_install};
155             if($pre_install !~ m/\n/sim && -f $pre_install) {
156             $pre_install = eval { local(@ARGV, $/) = ($pre_install); <>; };
157             }
158              
159             file "temp-deb-build/control/preinst",
160             content => $pre_install,
161             mode => 755;
162             }
163              
164             if($self->{post_uninstall}) {
165             my $post_uninstall = $self->{post_uninstall};
166             if($post_uninstall !~ m/\n/sim && -f $post_uninstall) {
167             $post_uninstall = eval { local(@ARGV, $/) = ($post_uninstall); <>; };
168             }
169              
170             file "temp-deb-build/control/postrm",
171             content => $post_uninstall,
172             mode => 755;
173             }
174              
175             if($self->{pre_uninstall}) {
176             my $pre_uninstall = $self->{pre_uninstall};
177             if($pre_uninstall !~ m/\n/sim && -f $pre_uninstall) {
178             $pre_uninstall = eval { local(@ARGV, $/) = ($pre_uninstall); <>; };
179             }
180              
181             file "temp-deb-build/control/prerm",
182             content => $pre_uninstall,
183             mode => 755;
184             }
185              
186             }
187              
188             sub package_data {
189             my ($self) = @_;
190              
191             chdir "temp-deb-build/tree";
192             run "tar czf ../data.tar.gz .";
193             chdir "../../";
194             }
195              
196             sub package_control {
197             my ($self) = @_;
198              
199             chdir "temp-deb-build/control";
200             run "tar czf ../control.tar.gz .";
201             chdir "../../";
202             }
203              
204              
205             sub copy_files_to_tmp {
206             my ($self) = @_;
207              
208             my $prefix = $self->prefix || ".";
209             mkdir "temp-deb-build/tree/$prefix";
210              
211             my @dirs = ($self->{source});
212              
213             for my $dir (@dirs) {
214             opendir(my $dh, $dir) or die($!);
215              
216             DIR_ENTRY: while(my $entry = readdir($dh)) {
217             next if ($entry eq "." or $entry eq ".." or $entry eq "temp-deb-build");
218              
219             for my $ex (@{ $self->exclude }) {
220             if($entry =~ m/$ex/) {
221             next DIR_ENTRY;
222             }
223             }
224              
225             my $new_dir = "$dir/$entry";
226             $new_dir =~ s/^$dirs[0]//;
227             $new_dir =~ s/^\///;
228              
229             if(-d "$dir/$entry") {
230             mkdir "temp-deb-build/tree$prefix/$new_dir";
231              
232             push(@dirs, "$dir/$entry");
233             next DIR_ENTRY;
234             }
235              
236             cp "$dir/$entry", "temp-deb-build/tree$prefix/$new_dir";
237             } # DIR_ENTRY
238              
239             closedir($dh);
240             }
241              
242             }
243              
244             sub get_md5sums {
245             my ($self) = @_;
246              
247             my @s = ();
248             chdir "temp-deb-build/tree";
249              
250             my @dirs = (".");
251             for my $dir (@dirs) {
252             opendir(my $dh, $dir);
253             while(my $entry = readdir($dh)) {
254             next if($entry eq ".");
255             next if($entry eq "..");
256              
257             my $file = "$dir/$entry";
258              
259             if(-d $file) {
260             push(@dirs, $file);
261             next;
262             }
263              
264             my $md5 = Digest::MD5->new;
265             open(my $fh, "<", $file) or die($!);
266             $file =~ s/^\.\///;
267             $md5->addfile($fh);
268             push(@s, $md5->hexdigest . " " . $file);
269             close($fh);
270              
271              
272             }
273             closedir($dh);
274             }
275              
276             chdir "../..";
277              
278             return join("\n", @s);
279              
280             }
281              
282             sub description {
283             my ($self, $desc) = @_;
284              
285             if($desc) {
286             $self->{description} = $desc;
287             }
288              
289             my $s = "";
290              
291             my @lines = split(/\n/, $self->{description});
292             $s = shift(@lines);
293              
294             for (@lines) {
295             $s .= " $_";
296             }
297              
298             return $s;
299             }
300              
301             sub depends {
302             my ($self, $dep) = @_;
303              
304             if($dep) {
305             $self->{depends} = $dep;
306             }
307              
308             my @s = ();
309              
310             for my $dep (@{ $self->{depends} }) {
311             if(ref($dep)) {
312             my ($pkg) = keys %{ $dep };
313             my ($ver) = values %{ $dep };
314              
315             push(@s, $pkg . "($ver)");
316             }
317             else {
318             push(@s, $dep);
319             }
320             }
321              
322             return join(", ", @s);
323             }
324              
325             sub installed_size {
326             my ($self) = @_;
327              
328             my $size = 0;
329              
330             chdir "temp-deb-build/tree";
331              
332             my @dirs = (".");
333             for my $dir (@dirs) {
334             opendir(my $dh, $dir);
335             while(my $entry = readdir($dh)) {
336             next if($entry eq ".");
337             next if($entry eq "..");
338              
339             my $file = "$dir/$entry";
340              
341             if(-d $file) {
342             push(@dirs, $file);
343             next;
344             }
345             $size += -s $file;
346              
347             }
348             closedir($dh);
349             }
350              
351             chdir "../..";
352              
353             return $size;
354             }
355              
356              
357             1;
358              
359             __DATA__