Diff for /loncom/build/make_rpm.pl between versions 1.15 and 1.16

version 1.15, 2002/02/16 19:53:46 version 1.16, 2002/04/07 19:35:27
Line 1 Line 1
 #!/usr/bin/perl  #!/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  # The LearningOnline Network with CAPA
 # make_rpm.pl - make RedHat package manager file (A CLEAN AND CONFIGURABLE WAY)  # make_rpm.pl - make RedHat package manager file (A CLEAN AND CONFIGURABLE WAY)
 #  #
Line 32 Line 37
 # YEAR=2001  # YEAR=2001
 # 1/8,1/10,1/13,1/23,5/16 - Scott Harrison  # 1/8,1/10,1/13,1/23,5/16 - Scott Harrison
 # YEAR=2002  # YEAR=2002
 # 1/4,1/8,1/9,2/13 - Scott Harrison  # 1/4,1/8,1/9,2/13,4/7 - Scott Harrison
 #  #
 ###  ###
   
Line 45 Line 50
 ## ORGANIZATION OF THIS PERL SCRIPT                                          ##  ## ORGANIZATION OF THIS PERL SCRIPT                                          ##
 ##                                                                           ##  ##                                                                           ##
 ## 1. Check to see if RPM builder application is available                   ##  ## 1. Check to see if RPM builder application is available                   ##
 ## 2. Read in arguments                                                      ##  ## 2. Read in command-line arguments                                         ##
 ## 3. Generate temporary directories                                         ##  ## 3. Generate temporary directories (subdirs of first command-line argument)##
 ## 4. Initialize some variables                                              ##  ## 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                    ##  ## 6. Perform variable initializations and customizations                    ##
 ## 7. Print header information for .spec file                                ##  ## 7. Print header information for .spec file                                ##
 ## 8. Process file list and generate information                             ##  ## 8. Process file list and generate information                             ##
