#!/usr/bin/perl use warnings; use strict; use Text::Template; use Archive::Tar; use File::stat; use Getopt::Long; my $tmpDir=$ENV{'HOME'}."/tmp"; my $srcDir=$ENV{'HOME'}."/fedora/SOURCES"; my $specDir=$ENV{'HOME'}."/fedora/SPECS"; my $line=""; my @files=(); my @defFiles=(); my @instFiles=(); Getopt::Long::Configure('bundling'); my ($on, $ov, $or, $op, $oI, $oE, $oh, $ob, $od, $oV, $oD, $oS); GetOptions ("h" => \$oh, "help" => \$oh, "n=s" => \$on, "name=s" => \$on, "b" => \$ob, "build" => \$ob, "V" => \$oV, "verbose" => \$oV, "v=s" => \$ov, "version=s" => \$ov, "d=s" => \$od, "directory=s"=> \$od, "D=s" => \$oD, "description=s"=> \$oD, "S=s" => \$oS, "summary=s"=> \$oS, "r=s" => \$or, "release=s" => \$or, "p=s" => \$op, "packager=s" => \$op); print_usage() if ($oh); ($on) || ($on = shift) || ($on = "TailTail"); ($ov) || ($ov = shift) || ($ov = "0.1"); ($or) || ($or = shift) || ($or = "1"); ($op) || ($op = shift) || ($op = 'Jean-Marie Renouard'); ($od) || ($od = shift) || ($od = ""); ($oD) || ($oD = shift) || ($oD = "A standard description for this package ;)"); ($oS) || ($oS = shift) || ($oS = "A standard summary for this package ;)"); my %lusers; my %lgroups; while (defined($line = <>)) { chop($line); last if ($line eq ""); my $line_chrooted=$line; $line_chrooted =~ s/^$od\///; # print " * Traitement de '$line'\n" if defined $oV; die (" $line does nt exists") unless ( -e $line); my $mode=stat($line)->mode; my $uid =stat($line)->uid; my $gid =stat($line)->gid; my $cmd="cat /etc/passwd | cut -d ':' -f 1,3 | grep $uid"; my @nameu=split (':', `$cmd`); $cmd="cat /etc/group | cut -d ':' -f 1,3 | grep $gid"; my @nameg=split (':', `$cmd`); # print "\n* util=".$nameu[0]; # print "\n* group=".$nameg[0]; $lusers{$nameu[0]}++; $lgroups{$nameg[0]}++; my $trueMode=sprintf( "%04o", $mode & 07777); push @files, "./$line_chrooted"; # print "\t * $line into Tar ball....\n" if defined $oV; # print "\t * $line and $line_chrooted into Spec file....\n" if defined $oV; # $line =~ s/^\///; push @instFiles, "mkdir -p `dirname %{buildroot}$line` || 1" if (-f "$line"); push @instFiles, "%{__install} -m $trueMode $line_chrooted %{buildroot}/$line_chrooted" if ( -f "$line"); push @instFiles, "%{__install} -d -m $trueMode $line_chrooted %{buildroot}/$line_chrooted" if ( -d "$line"); push @defFiles, "%defattr(-, $nameu[0], $nameg[0], $trueMode)", "/$line_chrooted"; } my $pre_code = "echo -e 'PRE'"; foreach my $g (keys(%lgroups)) { $pre_code.="\ngroupadd $g || 1";} foreach my $u (keys(%lusers) ) { $pre_code.="\nadduser $u || 1"; } ############################ # THE TEMPLATE ############################ my $templDef= 'Summary: <$summary> Name: <$name> Version: <$version> Release: <$release> License: GPL URL: http://www.alcove.fr Source0: %{name}-%{version}.tar.gz Group: System/Administration Vendor: AlcĂ´ve Packager: <$packager> Buildarch: i486 BuildRoot: %{_tmppath}/%{name}-%{version}-root %description <$description> %prep #%setup -q #-n %{name}-%{version} %setup -c -q %pre <$pre_code> %build echo -e \'BUILD\' %install mkdir -p %{buildroot} < foreach $i (@instFiles) { $OUT.= "$i\n"; }> %post <$post_code> %preun <$preun_code> %postun <$postun_code> %clean rm -rf %{buildroot} %files < foreach $i (@listOfFiles) { $OUT.= "$i\n"; }> %changelog * <$date> <$packager> <$name>-<$version>-<$release> - <$ChangeLog> - Generated version.'; my $template = Text::Template->new(SOURCE => "$templDef", TYPE => 'STRING', DELIMITERS => ["<", ">"]) or die "Couldn't construct template: $Text::Template::ERROR"; my @monthname = qw(January February March April May June July August September October November December); my %vars = (name => "$on", summary => "$oS", version => "$ov", release => "$or", packager => "$op", pre_code => "$pre_code", post_code => "echo -e 'POST'", preun_code => "echo -e 'PREUN'", postun_code => "echo -e 'POSTUN'", listOfFiles =>\@defFiles, instFiles =>\@instFiles, ChangeLog => 'Test release at the starting point', date => 'Wed May 04 2005',#`date +"%a %b %d %Y"` , description => "$oD", ); my $result = $template->fill_in(HASH => \%vars); die "Couldn't fill in template: $Text::Template::ERROR" unless (defined $result); #die ("erreur Path : $od") unless defined $od; if ( $od eq "") { chdir ("/") } else { chdir($od); } #generate Tarball my $tar = Archive::Tar->new; foreach my $file (@files) { $file =~ s/^\//\.\//; # print "\n$file to Archive...\n"; $tar->add_files( $file); } $tar->write("$srcDir/$vars{'name'}-$vars{'version'}.tar.gz", 1); #Writing spec file open F, "> $specDir/$vars{'name'}-$vars{'version'}.spec"; print F $result if (defined($result)); print $result if (defined($result) && $oV); close F; #my $editor=$ENV{'EDITOR'}; #$editor="/bin/sh /usr/bin/vim" unless (defined($editor)); #`$editor $specDir/$vars{'name'}-$vars{'version'}.spec` if ($oe); #Compiling pakage my $cmd="rpmbuild -ba $specDir/$vars{'name'}-$vars{'version'}.spec"; print "\n#Executing to build package : $cmd\n" if ($oV); print `$cmd` if ($ob); exit 0; sub print_usage { print " Usage: myrpm.pl [OPTION]... \n"; print "myrpm.pl is a automatic spec file generator and builder.\n"; print "Allow you to install freely software on a rpm compliant system and realize a binary package.\n"; print "from a list of file. This program manages rigths and users.\n"; print "It s a simple tool that simplify packaging in chroot mode.\n"; print "\nGeneral Options :"; print "\n -h, --help\t\t\t: Print this help."; print "\n -V, --verbose\t\t\t: Print debug information, verbose mode."; print "\n -b, --build\t\t\t: Build the package automattically at the end."; print "\n -d, --directory=\t: Root directory ( / by default )."; print "\n\nPackage Options :"; print "\n -n, --name=\t\t: Package name"; print "\n -v, --version=\t: Package version."; print "\n -r, --release=\t: Package release."; print "\n -D, --description=: Package Description."; print "\n -S, --summary=\t: Package Summary."; print "\n -p, --packager=\t: Packager identity."; print "\n\nExamples :"; print "\ncd /home/jmrenouard/myrpmBuildDir && find `pwd` -iname '*' -print | myrpm.pl -V -d /home/jmrenouard/myrpmBuildDir -n toto -b"; print "\n\t\t * Find build the list of all the files in /home/jmrenouard/myrpmBuildDir."; print "\n\t\t * myrpm.pl packages all the files /home/jmrenouard/myrpmBuildDir in a package with toto as name."; print "\n\t\t * myrpm.pl consider /home/jmrenouard/myrpmBuildDir as the root of all the files so all this files will be installed from the root file system by the rpm program."; print "\n\nrpm -ql yum | myrpm.pl -V -n yum -r 1_jmr -b"; print "\n\t\t * Rpm gives the list of the files in the yum package installed on the system."; print "\n\t\t * myrpm.pl packages all the files in a package with yum as name and 1_jmr as release."; print "\n\t\t * This is a new way to package modification on a installed system."; print "\n\nSubmit bugs at Jean-Marie Renouard \n"; exit; }