#!/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<jean-marie.renou
+ard@alcove.fr>');
($od) || ($od = shift) || ($od = "");
($oD) || ($oD = shift) || ($oD = "A standard description for this pack
+age ;)");
($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 de
+fined $oV;
# $line =~ s/^\///;
push @instFiles, "mkdir -p `dirname %{buildroot}$line` || 1" if (-
+f "$line");
push @instFiles, "%{__install} -m $trueMode $line_chrooted %{build
+root}/$line_chrooted" if ( -f "$line");
push @instFiles, "%{__install} -d -m $trueMode $line_chrooted %{bu
+ildroot}/$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 => 'STR
+ING', DELIMITERS => ["<", ">"])
or die "Couldn't construct template: $Text::Template::ERROR"
+;
my @monthname = qw(January February March April May June
July August September October November Dece
+mber);
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 (define
+d $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 e
+nd.";
print "\n -d, --directory=<directory>\t: Root directory ( / by default
+ ).";
print "\n\nPackage Options :";
print "\n -n, --name=<name>\t\t: Package name";
print "\n -v, --version=<version>\t: Package version.";
print "\n -r, --release=<release>\t: Package release.";
print "\n -D, --description=<description>: Package Description.";
print "\n -S, --summary=<summary>\t: Package Summary.";
print "\n -p, --packager=<packager>\t: Packager identity.";
print "\n\nExamples :";
print "\ncd /home/jmrenouard/myrpmBuildDir && find `pwd` -iname '*' -p
+rint | myrpm.pl -V -d /home/jmrenouard/myrpmBuildDir -n toto -b";
print "\n\t\t * Find build the list of all the files in /home/jmrenoua
+rd/myrpmBuildDir.";
print "\n\t\t * myrpm.pl packages all the files /home/jmrenouard/myrpm
+BuildDir in a package with toto as name.";
print "\n\t\t * myrpm.pl consider /home/jmrenouard/myrpmBuildDir as th
+e 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 ins
+talled 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 install
+ed system.";
print "\n\nSubmit bugs at Jean-Marie Renouard <jmrenouard at gmail.com
+>\n";
exit;
}
|