[LON-CAPA-cvs] cvs: loncom /build make_rpm.pl

harris41 lon-capa-cvs@mail.lon-capa.org
Sun, 07 Apr 2002 19:35:28 -0000


This is a MIME encoded message

--harris411018208128
Content-Type: text/plain

harris41		Sun Apr  7 15:35:28 2002 EDT

  Modified files:              
    /loncom/build	make_rpm.pl 
  Log:
  cleaning up documentation; testing for more error conditions; beautifying code
  
  
--harris411018208128
Content-Type: text/plain
Content-Disposition: attachment; filename="harris41-20020407153528.txt"

Index: loncom/build/make_rpm.pl
diff -u loncom/build/make_rpm.pl:1.15 loncom/build/make_rpm.pl:1.16
--- loncom/build/make_rpm.pl:1.15	Sat Feb 16 14:53:46 2002
+++ loncom/build/make_rpm.pl	Sun Apr  7 15:35:27 2002
@@ -1,9 +1,14 @@
 #!/usr/bin/perl
 
+# -------------------------------------------------------- Documentation notice
+# Run "perldoc ./make_rpm.pl" in order to best view the software documentation
+# internalized in this program.
+
+# --------------------------------------------------------- License Information
 # The LearningOnline Network with CAPA
 # make_rpm.pl - make RedHat package manager file (A CLEAN AND CONFIGURABLE WAY)
 #
-# $Id: make_rpm.pl,v 1.15 2002/02/16 19:53:46 harris41 Exp $
+# $Id: make_rpm.pl,v 1.16 2002/04/07 19:35:27 harris41 Exp $
 #
 # Written by Scott Harrison, harris41@msu.edu
 #
@@ -32,7 +37,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 - Scott Harrison
+# 1/4,1/8,1/9,2/13,4/7 - Scott Harrison
 #
 ###
 
@@ -45,10 +50,10 @@
 ## ORGANIZATION OF THIS PERL SCRIPT                                          ##
 ##                                                                           ##
 ## 1. Check to see if RPM builder application is available                   ##
-## 2. Read in arguments                                                      ##
-## 3. Generate temporary directories                                         ##
+## 2. Read in command-line arguments                                         ##
+## 3. Generate temporary directories (subdirs of first command-line argument)##
 ## 4. Initialize some variables                                              ##
-## 5. Create a standalone rpm building environment                           ##
+## 5. Create a stand-alone rpm building environment                          ##
 ## 6. Perform variable initializations and customizations                    ##
 ## 7. Print header information for .spec file                                ##
 ## 8. Process file list and generate information                             ##
@@ -67,23 +72,24 @@
 
 # ------------------------ Check to see if RPM builder application is available
 
-unless (-e '/usr/lib/rpm/rpmrc') {
-    print <<END;
-ERROR: This script only works with a properly installed RPM builder
+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.  
 Cannot find /usr/lib/rpm/rpmrc, so cannot generate customized rpmrc file.
 Script aborting.
 END
+    exit(1);
 }
 
-# ----------------------------------------------------------- Read in arguments
+# ---------------------------------------------- Read in command-line arguments
 
 my ($tag,$version,$configuration_files,$documentation_files,
     $pathprefix,$customize)=@ARGV;
-@ARGV=();
+@ARGV=(); # read standard input based on a pipe, not a command-line argument
 
