checking in RPM build system
[freeside.git] / rpm / build / enrpm
1 #!/usr/bin/perl -w
2 #
3 # Attempt to build RPMs for Freeside from a tarball or module
4 #
5 # Contains portions of "cpanspec" http://cpanspec.sourceforge.net/
6
7 =head1 NAME
8
9 enrpm - Attempt to build RPMs for Freeside from a tarball or a module
10
11 =head1 SYNOPSIS
12
13 enrpm [options] [tarball|module-name [...]]
14
15  Options:
16    --help       -h      Help message
17
18 =head1 DESCRIPTION
19
20 B<enrpm> will generate a spec file to build a rpm from a CPAN-style
21 Perl module distribution, then try to build RPMs from that spec file
22 under mock, and update the repositories if successful.
23
24 B<enrpm> uses the file extension of the tarball or module-name specified
25 on the command line to determine if the argument is a tarball or a module name.
26
27 Modules are downloaded from the CPAN.  You must have initialized CPAN on the machine
28 for B<enrpm> to be able to do this.
29
30 For tarballs B<enrpm> attempts to build a usable .spec file using cpanflute2, and then builds
31 an SRPM from the .spec file and the tarball.
32
33 Once an SRPM has been built, B<enrpm> uses an external script to build binary RPMs under "mock".
34 It then uses a second script to update the repositories.
35
36 =head1 OPTIONS
37
38 =over 4
39
40 =item B<--help>
41
42 Print a brief help message and exit.
43
44 =item B<--packager>
45
46 Specify the name and e-mail address of the packager.  This winds up in auto-generated .spec files.
47
48 =item B<--server>
49
50 Specify the host name or IP address of the server on which the SRPM will be built.  This server must be
51 set up for SRPM building, which means it must have both B<ovid> and B<cpanflute2> installed on it.
52
53 =item B<--dry-run>
54
55 Just print out commands, don't actually run them.
56
57 =back
58
59 =head1 BUGS
60
61 Currently has little in the way of error detection and diagnostics.
62
63 The back-end should be replaced with an existing build system such as koji.
64
65 =head1 AUTHOR
66
67 Richard Siddall <richard.siddall@elirion.net>
68
69 =head1 SEE ALSO
70
71 L<perl(1)>, L<cpan2rpm(1)>, L<cpanflute2(1)>
72
73 =cut
74
75 use strict;
76 use Getopt::Long;
77 use Cwd qw/getcwd abs_path/;
78 use File::Basename;
79 use Sys::Hostname; # False laziness to get around a real config file...
80
81 my %opts;
82
83 GetOptions(\%opts, 'packager=s', 'release=s', 'server=s', 'dryrun');
84
85 $ENV{PATH} = "/bin:/usr/bin";
86
87 sub usage {
88         print STDERR "usage: enrpm --packager <Your Name <you\@example.com>> [--release=<rpm-release-string>] --server <server-name> [--dryrun] tarball|module-name\n";
89         print STDERR "where:\n\t--packager is the name and e-mail address of the packager for the .spec file\n\t--release is the rpm release number for the .spec file\n\t--server is the server to build the SRPM on\n\t--dryrun means do not actually run the commands\n\n";
90         print STDERR "\ttarball is the name of a tarball containing the Perl module to be packaged\n";
91         print STDERR "\tmodule-name is the name of a CPAN Perl module to be packaged\n";
92         exit;
93 }
94
95 # Feeble excuse for not having a real configuration file
96 my $user = 'rsiddall';
97 my $buildsys = '/home/rsiddall/work';
98 my $rembuild = '/home/rsiddall/work/cvs';
99 my $remdeps = '/home/rsiddall';
100 my $rpmtopdir = '/home/rsiddall/work/redhat';
101 my $packager = 'Richard Siddall <richard.siddall@elirion.net>';
102 my $server = 'grosbeak';
103
104 if (hostname =~ /wavetail/i) {
105         $buildsys = '/home/rsiddall/buildsys';
106         $rembuild = '/home/rsiddall/buildsys/ref';
107         $remdeps = '/home/rsiddall';
108         $rpmtopdir = '/home/rsiddall/redhat';
109         $packager = 'Ivan Kohler <ivan@freeside.biz>';
110         $server = '10.5.4.5';
111 }
112
113 $server = $opts{server} if defined($opts{server});
114 $user = $1 if $server =~ /(\w+)\@[\w\d\.]+/;
115
116 $packager = $opts{packager} if defined($opts{packager});
117
118 # Go ahead and build an SRPM...
119
120 my $ovidignore = '--ignore ' . join ('--ignore ', qw/libwww/);
121
122
123 for my $file (@ARGV) {
124         my ($name,$version,$type);
125
126         if ($file =~ /^(?:.*\/)?(.*)-(?:v\.?)?([^-]+)\.(tar)\.(?:gz|bz2)$/) {
127                 $name = $1;
128                 $version = $2;
129                 $type = $3;
130         } elsif ($file =~ /^(?:.*\/)?(.*)-(?:v\.?)?([^-]+)\.tgz$/) {
131                 $name = $1;
132                 $version = $2;
133                 $type = 'tar';
134         } elsif ($file =~ /^(?:.*\/)?(.*)-(?:v\.?)?([^-]+)\.(zip)$/) {
135                 $name = $1;
136                 $version = $2;
137                 $type = $3;
138         } else {
139                 # keep things happy if we get "Foo-Bar" instead of "Foo::Bar"
140                 $file =~ s/-/::/g;
141                 $name = $file;
142                 $version = undef;
143                 $type = 'module';
144         }
145
146         if ($type eq 'module') {
147                 my $fluteopts = '';
148                 $fluteopts .= "--packager='$packager' " if defined($packager);
149                 $fluteopts .= "--release='$opts{release}' " if defined($opts{release});
150                 do_cmd("ssh $user\@$server \"ovid --deps $ovidignore $name | tail -1 | $remdeps/ovid2flute $fluteopts | /bin/sh\"");
151         } else {
152                 my $absfile = abs_path($file);
153                 my $fname = basename($file);
154                 die "Packager name and e-mail required" if !defined($packager);
155                 die "RPM release string required" if !defined($opts{release});
156                 do_cmd("scp $absfile $user\@$server:/home/$user/$fname");
157 #               do_cmd("ssh $user\@$server 'cpanflute2 --just-spec --noperlreqs --email=\\\"$packager\\\" --release=$opts{release}  /home/$user/$fname > /home/$user/work/redhat/SPECS/$name.spec;'");
158 #               do_cmd("ssh $user\@$server 'perl -pi -e \\\"s/perl\(perl\)/perl/g\\\" /home/$user/work/redhat/SPECS/$name.spec;'");
159 #               do_cmd("ssh $user\@$server 'rpmbuild -bs --nodeps --define \\\"_sourcedir /home/$user/\\\" --define \\\"_srcrpmdir /home/$user/work/redhat/SRPMS\\\" /home/$user/work/redhat/SPECS/$name.spec'");
160                 open SCRIPT, ">/home/$user/makesrpm" or die "Can't create SRPM construction script: ", $!;
161                 print SCRIPT "#!/bin/sh\n\n";
162                 print SCRIPT "cpanflute2 --just-spec --noperlreqs --email='$packager' --release=$opts{release}  /home/$user/$fname > $rpmtopdir/SPECS/$name.spec;\n";
163                 print SCRIPT "perl -pi -e 's/perl(perl)/perl/g' $rpmtopdir/SPECS/$name.spec\n";
164                 print SCRIPT "rpmbuild -bs --nodeps --define '_sourcedir /home/$user/' --define '_srcrpmdir $rpmtopdir/SRPMS' $rpmtopdir/SPECS/$name.spec\n";
165                 close SCRIPT or die "Can't close SRPM construction script: ", $!;
166                 chmod(0711, "/home/$user/makesrpm");
167                 do_cmd("scp /home/$user/makesrpm $user\@$server:/home/$user/makesrpm");
168                 do_cmd("ssh $user\@$server /home/$user/makesrpm");
169         }
170         my $olddir = getcwd();
171         do_cmd("$buildsys/build-freeside");
172         if (-x "$buildsys/refresh-repo") {
173                 do_cmd("$buildsys/refresh-repo");
174         } else {
175                 do_cmd("ssh $user\@$server $rembuild/refresh-repo");
176         }
177 }
178
179 sub do_cmd {
180         my $cmd = shift;
181
182         print "$cmd\n";
183         `$cmd` if !exists($opts{dryrun});
184 }
185
186 1;
187