Line 67  use strict; Line 72  use strict;
   
 # ------------------------ Check to see if RPM builder application is available  # ------------------------ Check to see if RPM builder application is available
   
 unless (-e '/usr/lib/rpm/rpmrc') {  unless (-e '/usr/lib/rpm/rpmrc') { # part of the expected rpm software package
     print <<END;      print(<<END);
 ERROR: This script only works with a properly installed RPM builder  **** ERROR **** This script only works with a properly installed RPM builder
 application.    application.  
 Cannot find /usr/lib/rpm/rpmrc, so cannot generate customized rpmrc file.  Cannot find /usr/lib/rpm/rpmrc, so cannot generate customized rpmrc file.
 Script aborting.  Script aborting.
 END  END
       exit(1);
 }  }
   
 # ----------------------------------------------------------- Read in arguments  # ---------------------------------------------- Read in command-line arguments
   
 my ($tag,$version,$configuration_files,$documentation_files,  my ($tag,$version,$configuration_files,$documentation_files,
     $pathprefix,$customize)=@ARGV;      $pathprefix,$customize)=@ARGV;
 @ARGV=();  @ARGV=(); # read standard input based on a pipe, not a command-line argument
   
 if (!$version) {  if (!$version) {# version should be defined and string length greater than zero
     print <<END;      print(<<END);
 See "perldoc make_rpm.pl" for more information.  See "perldoc make_rpm.pl" for more information.
   
 Usage:   Usage: 
Line 92  Usage: Line 98  Usage:
   
 Standard input provides the list of files to work with.  Standard input provides the list of files to work with.
 TAG, required descriptive tag.  For example, a kerberos software  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  VERSION, required version.  Needed to generate version information
 for the RPM.  This should be in the format N.M where N and M are  for the RPM.  It is recommended that this be in the format N.M where N and
 integers.  M are integers.
 CONFIGURATION_FILES, optional comma-separated listing of files to  CONFIGURATION_FILES, optional comma-separated listing of files to
 be treated as configuration files by RPM (and thus subject to saving  be treated as configuration files by RPM (and thus subject to saving
 during RPM upgrades).  during RPM upgrades).
Line 108  root-level.  Note, this still depends on Line 116  root-level.  Note, this still depends on
 after PATHPREFIX.  after PATHPREFIX.
 CUSTOMIZATION_XML, allows for customizing various pieces of information such  CUSTOMIZATION_XML, allows for customizing various pieces of information such
 as vendor, summary, name, copyright, group, autoreqprov, requires, prereq,  as vendor, summary, name, copyright, group, autoreqprov, requires, prereq,
 description, and pre-installation scripts (see more in the POD;  description, and pre-installation scripts (see more in the POD,
 perldoc make_rpml.pl).  "perldoc make_rpm.pl").
 END  END
     exit;      exit(1);
 }  }
   
 mkdir $tag,0755;  # ----- Generate temporary directories (subdirs of first command-line argument)
 mkdir "$tag/BuildRoot",0755;  
 mkdir "$tag/SOURCES",0755;  # Do some error-checking related to important first command-line argument.
 mkdir "$tag/SPECS",0755;  if ($tag=~/\W/) { # non-alphanumeric characters cause problems
 mkdir "$tag/BUILD",0755;      print(<<END);
 mkdir "$tag/SRPMS",0755;  **** ERROR **** Invalid tag name "$tag"
 mkdir "$tag/RPMS",0755;  (The first command-line argument must be alphanumeric characters without
 mkdir "$tag/RPMS/i386",0755;  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  # -------------------------------------------------------- Initialize variables
   
 my $file;  my $file;
 my $binaryroot="$tag/BinaryRoot";  my $binaryroot=$tag.'/BinaryRoot';
 my ($type,$size,$octalmode,$user,$group);  my ($type,$size,$octalmode,$user,$group);
   
 my $currentdir=`pwd`; chop $currentdir; my $invokingdir=$currentdir;  my $currentdir=`pwd`; chomp($currentdir); my $invokingdir=$currentdir;
 $currentdir.="/$tag";  $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>;  my @lines=<IN>;
 close IN;  close(IN);
   
 open (RPMRC,">$tag/SPECS/rpmrc");  open(RPMRC,">$tag/SPECS/rpmrc");
 foreach my $line (@lines) {  foreach my $line (@lines) {
     if ($line=~/^macrofiles/) {      if ($line=~/^macrofiles/) {
  chop $line;   chomp($line);
  $line.=":$currentdir/SPECS/rpmmacros\n";   $line.=":$currentdir/SPECS/rpmmacros\n";
     }      }
     print RPMRC $line;      print(RPMRC $line);
 }  }
 close RPMRC;  close(RPMRC);
   
 open (RPMMACROS,">$tag/SPECS/rpmmacros");  open(RPMMACROS,">$tag/SPECS/rpmmacros");
 print RPMMACROS <<END;  print(RPMMACROS <<END);
 \%_topdir $currentdir  \%_topdir $currentdir
 \%__spec_install_post    \\  \%__spec_install_post    \\
     /usr/lib/rpm/brp-strip \\      /usr/lib/rpm/brp-strip \\
     /usr/lib/rpm/brp-strip-comment-note \\      /usr/lib/rpm/brp-strip-comment-note \\
 \%{nil}  \%{nil}
 END  END
 close RPMMACROS;  close(RPMMACROS);
   
 # ------------------------- Perform variable initializations and customizations  # ------------------------- Perform variable initializations and customizations
   
 my $cu;  my $cu=''; # string that holds customization XML file contents
 if ($customize) {  if (length($customize)>0) {
     open (IN,"<$customize") or die("Cannot open $customize");      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>);      my @clines=(<IN>);
     $cu=join('',@clines);      $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?)  # would it?)
 my $name=$tag;  my $name=$tag;
 # read in name from customization if available  # read in name from customization if available
 $tv=grabtag('name',$cu,1); $name=$tv if $tv;  $tv=grabtag('name',$cu,1); $name=$tv if $tv;
 $name=~s/\<tag \/\>/$tag/g;  $name=~s/\<tag \/\>/$tag/g;
   
 # okay.. now we can generate this needed directory  # (When in doubt, be paranoid about overwriting things.)
 mkdir "$tag/SOURCES/$name-$version",0755;  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)  # read in relevant requires info from customization file (if applicable)
 # note that "PreReq: item" controls order of CD-ROM installation (if you  # note that "PreReq: item" controls order of CD-ROM installation (if you
 # are making a customized CD-ROM)  # are making a customized CD-ROM)
Line 190  $requires=~s/\s*\<\/item\>\s*//g; Line 230  $requires=~s/\s*\<\/item\>\s*//g;
 $requires=~s/\s*\<item\>\s*/\n/g;  $requires=~s/\s*\<item\>\s*/\n/g;
 $requires=~s/^\s+//s;  $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  # read in summary from customization if available
 $tv=grabtag('summary',$cu,1); $summary=$tv if $tv;  $tv=grabtag('summary',$cu,1); $summary=$tv if $tv;
 $summary=~s/\<tag \/\>/$tag/g;  $summary=~s/\<tag \/\>/$tag/g;
Line 204  my $copyright="not specified here"; Line 244  my $copyright="not specified here";
 $tv=grabtag('copyright',$cu,1); $copyright=$tv if $tv;  $tv=grabtag('copyright',$cu,1); $copyright=$tv if $tv;
 $copyright=~s/\<tag \/\>/$tag/g;  $copyright=~s/\<tag \/\>/$tag/g;
   
 open (SPEC,">$tag/SPECS/$name-$version.spec");  open(SPEC,">$tag/SPECS/$name-$version.spec");
   
 my $vendor='Me';  my $vendor='Me';
 # read in vendor from customization if available  # read in vendor from customization if available
Line 216  my $description="$name software package" Line 256  my $description="$name software package"
 $tv=grabtag('description',$cu,0); $description=$tv if $tv;  $tv=grabtag('description',$cu,0); $description=$tv if $tv;
 $description=~s/\<tag \/\>/$tag/g;  $description=~s/\<tag \/\>/$tag/g;
   
 my $pre="";  my $pre='';
 # read in pre-installation script if available  # read in pre-installation script if available
 $tv=grabtag('pre',$cu,0); $pre=$tv if $tv;  $tv=grabtag('pre',$cu,0); $pre=$tv if $tv;
 $pre=~s/\<tag \/\>/$tag/g;  $pre=~s/\<tag \/\>/$tag/g;
   
 # ------------------------------------- Print header information for .spec file  # ------------------------------------- Print header information for .spec file
   
 print SPEC <<END;  print(SPEC <<END);
 Summary: $summary  Summary: $summary
 Name: $name  Name: $name
 Version: $version  Version: $version
Line 265  my %BinaryRootMakefile; Line 305  my %BinaryRootMakefile;
 my %Makefile;  my %Makefile;
 my %dotspecfile;  my %dotspecfile;
   
 foreach $file (<>) {  foreach my $file (<>) {
     chop $file;      chomp($file);
     my $comment="";      my $comment="";
     if ($file=~/\s+\#(.*)$/) {      if ($file=~/\s+\#(.*)$/) {
  $file=~s/\s+\#(.*)$//;   $file=~s/\s+\#(.*)$//;
Line 288  foreach $file (<>) { Line 328  foreach $file (<>) {
     $file=~s/^$pathprefix//;      $file=~s/^$pathprefix//;
  }   }
  if ($type eq "files") {   if ($type eq "files") {
     push @{$BinaryRootMakefile{$type}},"\tinstall -D -m $octalmode ".      push(@{$BinaryRootMakefile{$type}},"\tinstall -D -m $octalmode ".
  "$pathprefix$file $binaryroot$file\n";   "$pathprefix$file $binaryroot$file\n");
     push @{$Makefile{$type}},"\tinstall -D -m $octalmode ".      push(@{$Makefile{$type}},"\tinstall -D -m $octalmode ".
  "\$(SOURCE)$file \$(ROOT)$file\n";   "\$(SOURCE)$file \$(ROOT)$file\n");
     push @{$dotspecfile{$type}},"$directive\%attr($octalmode,$user,".      push(@{$dotspecfile{$type}},"$directive\%attr($octalmode,$user,".
  "$group) $file\n";   "$group) $file\n");
  }   }
  elsif ($type eq "directories") {   elsif ($type eq "directories") {
     push @{$BinaryRootMakefile{$type}},"\tinstall -m $octalmode -d ".      push(@{$BinaryRootMakefile{$type}},"\tinstall -m $octalmode -d ".
  "$binaryroot$file\n";   "$binaryroot$file\n");
     push @{$Makefile{$type}},"\tinstall -m $octalmode -d ".      push(@{$Makefile{$type}},"\tinstall -m $octalmode -d ".
  "\$(SOURCE)$file \$(ROOT)$file\n";   "\$(SOURCE)$file \$(ROOT)$file\n");
     push @{$dotspecfile{$type}},"\%dir \%attr($octalmode,$user,".      push(@{$dotspecfile{$type}},"\%dir \%attr($octalmode,$user,".
  "$group) $file\n";   "$group) $file\n");
  }   }
  elsif ($type eq "links") {   elsif ($type eq "links") {
     my $link=$size; # I use the size variable to pass the link value      my $link=$size; # I use the size variable to pass the link value
                             # from the subroutine find_info                              # from the subroutine find_info
     $link=~s/^$pathprefix//;      $link=~s/^$pathprefix//;
     push @{$BinaryRootMakefile{$type}},      push(@{$BinaryRootMakefile{$type}},
          "\tln -s $link $binaryroot$file\n";           "\tln -s $link $binaryroot$file\n");
     push @{$Makefile{$type}},"\tln -s $link \$(ROOT)$file\n";      push(@{$Makefile{$type}},"\tln -s $link \$(ROOT)$file\n");
     push @{$dotspecfile{$type}},"\%attr(-,$user,$group) $file\n";      push(@{$dotspecfile{$type}},"\%attr(-,$user,$group) $file\n");
  }   }
     }      }
 }  }
   
 # -------------------------------------- Generate SRPM and BinaryRoot Makefiles  # -------------------------------------- Generate SRPM and BinaryRoot Makefiles
   
 open OUTS, ">$tag/SOURCES/$name-$version/Makefile";  # Generate a much needed directory.
 open OUTB, ">$tag/BinaryRootMakefile";  # 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") {  foreach $type ("directories","files","links") {
     print OUTS "$type\:\n";      print(OUTS "$type\:\n");
     print OUTS join("",@{$Makefile{$type}}) if $Makefile{$type};      print(OUTS join("",@{$Makefile{$type}})) if $Makefile{$type};
     print OUTS "\n";      print(OUTS "\n");
     print OUTB "$type\:\n";      print(OUTB "$type\:\n");
     print OUTB join("",@{$BinaryRootMakefile{$type}})      print(OUTB join("",@{$BinaryRootMakefile{$type}}))
  if $BinaryRootMakefile{$type};   if $BinaryRootMakefile{$type};
     print OUTB "\n";      print(OUTB "\n");
     print SPEC join("",@{$dotspecfile{$type}}) if $dotspecfile{$type};      print(SPEC join("",@{$dotspecfile{$type}})) if $dotspecfile{$type};
 }  }
 close OUTB;  close(OUTB);
 close OUTS;  close(OUTS);
   
 close SPEC;  close(SPEC);
   
 # ------------------ mirror copy (BinaryRoot) files under a temporary directory  # ------------------ mirror copy (BinaryRoot) files under a temporary directory
   
