[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--