-if (!$version) {
-    print <<END;
+if (!$version) {# version should be defined and string length greater than zero
+    print(<<END);
 See "perldoc make_rpm.pl" for more information.
 
 Usage: 
@@ -92,10 +98,12 @@
 
 Standard input provides the list of files to work with.
 TAG, required descriptive tag.  For example, a kerberos software
-package might be tagged as "krb4".
+package might be tagged as "krb4". (This value is also used in
+the generation of a temporary directory; you cannot have
+a pre-existing directory named ./TAG.)
 VERSION, required version.  Needed to generate version information
-for the RPM.  This should be in the format N.M where N and M are
-integers.
+for the RPM.  It is recommended that this be in the format N.M where N and
+M are integers.
 CONFIGURATION_FILES, optional comma-separated listing of files to
 be treated as configuration files by RPM (and thus subject to saving
 during RPM upgrades).
@@ -108,78 +116,110 @@
 after PATHPREFIX.
 CUSTOMIZATION_XML, allows for customizing various pieces of information such
 as vendor, summary, name, copyright, group, autoreqprov, requires, prereq,
-description, and pre-installation scripts (see more in the POD;
-perldoc make_rpml.pl).
+description, and pre-installation scripts (see more in the POD,
+"perldoc make_rpm.pl").
 END
-    exit;
+    exit(1);
 }
 
-mkdir $tag,0755;
-mkdir "$tag/BuildRoot",0755;
-mkdir "$tag/SOURCES",0755;
-mkdir "$tag/SPECS",0755;
-mkdir "$tag/BUILD",0755;
-mkdir "$tag/SRPMS",0755;
-mkdir "$tag/RPMS",0755;
-mkdir "$tag/RPMS/i386",0755;
+# ----- 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
+    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
+    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");
+mkdir("$tag/BuildRoot",0755);
+mkdir("$tag/SOURCES",0755);
+mkdir("$tag/SPECS",0755);
+mkdir("$tag/BUILD",0755);
+mkdir("$tag/SRPMS",0755);
+mkdir("$tag/RPMS",0755);
+mkdir("$tag/RPMS/i386",0755);
 
 # -------------------------------------------------------- Initialize variables
 
 my $file;
-my $binaryroot="$tag/BinaryRoot";
+my $binaryroot=$tag.'/BinaryRoot';
 my ($type,$size,$octalmode,$user,$group);
 
-my $currentdir=`pwd`; chop $currentdir; my $invokingdir=$currentdir;
-$currentdir.="/$tag";
+my $currentdir=`pwd`; chomp($currentdir); my $invokingdir=$currentdir;
+$currentdir.='/'.$tag;
 
-# -------------------------------- Create a standalone rpm building environment
+# ------------------------------- Create a stand-alone rpm building environment
 
-open (IN,'</usr/lib/rpm/rpmrc') or die('Cannot open /usr/lib/rpm/rpmrc');
+print('Creating stand-alone rpm build environment.'."\n");
+open(IN,'</usr/lib/rpm/rpmrc') or die('Cannot open /usr/lib/rpm/rpmrc'."\n");
 my @lines=<IN>;
-close IN;
+close(IN);
 
-open (RPMRC,">$tag/SPECS/rpmrc");
+open(RPMRC,">$tag/SPECS/rpmrc");
 foreach my $line (@lines) {
     if ($line=~/^macrofiles/) {
-	chop $line;
+	chomp($line);
 	$line.=":$currentdir/SPECS/rpmmacros\n";
     }
-    print RPMRC $line;
+    print(RPMRC $line);
 }
-close RPMRC;
+close(RPMRC);
 
-open (RPMMACROS,">$tag/SPECS/rpmmacros");
-print RPMMACROS <<END;
+open(RPMMACROS,">$tag/SPECS/rpmmacros");
+print(RPMMACROS <<END);
 \%_topdir $currentdir
 \%__spec_install_post    \\
     /usr/lib/rpm/brp-strip \\
     /usr/lib/rpm/brp-strip-comment-note \\
 \%{nil}
 END
-close RPMMACROS;
+close(RPMMACROS);
 
 # ------------------------- Perform variable initializations and customizations
 
-my $cu;
-if ($customize) {
-    open (IN,"<$customize") or die("Cannot open $customize");
+my $cu=''; # string that holds customization XML file contents
+if (length($customize)>0) {
+    print('Reading in XML-formatted customizations from '.$customize."\n");
+    open(IN,"<$customize") or
+    (
+     print(`cd $invokingdir; rm -Rf $tag`) and
+     die('Cannot open customization file "'.$customize.'"'."\n")
+    );
     my @clines=(<IN>);
     $cu=join('',@clines);
-    close IN;
+    close(IN);
 }
-my $tv; # tag value variable for storing retrievals from $cu
 
-# (Sure. We could use HTML::TokeParser here.. but that wouldn't be fun now,
+# tv - temporary variable (if it exists inside the XML document) then use it,
+# otherwise don't overwrite existing values of variables
+my $tv='';
+
+# (Sure. We could use HTML::TokeParser here... but that wouldn't be fun now,
 # would it?)
 my $name=$tag;
 # read in name from customization if available
 $tv=grabtag('name',$cu,1); $name=$tv if $tv;
 $name=~s/\<tag \/\>/$tag/g;
 
-# okay.. now we can generate this needed directory
-mkdir "$tag/SOURCES/$name-$version",0755;
+# (When in doubt, be paranoid about overwriting things.)
+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="";
+my $requires='';
 # read in relevant requires info from customization file (if applicable)
 # note that "PreReq: item" controls order of CD-ROM installation (if you
 # are making a customized CD-ROM)
@@ -190,7 +230,7 @@
 $requires=~s/\s*\<item\>\s*/\n/g;
 $requires=~s/^\s+//s;
 
-my $summary="Files for the $name software package.";
+my $summary='Files for the '.$name.' software package.';
 # read in summary from customization if available
 $tv=grabtag('summary',$cu,1); $summary=$tv if $tv;
 $summary=~s/\<tag \/\>/$tag/g;
@@ -204,7 +244,7 @@
 $tv=grabtag('copyright',$cu,1); $copyright=$tv if $tv;
 $copyright=~s/\<tag \/\>/$tag/g;
 
-open (SPEC,">$tag/SPECS/$name-$version.spec");
+open(SPEC,">$tag/SPECS/$name-$version.spec");
 
 my $vendor='Me';
 # read in vendor from customization if available
@@ -216,14 +256,14 @@
 $tv=grabtag('description',$cu,0); $description=$tv if $tv;
 $description=~s/\<tag \/\>/$tag/g;
 
-my $pre="";
+my $pre='';
 # read in pre-installation script if available
 $tv=grabtag('pre',$cu,0); $pre=$tv if $tv;
 $pre=~s/\<tag \/\>/$tag/g;
 
 # ------------------------------------- Print header information for .spec file
 
-print SPEC <<END;
+print(SPEC <<END);
 Summary: $summary
 Name: $name
 Version: $version
@@ -265,8 +305,8 @@
 my %Makefile;
 my %dotspecfile;
 
-foreach $file (<>) {
-    chop $file;
+foreach my $file (<>) {
+    chomp($file);
     my $comment="";
     if ($file=~/\s+\#(.*)$/) {
 	$file=~s/\s+\#(.*)$//;
@@ -288,51 +328,56 @@
 	    $file=~s/^$pathprefix//;
 	}
 	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";
+	    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") {
-	    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";
+	    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") {
 	    my $link=$size; # I use the size variable to pass the link value
                             # from the subroutine find_info
 	    $link=~s/^$pathprefix//;
-	    push @{$BinaryRootMakefile{$type}},
-	         "\tln -s $link $binaryroot$file\n";
-	    push @{$Makefile{$type}},"\tln -s $link \$(ROOT)$file\n";
-	    push @{$dotspecfile{$type}},"\%attr(-,$user,$group) $file\n";
+	    push(@{$BinaryRootMakefile{$type}},
+	         "\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
 
-open OUTS, ">$tag/SOURCES/$name-$version/Makefile";
-open OUTB, ">$tag/BinaryRootMakefile";
+# Generate a much needed directory.
+# This directory is meant to hold all source code information
+# necessary for converting .src.rpm files into .i386.rpm files.
+mkdir("$tag/SOURCES/$name-$version",0755);
+
+open(OUTS,">$tag/SOURCES/$name-$version/Makefile");
+open(OUTB, ">$tag/BinaryRootMakefile");
 foreach $type ("directories","files","links") {
-    print OUTS "$type\:\n";
-    print OUTS join("",@{$Makefile{$type}}) if $Makefile{$type};
-    print OUTS "\n";
-    print OUTB "$type\:\n";
-    print OUTB join("",@{$BinaryRootMakefile{$type}})
+    print(OUTS "$type\:\n");
+    print(OUTS join("",@{$Makefile{$type}})) if $Makefile{$type};
+    print(OUTS "\n");
+    print(OUTB "$type\:\n");
+    print(OUTB join("",@{$BinaryRootMakefile{$type}}))
 	if $BinaryRootMakefile{$type};
-    print OUTB "\n";
-    print SPEC join("",@{$dotspecfile{$type}}) if $dotspecfile{$type};
+    print(OUTB "\n");
+    print(SPEC join("",@{$dotspecfile{$type}})) if $dotspecfile{$type};
 }
-close OUTB;
-close OUTS;
+close(OUTB);
+close(OUTS);
 
-close SPEC;
+close(SPEC);
 
 # ------------------ mirror copy (BinaryRoot) files under a temporary directory
 
@@ -341,109 +386,227 @@
 `make -f $tag/BinaryRootMakefile links`;
 
 # ------------------------------------------------- roll everything into an RPM
-
+print('Build a tarball and then run the rpm -ba command.'."\n");
 my $command="cd $currentdir/SOURCES; tar czvf $name-$version.tar.gz ".
     "$name-$version";
-print `$command`;
+print(`$command`);
 $command="cd $currentdir/SPECS; rpm --rcfile=./rpmrc -ba ".
-    "$name-$version.spec; cd ../RPMS/i386; cp ".
+    "$name-$version.spec; cd ../RPMS/i386; cp -v ".
     "$name-$version-1.i386.rpm $invokingdir/.";
-print `$command`;
+print(`$command`);
 
 # --------------------------------------------------------- clean everything up
+print('Removing temporary ./'.$tag.' directory'."\n");
+print(`cd $invokingdir; rm -Rf $tag`);
 
-print `cd $invokingdir; rm -Rf $tag`;
+# -------------------------------------------------------- Yeah! We're all done
+print('Success. Script complete.'."\n");
 
 # ----------------------------------------------------------------- SUBROUTINES
 # ----- Subroutine: find_info - recursively gather information from a directory
 sub find_info {
     my ($file)=@_;
-    my $line;
+    my $line='';
     if (($line=`find $file -type f -prune`)=~/^$file\n/) {
 	$line=`find $file -type f -prune -printf "\%s\t\%m\t\%u\t\%g"`;
-	return ("files",split(/\t/,$line));
+	return("files",split(/\t/,$line));
     }
     elsif (($line=`find $file -type d -prune`)=~/^$file\n/) {
 	$line=`find $file -type d -prune -printf "\%s\t\%m\t\%u\t\%g"`;
-	return ("directories",split(/\t/,$line));
+	return("directories",split(/\t/,$line));
     }
     elsif (($line=`find $file -type l -prune`)=~/^$file\n/) {
 	$line=`find $file -type l -prune -printf "\%l\t\%m\t\%u\t\%g"`;
-	return ("links",split(/\t/,$line));
+	return("links",split(/\t/,$line));
     }
-    die("**** ERROR **** $file is neither a directory, soft link, or file");
+    die("**** ERROR **** $file is neither a directory, soft link, or file.\n");
 }
 
 # ------------------------- Subroutine: grabtag - grab a tag from an xml string
 sub grabtag {
     my ($tag,$text,$clean)=@_;
     # meant to be quick and dirty as opposed to a formal state machine parser
-    my $value;
+    my $value='';
     $cu=~/\<$tag\>(.*?)\<\/$tag\>/s; 
     $value=$1; $value=~s/^\s+//;
-    if ($clean) {
+    if ($clean==1) {
 	$value=~s/\n\s/ /g;
 	$value=~s/\s\n/ /g;
 	$value=~s/\n/ /g;
 	$value=~s/\s+$//;
     }
-    return $value;
+    return($value);
 }
 
 # ----------------------------------------------------- Plain Old Documentation
 
 =head1 NAME
 
-make_rpm.pl - automatically generate an RPM software package
+make_rpm.pl - cleanly generate an rpm in a simple one-line command
 
 =head1 SYNOPSIS
 
-Usage: <TAG> <VERSION> [CONFIGURATION_FILES]
- [DOCUMENTATION_FILES] [PATHPREFIX] [CUSTOMIZATION_XML]
+Usage: <STDIN> | make_rpm.pl <TAG> <VERSION>
+       [CONFIGURATION_FILES] [DOCUMENTATION_FILES]
+       [PATHPREFIX] [CUSTOMIZATION_XML]
+
+=head2 The standard input stream
+
+I<STDIN>, the standard input stream, provides the list of files to work
+with.  This list of file names must give the complete filesystem
+path starting from '/'.
 
-Standard input provides the list of files to work with.
+=over 4
 
-TAG, required descriptive tag.  For example, a kerberos software
+=item * For instance, the following is invalid:
+
+ romeodir/file1.txt # ** INVALID! ** missing leading filesystem path
+ romeodir/file2.txt
+ romeodir/file3.txt
+
+=item * Whereas, the following is valid:
+
+ /home/joe/romeodir/file1.txt
+ /home/joe/romeodir/file2.txt
+ /home/joe/romeodir/file3.txt
+
+=item * In terms of the B<find> command,
+
+ "find romeodir | perl make_rpm.pl [COMMAND-LINE ARGUMENTS]"
+
+is incorrect, whereas
+
+ "find /home/joe/romeodir |perl make_rpm.pl [COMMAND-LINE ARGUMENTS]"
+
+or
+
+ "find `pwd`/romeodir |perl make_rpm.pl [COMMAND-LINE ARGUMENTS]"
+
+is correct.
+
+=back
+
+The standard input stream can also
+specify configuration files and documentation files through
+'#'-style commenting.
+
+For example, the following file listing encodes some of these directives:
+
+ /home/joe/romeodir/buildloc/etc/romeo/user.conf # config(noreplace)
+ /home/joe/romeodir/buildloc/etc/romeo/juliet.conf # config
+ /home/joe/romeodir/buildloc/doc/man/man.1/romeo.1 # doc
+ /home/joe/romeodir/buildloc/doc/man/man.1/romeo_talks.1 # doc
+ /home/joe/romeodir/buildloc/usr/local/bin/where_art_thou
+ /home/joe/romeodir/buildloc/usr/local/bin/romeo_talks
+
+The I<config> directive controls how files are replaced
+and/or backed up when a user attempts to install (B<rpm -i>) the F<.rpm>
+file generated by B<make_rpm.pl>.  The I<doc> directive controls how a
+given file is placed inside special documentation directories
+on the filesystem during rpm installation (B<rpm -i>).
+(If you want to learn more on how the B<rpm> tool gives configuration and
+documentation files special treatment, you should read about "Directives"
+in Edward Bailey's well-known "Maximum RPM" book available online
+at http://www.rpm.org/max-rpm/s1-rpm-inside-files-list-directives.html.)
+
+=head2 Description of command-line arguments
+
+I<TAG> ($tag), B<required> descriptive tag.  For example, a kerberos software
 package might be tagged as "krb4".
 
-VERSION, required version.  Needed to generate version information
-for the RPM.  This should be in the format N.M where N and M are
+I<VERSION> ($version), B<required> version.  Needed to generate version
+information for the RPM.  This should be in the format N.M where N and M are
 integers.
 
-CONFIGURATION_FILES, optional comma-separated listing of files to
+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).
+during RPM upgrades).  Configuration files can also be specified in
+the standard input stream (as described in L<"The standard input stream">).
 
-DOCUMENTATION_FILES, optional comma-separated listing of files to be
+I<DOCUMENTATION_FILES>, B<optional> comma-separated listing of files to be
 treated as documentation files by RPM (and thus subject to being
-placed in the /usr/doc/RPM-NAME directory during RPM installation).
+placed in the F</usr/doc/RPM-NAME> directory during RPM installation).
+Documentation files can also be specified in
+the standard input stream (as described in L<"The standard input stream">).
 
-PATHPREFIX, optional path to be removed from file listing.  This
+I<PATHPREFIX>, B<optional> path to be removed from file listing.  This
 is in case you are building an RPM from files elsewhere than
 root-level.  Note, this still depends on a root directory hierarchy
 after PATHPREFIX.
 
-CUSTOMIZATION_XML, allows for customizing various pieces of information such
+I<CUSTOMIZATION_XML>, B<optional> filename where XML-ish information exists.
+Allows for customizing various pieces of information such
 as vendor, summary, name, copyright, group, autoreqprov, requires, prereq,
-description, and pre-installation scripts (see more in the POD;
-perldoc make_rpml.pl).
+description, and pre-installation scripts
+(see L<"Customizing descriptive data of your RPM software package">).
 
-Examples:
+=head2 Examples
 
-[prompt] find notreallyrootdir | perl make_rpm.pl makemoney 3.1 '' \
-    '/usr/doc/man/man3/makemoney.3' notreallyrootdir
+ bash$ find /notreallyrootdir | perl make_rpm.pl \
+       makemoney 3.1 '' \
+       '/usr/doc/man/man3/makemoney.3' \
+       /notreallyrootdir
  would generate makemoney-3.1-1.i386.rpm
 
-[prompt] find /usr/local/bin | perl make_rpm.pl mybinfiles 1.0
+ bash$ find /usr/local/bin | \
+       perl make_rpm.pl mybinfiles 1.0
  would generate mybinfiles-1.0-1.i386.rpm
 
-[prompt] find romeo | perl make_rpm.pl romeo 1.0 '' '' '' customize.xml
+ bash$ find /home/joe/romeodir/buildloc | \
+       perl make_rpm.pl romeo \
+       1.0 '' '' '/home/joe/romeodir/buildloc' customize.xml
  would generate romeo with customizations from customize.xml.
 
-The CUSTOMIZATION_XML argument represents a way to customize the
+The I<CUSTOMIZATION_XML> argument represents a way to customize the
 numerous variables associated with RPMs.  This argument represents
 a file name.  (Parsing is done in an unsophisticated fashion using
-regular expressions.)  Here are example contents of such a file:
+regular expressions.)  See
+L<"Customizing descriptive data of your RPM software package">.
+
+=head1 Customizing descriptive data of your RPM software package
+
+RPMS can be (and often are) packaged with descriptive data 
+describing authorship, dependencies, descriptions, etc.
+
+The following values can be tagged inside an XML file
+(specified by the 6th command-line argument)
+and made part of the RPM package information
+(B<rpm -qi E<lt>package-nameE<gt>>).
+
+=over 4
+
+=item * vendor
+
+=item * summary
+
+=item * name
+
+(overrides the <TAG> argument value; see 
+L<"Description of command-line arguments>)
+
+=item * copyright
+
+=item * group
+
+(the software package group;
+e.g. Applications/System, User Interface/X, Development/Libraries,
+etc.)
+
+=item * requires
+
+Contains all the dependency information (see the example below).
+
+=item * description
+
+=item * pre
+
+Commands to be executed prior to software package installation.
+
+=back
+
+Here is an example (note that B<make_rpm.pl> automatically substitutes
+any "<tag />" string with the first command-line argument described
+in L<"Description of command-line arguments">):
 
  <vendor>
  Laboratory for Instructional Technology Education, Division of
@@ -474,7 +637,7 @@
  For more on the LON-CAPA project, visit http://www.lon-capa.org/.
  </description>
  <pre>
- echo "***********************************************************************"
+ echo "************************************************************"
  echo "LON-CAPA  LearningOnline with CAPA"
  echo "http://www.lon-capa.org/"
  echo " "
@@ -485,42 +648,45 @@
  echo " "
  echo "This installation assumes an installation of Redhat 6.2"
  echo " "
- echo "The server computer should be currently connected to the ethernet"
- echo " "
- echo "The files in this package are only those for the <tag /> component."
- echo "Configuration files are sometimes part of the LON-CAPA-base RPM."
- echo "***********************************************************************"
+ echo "The files in this package are for the <tag /> component."
+ echo "***********************************************************"
  </pre>
 
 =head1 DESCRIPTION
 
 Automatically generate an RPM software package from a list of files.
 
-This script builds the RPM in a very clean and configurable fashion.
-(Finally!  Making RPMs outside of /usr/src/redhat without a zillion
+B<make_rpm.pl> builds the RPM in a very clean and configurable fashion.
+(Finally!  Making RPMs outside of F</usr/src/redhat> without a zillion
 file intermediates left over!)
 
-This script generates and then deletes temporary
+B<make_rpm.pl> generates and then deletes temporary
 files needed to build an RPM with.
 It works cleanly and independently from pre-existing
-directory trees such as /usr/src/redhat/*.
+directory trees such as F</usr/src/redhat/*>.
 
-The script is also simple.  It accepts four kinds of information,
-two of which are mandatory:
+Input to the script is simple.  B<make_rpm.pl> accepts five kinds of
+information, three of which are mandatory:
 
 =over 4
 
 =item *
 
-a list of files that are to be part of the software package;
+(required) a list of files that are to be part of the software package;
 
-=item * 
+=item *
+
+(required) the absolute filesystem location of these files
+(see L<"The standard input stream">);
+
+=item *
 
-the location of these files;
+(required) a descriptive tag and a version tag for the naming of the
+RPM software package;
 
 =item *
 
-(optional) a descriptive tag and a version tag;
+(optional) documentation and configuration files;
 
 =item *
 
@@ -529,37 +695,100 @@
 
 =back
 
-The following items are initially and temporarily generated during the
-construction of an RPM:
+A temporary directory named $tag (first argument described in
+L<"Description of command-line arguments">) is
+
+=over 4
+
+=item *
+
+generated under the directory from which you run B<make_rpm.pl>.
+
+For example, user "joe" running
+
+ cat file_list.txt | make_rpm.pl krb4 1.0
+
+would temporarily generate F</home/joe/krb4/>.
+
+=item *
+
+F</home/joe/krb4/> is deleted after the *.rpm
+file is generated.
+
+=back
+
+The RPM will typically be named $name-$version.i386.rpm
+where $name=$tag.  (The $name can be overridden in the customization
+XML file; see
+L<"Customizing descriptive data of your RPM software package">.)
+
+Here are some of the items are generated inside
+the $tag directory during the construction of an RPM:
+
+=over 4
+
+=item *
+
+RPM .spec file (F<./$tag/SPECS/$name-$version.spec>)
+
+=item *
+
+RPM Makefile (F<./$tag/SOURCES/$name-$version/Makefile>)
+
+This is the Makefile that is called by the rpm
+command in building the .i386.rpm from the .src.rpm.
+The following directories are generated and/or used:
 
 =over 4
 
 =item *
 
-RPM .spec file
+SOURCE directory: F<./$tag/BinaryRoot/>
+
+=item *
+
+TARGET directory: F<./$tag/BuildRoot/>
+
+=back
+
+=item *
+
+BinaryRootMakefile (F<./$tag/BinaryRootMakefile>)
+
+This is the Makefile that this script creates and calls
+to build the F<$tag/BinaryRoot/> directory from the existing
+filesystem.
+The following directories are generated and/or used:
+
+=over 4
 
 =item *
 
-RPM Makefile
+SOURCE directory: / (your entire filesystem)
 
 =item *
 
-SourceRoot
+TARGET directory: F<./$tag/BinaryRoot/>
 
 =back
 
-A resulting .rpm file is generated.
+=back
+
+The final output of B<make_rpm.pl> is a binary F<.rpm> file.
+The F<./tag> directory is deleted (along with the F<.src.rpm>
+file).  The typical file name generated by B<make_rpm.pl> is
+F<$tag-$version.i386.rpm>.
 
-make_rpm.pl is compatible with both rpm version 3.* and rpm version 4.*.
+B<make_rpm.pl> is compatible with either rpm version 3.* or rpm version 4.*.
 
 =head1 README
 
 Automatically generate an RPM software package from a list of files.
 
-This script builds the RPM in a very clean and configurable fashion.
-(Making RPMs the simple and right way!)
+B<make_rpm.pl> builds the RPM in a very clean and configurable fashion.
+(Making RPMs "the simple way" in a one-line command.)
 
-This script generates and then deletes temporary
+B<make_rpm.pl> generates and then deletes temporary
 files (and binary root directory tree) to build an RPM with.
 It is designed to work cleanly and independently from pre-existing
 directory trees such as /usr/src/redhat/*.
@@ -568,12 +797,45 @@
 
 This script requires the C<strict> module.
 
-=pod OSNAMES
+=head1 AUTHOR
+
+ Scott Harrison
+ harris41@msu.edu
+
+Please let me know how/if you are finding this script useful and
+any/all suggestions.  -Scott
+
+=head1 LICENSE
+
+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 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This file is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+The GNU Public License is available for review at
+http://www.gnu.org/copyleft/gpl.html.
+
+For information on the LON-CAPA project, please visit
+http://www.lon-capa.org/.
+
+=head1 OSNAMES
 
 Linux
 
-=pod SCRIPT CATEGORIES
+=head1 SCRIPT CATEGORIES
 
 UNIX/System Administration
 
 =cut
+

--harris411018208128--