File Coverage

blib/lib/Rex/Apache/Build/rpm.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::rpm - Build rpm packages
10              
11             =head1 DESCRIPTION
12              
13             With this module you can build RedHat packages to distribute your application.
14              
15             =head1 SYNOPSIS
16              
17             build "my-software",
18             type => "rpm",
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/httpd 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 => "x86_64",
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             config_files => [qw/special files for configuration mostly for etc directory/];
42              
43              
44             =cut
45              
46             package Rex::Apache::Build::rpm;
47              
48 1     1   4171 use strict;
  1         2  
  1         43  
49 1     1   6 use warnings;
  1         2  
  1         46  
50 1     1   6 use attributes;
  1         3  
  1         7  
51              
52 1     1   62 use Cwd qw(getcwd);
  1         2  
  1         132  
53 1     1   6 use Digest::MD5;
  1         3  
  1         33  
54 1     1   799 use Rex::Logger;
  0            
  0            
55             use Rex::Commands::Run;
56             use Rex::Commands::Fs;
57             use Rex::Commands::File;
58             use Rex::Template;
59             use Data::Dumper;
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             $self->{license} ||= "unknown";
72             $self->{file_user} ||= "root";
73             $self->{file_group} ||= "root";
74             $self->{release} ||= 1;
75             $self->{exclude} ||= [];
76              
77             push(@{ $self->{exclude} }, qr{^Rexfile$}, qr{^Rexfile\.lock$}, qr{^\.git}, qr{^\.svn}, qr{.*~$}, qr{\.sw[a-z]$}, qr{\.rpm$});
78              
79             return $self;
80             }
81              
82             sub build {
83             my ($self, $name) = @_;
84              
85             $name ||= $self->name;
86              
87             mkdir "temp-rpm-build";
88             mkdir "temp-rpm-build/tree";
89             mkdir "temp-rpm-build/tree" . $self->prefix;
90              
91             my @dirs = $self->find_dirs;
92             push(@dirs, $self->prefix);
93              
94             my @files = $self->find_files;
95              
96             file "temp-rpm-build/$name.spec",
97             content => template('@spec.template', pkg => $self, cur_dir => getcwd(), files => \@files, dirs => \@dirs);
98              
99             chdir "temp-rpm-build";
100              
101             my $rpmbuild_path = Rex::Config->get("rpmbuild") || "rpmbuild";
102             run "$rpmbuild_path --buildroot=" . getcwd() . "/tree -bb $name.spec";
103              
104             chdir "..";
105              
106             my $arch = $self->arch;
107             cp "temp-rpm-build/$arch/*.rpm", ".";
108              
109             rmdir "temp-rpm-build";
110              
111             my $build_file = "$name-" . $self->version . "-" . $self->release . "." . $self->arch . ".rpm";
112             Rex::Logger::info("Your build is now available: $build_file");
113              
114             return $build_file;
115             }
116              
117             sub find_files {
118             my ($self) = @_;
119              
120             my @ret;
121              
122             my @dirs = ($self->{source});
123             for my $dir (@dirs) {
124             opendir(my $dh, $dir) or die($!);
125             while(my $entry = readdir($dh)) {
126             next if($entry eq ".");
127             next if($entry eq "..");
128              
129             if(-d "$dir/$entry") {
130             push(@dirs, "$dir/$entry");
131             next;
132             }
133              
134             Rex::Logger::debug("Adding file: " . getcwd() . "/$dir/$entry => $dir/$entry");
135             push(@ret, [getcwd() . "/$dir/$entry", "$dir/$entry"]);
136             }
137             closedir($dh);
138             }
139              
140             # free conffiles
141             for my $conf (@{ $self->config_files }) {
142             @ret = grep { $_->[0] !~ m/$conf/ } @ret;
143             }
144              
145             my $top = $self->source . "/";
146             map { $_->[1] =~ s/^$top// } @ret;
147              
148             Rex::Logger::debug("==== files ====");
149             Rex::Logger::debug(Dumper(\@ret));
150              
151             return @ret;
152             }
153              
154             sub find_dirs {
155             my ($self) = @_;
156              
157             my @ret;
158              
159             my @dirs = ($self->{source});
160             for my $dir (@dirs) {
161             opendir(my $dh, $dir) or die($!);
162             while(my $entry = readdir($dh)) {
163             next if($entry eq ".");
164             next if($entry eq "..");
165              
166             if(-d "$dir/$entry") {
167             push(@dirs, "$dir/$entry");
168              
169             Rex::Logger::debug("Adding directory: $dir/$entry");
170             push(@ret, "$dir/$entry");
171             }
172              
173             }
174             closedir($dh);
175             }
176              
177             my $top = $self->source;
178             map { s/^$top//; $_ = $self->prefix . $_ } @ret;
179              
180             Rex::Logger::debug("==== directories ====");
181             Rex::Logger::debug(Dumper(\@ret));
182              
183             return @ret;
184             }
185              
186              
187              
188             1;
189              
190             __DATA__