Line 341  close SPEC; Line 386  close SPEC;
 `make -f $tag/BinaryRootMakefile links`;  `make -f $tag/BinaryRootMakefile links`;
   
 # ------------------------------------------------- roll everything into an RPM  # ------------------------------------------------- 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 ".  my $command="cd $currentdir/SOURCES; tar czvf $name-$version.tar.gz ".
     "$name-$version";      "$name-$version";
 print `$command`;  print(`$command`);
 $command="cd $currentdir/SPECS; rpm --rcfile=./rpmrc -ba ".  $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/.";      "$name-$version-1.i386.rpm $invokingdir/.";
 print `$command`;  print(`$command`);
   
 # --------------------------------------------------------- clean everything up  # --------------------------------------------------------- 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  # ----------------------------------------------------------------- SUBROUTINES
 # ----- Subroutine: find_info - recursively gather information from a directory  # ----- Subroutine: find_info - recursively gather information from a directory
 sub find_info {  sub find_info {
     my ($file)=@_;      my ($file)=@_;
     my $line;      my $line='';
     if (($line=`find $file -type f -prune`)=~/^$file\n/) {      if (($line=`find $file -type f -prune`)=~/^$file\n/) {
  $line=`find $file -type f -prune -printf "\%s\t\%m\t\%u\t\%g"`;   $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/) {      elsif (($line=`find $file -type d -prune`)=~/^$file\n/) {
  $line=`find $file -type d -prune -printf "\%s\t\%m\t\%u\t\%g"`;   $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/) {      elsif (($line=`find $file -type l -prune`)=~/^$file\n/) {
  $line=`find $file -type l -prune -printf "\%l\t\%m\t\%u\t\%g"`;   $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  # ------------------------- Subroutine: grabtag - grab a tag from an xml string
 sub grabtag {  sub grabtag {
     my ($tag,$text,$clean)=@_;      my ($tag,$text,$clean)=@_;
     # meant to be quick and dirty as opposed to a formal state machine parser      # meant to be quick and dirty as opposed to a formal state machine parser
     my $value;      my $value='';
     $cu=~/\<$tag\>(.*?)\<\/$tag\>/s;       $cu=~/\<$tag\>(.*?)\<\/$tag\>/s; 
     $value=$1; $value=~s/^\s+//;      $value=$1; $value=~s/^\s+//;
     if ($clean) {      if ($clean==1) {
  $value=~s/\n\s/ /g;   $value=~s/\n\s/ /g;
  $value=~s/\s\n/ /g;   $value=~s/\s\n/ /g;
  $value=~s/\n/ /g;   $value=~s/\n/ /g;
  $value=~s/\s+$//;   $value=~s/\s+$//;
     }      }
     return $value;      return($value);
 }  }
   
 # ----------------------------------------------------- Plain Old Documentation  # ----------------------------------------------------- Plain Old Documentation
   
 =head1 NAME  =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  =head1 SYNOPSIS
   
 Usage: <TAG> <VERSION> [CONFIGURATION_FILES]  Usage: <STDIN> | make_rpm.pl <TAG> <VERSION>
  [DOCUMENTATION_FILES] [PATHPREFIX] [CUSTOMIZATION_XML]         [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".  package might be tagged as "krb4".
   
 VERSION, required version.  Needed to generate version information  I<VERSION> ($version), B<required> version.  Needed to generate version
 for the RPM.  This should be in the format N.M where N and M are  information for the RPM.  This should be in the format N.M where N and M are
 integers.  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  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  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  is in case you are building an RPM from files elsewhere than
 root-level.  Note, this still depends on a root directory hierarchy  root-level.  Note, this still depends on a root directory hierarchy
 after PATHPREFIX.  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,  as vendor, summary, name, copyright, group, autoreqprov, requires, prereq,
 description, and pre-installation scripts (see more in the POD;  description, and pre-installation scripts
 perldoc make_rpml.pl).  (see L<"Customizing descriptive data of your RPM software package">).
   
 Examples:  =head2 Examples
   
 [prompt] find notreallyrootdir | perl make_rpm.pl makemoney 3.1 '' \   bash$ find /notreallyrootdir | perl make_rpm.pl \
     '/usr/doc/man/man3/makemoney.3' notreallyrootdir         makemoney 3.1 '' \
          '/usr/doc/man/man3/makemoney.3' \
          /notreallyrootdir
  would generate makemoney-3.1-1.i386.rpm   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   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.   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  numerous variables associated with RPMs.  This argument represents
 a file name.  (Parsing is done in an unsophisticated fashion using  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>   <vendor>
  Laboratory for Instructional Technology Education, Division of   Laboratory for Instructional Technology Education, Division of
Line 474  regular expressions.)  Here are example Line 637  regular expressions.)  Here are example
  For more on the LON-CAPA project, visit http://www.lon-capa.org/.   For more on the LON-CAPA project, visit http://www.lon-capa.org/.
  </description>   </description>
  <pre>   <pre>
  echo "***********************************************************************"   echo "************************************************************"
  echo "LON-CAPA  LearningOnline with CAPA"   echo "LON-CAPA  LearningOnline with CAPA"
  echo "http://www.lon-capa.org/"   echo "http://www.lon-capa.org/"
  echo " "   echo " "
Line 485  regular expressions.)  Here are example Line 648  regular expressions.)  Here are example
  echo " "   echo " "
  echo "This installation assumes an installation of Redhat 6.2"   echo "This installation assumes an installation of Redhat 6.2"
  echo " "   echo " "
  echo "The server computer should be currently connected to the ethernet"   echo "The files in this package are for the <tag /> component."
  echo " "   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 "***********************************************************************"  
  </pre>   </pre>
   
 =head1 DESCRIPTION  =head1 DESCRIPTION
   
 Automatically generate an RPM software package from a list of files.  Automatically generate an RPM software package from a list of files.
   
 This script builds the RPM in a very clean and configurable fashion.  B<make_rpm.pl> builds the RPM in a very clean and configurable fashion.
 (Finally!  Making RPMs outside of /usr/src/redhat without a zillion  (Finally!  Making RPMs outside of F</usr/src/redhat> without a zillion
 file intermediates left over!)  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.  files needed to build an RPM with.
 It works cleanly and independently from pre-existing  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,  Input to the script is simple.  B<make_rpm.pl> accepts five kinds of
 two of which are mandatory:  information, three of which are mandatory:
   
 =over 4  =over 4
   
 =item *  =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 *  =item *
   
 (optional) a descriptive tag and a version tag;  (optional) documentation and configuration files;
   
 =item *  =item *
   
Line 529  associated with the RPM software package Line 695  associated with the RPM software package
   
 =back  =back
   
 The following items are initially and temporarily generated during the  A temporary directory named $tag (first argument described in
 construction of an RPM:  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  =over 4
   
 =item *  =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 *  =item *
   
 RPM Makefile  SOURCE directory: / (your entire filesystem)
   
 =item *  =item *
   
 SourceRoot  TARGET directory: F<./$tag/BinaryRoot/>
   
 =back  =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  =head1 README
   
 Automatically generate an RPM software package from a list of files.  Automatically generate an RPM software package from a list of files.
   
 This script builds the RPM in a very clean and configurable fashion.  B<make_rpm.pl> builds the RPM in a very clean and configurable fashion.
 (Making RPMs the simple and right way!)  (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.  files (and binary root directory tree) to build an RPM with.
 It is designed to work cleanly and independently from pre-existing  It is designed to work cleanly and independently from pre-existing
 directory trees such as /usr/src/redhat/*.  directory trees such as /usr/src/redhat/*.
Line 568  directory trees such as /usr/src/redhat/ Line 797  directory trees such as /usr/src/redhat/
   
 This script requires the C<strict> module.  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  Linux
   
 =pod SCRIPT CATEGORIES  =head1 SCRIPT CATEGORIES
   
 UNIX/System Administration  UNIX/System Administration
   
 =cut  =cut
   

Removed from v.1.15  
changed lines
  Added in v.1.16


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>