[LON-CAPA-cvs] cvs: loncom /build make_rpm.pl
harris41
lon-capa-cvs@mail.lon-capa.org
Wed, 18 Dec 2002 17:56:34 -0000
This is a MIME encoded message
--harris411040234194
Content-Type: text/plain
harris41 Wed Dec 18 12:56:34 2002 EDT
Modified files:
/loncom/build make_rpm.pl
Log:
using latest
http://www.cpan.org/authors/id/S/SH/SHARRISON/make_rpm-2.0.pl;
accepts release command-line argument in addition to version number;
broader character set for filenames; synchronized with
http://www.cpan.org/authors/id/S/SH/SHARRISON/RPM-Tools-0.8.tar.gz;
works on redhat 8 (supports rpm >4.1... also still supports rpm 3.x and
rpm 4.0.x)
--harris411040234194
Content-Type: text/plain
Content-Disposition: attachment; filename="harris41-20021218125634.txt"
Index: loncom/build/make_rpm.pl
diff -u loncom/build/make_rpm.pl:1.20 loncom/build/make_rpm.pl:1.21
--- loncom/build/make_rpm.pl:1.20 Wed Jul 3 17:17:56 2002
+++ loncom/build/make_rpm.pl Wed Dec 18 12:56:34 2002
@@ -8,13 +8,14 @@
# The LearningOnline Network with CAPA
# make_rpm.pl - make RedHat package manager file (A CLEAN AND CONFIGURABLE WAY)
#
-# $Id: make_rpm.pl,v 1.20 2002/07/03 21:17:56 harris41 Exp $
+# $Id: make_rpm.pl,v 1.21 2002/12/18 17:56:34 harris41 Exp $
#
# Written by Scott Harrison, harris41@msu.edu
#
# Copyright Michigan State University Board of Trustees
#
-# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
+# This file was written to help the LearningOnline Network with CAPA (LON-CAPA)
+# project.
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -37,7 +38,7 @@
# YEAR=2001
# 1/8,1/10,1/13,1/23,5/16 - Scott Harrison
# YEAR=2002
-# 1/4,1/8,1/9,2/13,4/7 - Scott Harrison
+# 1/4,1/8,1/9,2/13,4/7,12/18 - Scott Harrison
#
###
@@ -68,11 +69,14 @@
## ##
###############################################################################
+my $VERSION = 2.0;
+
use strict;
# ------------------------ Check to see if RPM builder application is available
-unless (-e '/usr/lib/rpm/rpmrc') { # part of the expected rpm software package
+unless (-e '/usr/lib/rpm/rpmrc') # part of the expected rpm software package
+ {
print(<<END);
**** ERROR **** This script only works with a properly installed RPM builder
application.
@@ -80,24 +84,26 @@
Script aborting.
END
exit(1);
-}
+ }
# ---------------------------------------------- Read in command-line arguments
-my ($tag,$version,$configuration_files,$documentation_files,
+my ($tag,$version,$release,$configuration_files,$documentation_files,
$pathprefix,$customize)=@ARGV;
@ARGV=(); # read standard input based on a pipe, not a command-line argument
# standardize pathprefix argument
$pathprefix=~s/\/$//; # OTHERWISE THE BEGINNING SLASH MIGHT BE REMOVED
-if (!$version) {# version should be defined and string length greater than zero
+if (!$version) # version should be defined and string length greater than zero
+ {
print(<<END);
See "perldoc make_rpm.pl" for more information.
Usage:
- <STDIN> | perl make_rpm.pl <TAG> <VERSION> [CONFIGURATION_FILES]
- [DOCUMENTATION_FILES] [PATHPREFIX] [CUSTOMIZATION_XML]
+ <STDIN> | perl make_rpm.pl <TAG> <VERSION> <RELEASE>
+ [CONFIGURATION_FILES] [DOCUMENTATION_FILES] [PATHPREFIX]
+ [CUSTOMIZATION_XML]
Standard input provides the list of files to work with.
TAG, required descriptive tag. For example, a kerberos software
@@ -106,7 +112,10 @@
a pre-existing directory named ./TAG.)
VERSION, required version. Needed to generate version information
for the RPM. It is recommended that this be in the format N.M where N and
-M are integers.
+M are integers. For example, 0.3, 4.1, and 8.9 are all valid version numbers.
+RELEASE, required release number. Needed to generate release information
+for the RPM. This is typically an integer, but can also be given descriptive
+text such as 'rh7' or 'mandrake8a'.
CONFIGURATION_FILES, optional comma-separated listing of files to
be treated as configuration files by RPM (and thus subject to saving
during RPM upgrades).
@@ -123,26 +132,28 @@
"perldoc make_rpm.pl").
END
exit(1);
-}
+ }
# ----- Generate temporary directories (subdirs of first command-line argument)
# Do some error-checking related to important first command-line argument.
-if ($tag=~/\W/) { # non-alphanumeric characters cause problems
+if ($tag=~/[^\w-]/) # non-alphanumeric characters cause problems
+ {
print(<<END);
**** ERROR **** Invalid tag name "$tag"
(The first command-line argument must be alphanumeric characters without
spaces.)
END
exit(1);
-}
-if (-e $tag) { # do not overwrite or conflict with existing data
+ }
+if (-e $tag) # do not overwrite or conflict with existing data
+ {
print(<<END);
**** ERROR **** a file or directory "./$tag" already exists
(This program needs to generate a temporary directory named "$tag".)
END
exit(1);
-}
+ }
print('Generating temporary directory ./'.$tag."\n");
mkdir($tag,0755) or die("**** ERROR **** cannot generate $tag directory\n");
@@ -171,13 +182,15 @@
close(IN);
open(RPMRC,">$tag/SPECS/rpmrc");
-foreach my $line (@lines) {
- if ($line=~/^macrofiles/) {
+foreach my $line (@lines)
+ {
+ if ($line=~/^macrofiles/)
+ {
chomp($line);
$line.=":$currentdir/SPECS/rpmmacros\n";
- }
+ }
print(RPMRC $line);
-}
+ }
close(RPMRC);
open(RPMMACROS,">$tag/SPECS/rpmmacros");
@@ -193,7 +206,8 @@
# ------------------------- Perform variable initializations and customizations
my $cu=''; # string that holds customization XML file contents
-if (length($customize)>0) {
+if (length($customize)>0)
+ {
print('Reading in XML-formatted customizations from '.$customize."\n");
open(IN,"<$customize") or
(
@@ -203,7 +217,7 @@
my @clines=(<IN>);
$cu=join('',@clines);
close(IN);
-}
+ }
# tv - temporary variable (if it exists inside the XML document) then use it,
# otherwise don't overwrite existing values of variables
@@ -217,10 +231,11 @@
$name=~s/\<tag \/\>/$tag/g;
# (When in doubt, be paranoid about overwriting things.)
-if (-e "$name-$version-1.i386.rpm") {
+if (-e "$name-$version-1.i386.rpm")
+ {
print(`cd $invokingdir; rm -Rf $tag`); # clean temporary filespace in use
die("**** ERROR **** $name-$version-1.i386.rpm already exists.\n");
-}
+ }
my $requires='';
# read in relevant requires info from customization file (if applicable)
@@ -247,7 +262,10 @@
$tv=grabtag('copyright',$cu,1); $copyright=$tv if $tv;
$copyright=~s/\<tag \/\>/$tag/g;
-open(SPEC,">$tag/SPECS/$name-$version.spec");
+my $rpmgroup="Utilities/System";
+# read in copyright from customization if available
+$tv=grabtag('group',$cu,1); $rpmgroup=$tv if $tv;
+$rpmgroup=~s/\<tag \/\>/$tag/g;
my $vendor='Me';
# read in vendor from customization if available
@@ -267,15 +285,16 @@
# ------------------------------------- Print header information for .spec file
print('Print header information for .spec file'."\n");
+open(SPEC,">$tag/SPECS/$name-$version.spec");
print(SPEC <<END);
Summary: $summary
Name: $name
Version: $version
-Release: 1
+Release: $release
Vendor: $vendor
BuildRoot: $currentdir/BuildRoot
Copyright: $copyright
-Group: Utilities/System
+Group: $rpmgroup
Source: $name-$version.tar.gz
AutoReqProv: $autoreqprov
$requires
@@ -310,45 +329,55 @@
my %Makefile;
my %dotspecfile;
-foreach my $file (<>) {
+foreach my $file (<>)
+ {
chomp($file);
my $comment="";
- if ($file=~/\s+\#(.*)$/) {
+ if ($file=~/\s+\#(.*)$/)
+ {
$file=~s/\s+\#(.*)$//;
$comment=$1;
- }
+ }
my $directive="";
- if ($comment=~/config\(noreplace\)/) {
+ if ($comment=~/config\(noreplace\)/)
+ {
$directive="\%config(noreplace) ";
- }
- elsif ($comment=~/config/) {
+ }
+ elsif ($comment=~/config/)
+ {
$directive="\%config ";
- }
- elsif ($comment=~/doc/) {
+ }
+ elsif ($comment=~/doc/)
+ {
$directive="\%doc";
- }
- if (($type,$size,$octalmode,$user,$group)=find_info($file)) {
+ }
+ if (($type,$size,$octalmode,$user,$group)=find_info($file))
+ {
$octalmode="0" . $octalmode if length($octalmode)<4;
- if ($pathprefix) {
+ if ($pathprefix)
+ {
$file=~s/^$pathprefix//;
- }
- if ($type eq "files") {
+ }
+ if ($type eq "files")
+ {
push(@{$BinaryRootMakefile{$type}},"\tinstall -D -m $octalmode ".
"$pathprefix$file $binaryroot$file\n");
push(@{$Makefile{$type}},"\tinstall -D -m $octalmode ".
"\$(SOURCE)$file \$(ROOT)$file\n");
push(@{$dotspecfile{$type}},"$directive\%attr($octalmode,$user,".
"$group) $file\n");
- }
- elsif ($type eq "directories") {
+ }
+ elsif ($type eq "directories")
+ {
push(@{$BinaryRootMakefile{$type}},"\tinstall -m $octalmode -d ".
"$binaryroot$file\n");
push(@{$Makefile{$type}},"\tinstall -m $octalmode -d ".
"\$(SOURCE)$file \$(ROOT)$file\n");
push(@{$dotspecfile{$type}},"\%dir \%attr($octalmode,$user,".
"$group) $file\n");
- }
- elsif ($type eq "links") {
+ }
+ elsif ($type eq "links")
+ {
my $link=$size; # I use the size variable to pass the link value
# from the subroutine find_info
$link=~s/^$pathprefix//;
@@ -356,9 +385,9 @@
"\tln -s $link $binaryroot$file\n");
push(@{$Makefile{$type}},"\tln -s $link \$(ROOT)$file\n");
push(@{$dotspecfile{$type}},"\%attr(-,$user,$group) $file\n");
- }
- }
-}
+ }
+ }
+ }
# -------------------------------------- Generate SRPM and BinaryRoot Makefiles
print('Generate SRPM and BinaryRoot Makefiles.'."\n");
@@ -370,7 +399,8 @@
open(OUTS,">$tag/SOURCES/$name-$version/Makefile");
open(OUTB, ">$tag/BinaryRootMakefile");
-foreach $type ("directories","files","links") {
+foreach $type ("directories","files","links")
+ {
print(OUTS "$type\:\n");
print(OUTS join("",@{$Makefile{$type}})) if $Makefile{$type};
print(OUTS "\n");
@@ -379,7 +409,7 @@
if $BinaryRootMakefile{$type};
print(OUTB "\n");
print(SPEC join("",@{$dotspecfile{$type}})) if $dotspecfile{$type};
-}
+ }
close(OUTB);
close(OUTS);
@@ -397,9 +427,47 @@
my $command="cd $currentdir/SOURCES; tar czvf $name-$version.tar.gz ".
"$name-$version";
print(`$command`);
-$command="cd $currentdir/SPECS; rpm --rcfile=./rpmrc -ba ".
- "$name-$version.spec; cd ../RPMS/i386; cp -v ".
- "$name-$version-1.i386.rpm $invokingdir/.";
+
+# ----------------------------------------- Define commands to be executed.
+# command1a works for rpm version <=4.0.2
+# command1b works for rpm version >4.0.4
+
+my $arch = 'i386';
+
+my $command1a="cd $currentdir/SPECS; rpm --rcfile=./rpmrc --target=$arch -ba ".
+ "$name-$version.spec";
+
+my $rpmcommand = 'rpm';
+if (`rpmbuild --version`) {$rpmcommand = 'rpmbuild';}
+my $command1b="cd $currentdir/SPECS; $rpmcommand --rcfile=./rpmrc ".
+ "-ba --target $arch ".
+ "$name-$version.spec";
+
+# ---------------------------------------------- Run the "rpm -ba" command.
+# The strategy here is to...try one approach, and then the other.
+print "$command1a\n";
+print (`$command1a`);
+if ($?!=0)
+ {
+ print(<<END);
+**** WARNING **** RPM compilation failed for rpm version 4.0.2 command syntax
+(...trying another command syntax...)
+END
+ print "$command1b\n";
+ print (`$command1b`);
+ if ($?!=0)
+ {
+ print(<<END);
+**** ERROR **** RPM compilation failed for rpm version 4.0.4 command syntax
+(...no more syntax choices to try...)
+END
+ exit(1);
+ }
+ }
+
+# -------------------------------------------------------- Retrieve binary rpm.
+$command="cd $currentdir/RPMS/$arch; cp -v ".
+ "$name-$version-$release.$arch.rpm $invokingdir/.";
print(`$command`);
# --------------------------------------------------------- clean everything up
@@ -411,39 +479,47 @@
# ----------------------------------------------------------------- SUBROUTINES
# ----- Subroutine: find_info - recursively gather information from a directory
-sub find_info {
+sub find_info
+ {
my ($file)=@_;
my $line='';
- if (($line=`find $file -type f -prune`)=~/^$file\n/) {
+ my $safefile = $file;
+ $safefile =~ s/\+/\\+/g; # Better regular expression matching.
+ if (($line=`find $file -type f -prune`)=~/^$safefile\n/)
+ {
$line=`find $file -type f -prune -printf "\%s\t\%m\t\%u\t\%g"`;
return("files",split(/\t/,$line));
- }
- elsif (($line=`find $file -type d -prune`)=~/^$file\n/) {
+ }
+ elsif (($line=`find $file -type d -prune`)=~/^$safefile\n/)
+ {
$line=`find $file -type d -prune -printf "\%s\t\%m\t\%u\t\%g"`;
return("directories",split(/\t/,$line));
- }
- elsif (($line=`find $file -type l -prune`)=~/^$file\n/) {
+ }
+ elsif (($line=`find $file -type l -prune`)=~/^$safefile\n/)
+ {
$line=`find $file -type l -prune -printf "\%l\t\%m\t\%u\t\%g"`;
return("links",split(/\t/,$line));
- }
+ }
die("**** ERROR **** $file is neither a directory, soft link, or file.\n");
-}
+ }
# ------------------------- Subroutine: grabtag - grab a tag from an xml string
-sub grabtag {
+sub grabtag
+ {
my ($tag,$text,$clean)=@_;
# meant to be quick and dirty as opposed to a formal state machine parser
my $value='';
$cu=~/\<$tag\>(.*?)\<\/$tag\>/s;
$value=$1; $value=~s/^\s+//;
- if ($clean==1) {
+ if ($clean==1)
+ {
$value=~s/\n\s/ /g;
$value=~s/\s\n/ /g;
$value=~s/\n/ /g;
$value=~s/\s+$//;
- }
+ }
return($value);
-}
+ }
# ----------------------------------------------------- Plain Old Documentation
@@ -455,7 +531,7 @@
=head1 SYNOPSIS
-Usage: <STDIN> | make_rpm.pl <TAG> <VERSION>
+Usage: <STDIN> | make_rpm.pl <TAG> <VERSION> <RELEASE>
[CONFIGURATION_FILES] [DOCUMENTATION_FILES]
[PATHPREFIX] [CUSTOMIZATION_XML]
@@ -527,6 +603,10 @@
information for the RPM. This should be in the format N.M where N and M are
integers.
+I<RELEASE> ($release), B<required> release number. Needed to generate release
+information for the RPM. This is typically an integer, but can also be given
+descriptive text such as 'rh7' or 'mandrake8a'.
+
I<CONFIGURATION_FILES>, B<optional> comma-separated listing of files to
be treated as configuration files by RPM (and thus subject to saving
during RPM upgrades). Configuration files can also be specified in
@@ -552,19 +632,28 @@
=head2 Examples
bash$ find /notreallyrootdir | perl make_rpm.pl \
- makemoney 3.1 '' \
+ makemoney 3.1 1 '' \
'/usr/doc/man/man3/makemoney.3' \
/notreallyrootdir
would generate makemoney-3.1-1.i386.rpm
bash$ find /usr/local/bin | \
- perl make_rpm.pl mybinfiles 1.0
- would generate mybinfiles-1.0-1.i386.rpm
+ perl make_rpm.pl mybinfiles 1.0 2
+ would generate mybinfiles-1.0-2.i386.rpm
+
+ bash$ echo '/sycamore33/tree.txt' | \
+ perl make_rpm.pl sycamore 1.0 2 '' '' '/sycamore33'
+ would generate sycamore-1.0-2.i386.rpm
+ Note that the generated sycamore rpm would install files at the root
+ '/' directory (not underneath /sycamore33); thus a file named
+ '/tree.txt' is created, NOT '/sycamore33/tree.txt'.
bash$ find /home/joe/romeodir/buildloc | \
perl make_rpm.pl romeo \
- 1.0 '' '' '/home/joe/romeodir/buildloc' customize.xml
+ 1.0 3 '' '' '/home/joe/romeodir/buildloc' customize.xml
would generate romeo with customizations from customize.xml.
+ Note that the generated romeo rpm would install files at the root
+ '/' directory (not underneath /home/joe/romedir/buildloc).
The I<CUSTOMIZATION_XML> argument represents a way to customize the
numerous variables associated with RPMs. This argument represents
@@ -690,8 +779,8 @@
=item *
-(required) a descriptive tag and a version tag for the naming of the
-RPM software package;
+(required) a descriptive tag, version tag, and release tag for the naming of
+the RPM software package;
=item *
@@ -715,7 +804,7 @@
For example, user "joe" running
- cat file_list.txt | make_rpm.pl krb4 1.0
+ cat file_list.txt | make_rpm.pl krb4 1.0 1
would temporarily generate F</home/joe/krb4/>.
--harris411040234194--