--- loncom/build/make_rpm.pl 2002/01/05 00:48:05 1.12 +++ loncom/build/make_rpm.pl 2002/01/09 02:24:14 1.13 @@ -1,9 +1,9 @@ #!/usr/bin/perl # The LearningOnline Network with CAPA -# make_rpm.pl - make RedHat package manager file +# make_rpm.pl - make RedHat package manager file (A CLEAN AND CONFIGURABLE WAY) # -# $Id: make_rpm.pl,v 1.12 2002/01/05 00:48:05 harris41 Exp $ +# $Id: make_rpm.pl,v 1.13 2002/01/09 02:24:14 harris41 Exp $ # # Written by Scott Harrison, harris41@msu.edu # @@ -25,8 +25,6 @@ # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# /home/httpd/html/adm/gpl.txt -# # http://www.lon-capa.org/ # # YEAR=2000 @@ -34,17 +32,19 @@ # YEAR=2001 # 1/8,1/10,1/13,1/23,5/16 - Scott Harrison # YEAR=2002 -# 1/4 - Scott Harrison +# 1/4,1/8 - Scott Harrison # ### # Automatically generate RPM files # from file listing. -# This script does actually "build" the RPM. +# This script builds the RPM. # This script also 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/*. # I still need to implement the CONFIGURATION_FILES and # DOCUMENTATION_FILES portion of the command line interface to this @@ -59,7 +59,32 @@ # A resulting .rpm file is generated. -unless (-e "/usr/lib/rpm/rpmrc") { +############################################################################### +## ## +## ORGANIZATION OF THIS PERL SCRIPT ## +## ## +## 1. Check to see if RPM builder application is available ## +## 2. Read in arguments ## +## 3. Generate temporary directories ## +## 4. Initialize some variables ## +## 5. Create a standalone rpm building environment ## +## 6. Perform variable initializations and customizations ## +## 7. Print header information for .spec file ## +## 8. Process file list and generate information ## +## 9. Generate SRPM and BinaryRoot Makefiles ## +## 10. mirror copy (BinaryRoot) files under a temporary directory ## +## 11. roll everything into an rpm ## +## 12. clean everything up ## +## 13. find_info - recursively gather information from a directory ## +## 14. Plain Old Documentation ## +## ## +############################################################################### + +use strict; + +# ------------------------ Check to see if RPM builder application is available + +unless (-e '/usr/lib/rpm/rpmrc') { print < [CONFIGURATION_FILES] [DOCUMENTATION] ". - "[PATHPREFIX]\n"; - print "Standard input provides the list of files to work with.\n"; - print "TAG, required descriptive tag. For example, a kerberos software ". - "package might be tagged as \"krb4\".\n"; - print "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.\n"; - print "CONFIGURATION_FILES, optional comma-separated listing of files to ". - "be treated as configuration files by RPM (and thus subject to saving". - " during RPM upgrades).\n"; - print "DOCUMENTATION, 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).". - "\n"; - print "PATHPREFIX, 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.\n"; + print < [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 +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 +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). +DOCUMENTATION_FILES, 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). +PATHPREFIX, 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 +as vendor, summary, name, copyright, group, autoreqprov, requires, prereq, +description, and pre-installation scripts (see more in the POD; +perldoc make_rpml.pl). +END exit; } mkdir $tag,0755; mkdir "$tag/BuildRoot",0755; mkdir "$tag/SOURCES",0755; -mkdir "$tag/SOURCES/LON-CAPA-$tag-$version",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 ($type,$size,$octalmode,$user,$group); -$currentdir=`pwd`; chop $currentdir; $invokingdir=$currentdir; +my $currentdir=`pwd`; chop $currentdir; my $invokingdir=$currentdir; $currentdir.="/$tag"; -open (IN,"; +# -------------------------------- Create a standalone rpm building environment + +open (IN,'; close IN; open (RPMRC,">$tag/SPECS/rpmrc"); -foreach $line (@lines) { +foreach my $line (@lines) { if ($line=~/^macrofiles/) { chop $line; $line.=":$currentdir/SPECS/rpmmacros\n"; @@ -135,188 +173,82 @@ print RPMMACROS <); + $cu=join('',@clines); + close IN; } -open (SPEC,">$tag/SPECS/LON-CAPA-$tag-$version.spec"); +my $tv; # tag value variable for storing retrievals from $cu + +# (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/g; + +# okay.. now we can generate this needed directory +mkdir "$tag/SOURCES/$name-$version",0755; + +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) +# "Requires: item" just enforces dependencies from the command-line invocation +$tv=grabtag('requires',$cu,1); $requires=$tv if $tv; +# do more require processing here +$requires=~s/\s*\<\/item\>\s*//g; +$requires=~s/\s*\\s*/\n/g; +$requires=~s/^\s+//s; + +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/g; + +my $copyright="not specified here"; +# read in copyright from customization if available +$tv=grabtag('copyright',$cu,1); $copyright=$tv if $tv; +$copyright=~s/\/$tag/g; + +open (SPEC,">$tag/SPECS/$name-$version.spec"); + +my $vendor='Me'; +# read in vendor from customization if available +$tv=grabtag('vendor',$cu,1); $vendor=$tv if $tv; +$vendor=~s/\/$tag/g; + +my $description="$name software package"; +# read in description from customization if available +$tv=grabtag('description',$cu,0); $description=$tv if $tv; +$description=~s/\/$tag/g; + +my $pre=""; +# read in pre-installation script if available +$tv=grabtag('pre',$cu,0); $pre=$tv if $tv; +$pre=~s/\/$tag/g; -my $vendor='Laboratory for Instructional Technology Education, Division of '. - 'Science and Mathematics Education, Michigan State University.'; +# ------------------------------------- Print header information for .spec file print SPEC <) { chop $file; my $comment=""; @@ -360,9 +283,15 @@ foreach $file (<>) { $file=~s/\s+\#(.*)$//; $comment=$1; } - my $config=""; - if ($comment=~/config/i) { - $config="\%config "; + my $directive=""; + if ($comment=~/config\(noreplace\)/) { + $directive="\%config(noreplace) "; + } + elsif ($comment=~/config/) { + $directive="\%config "; + } + elsif ($comment=~/doc/) { + $directive="\%doc"; } if (($type,$size,$octalmode,$user,$group)=find_info($file)) { $octalmode="0" . $octalmode if length($octalmode)<4; @@ -374,7 +303,7 @@ foreach $file (<>) { "$pathprefix$file $binaryroot$file\n"; push @{$Makefile{$type}},"\tinstall -D -m $octalmode ". "\$(SOURCE)$file \$(ROOT)$file\n"; - push @{$dotspecfile{$type}},"$config\%attr($octalmode,$user,". + push @{$dotspecfile{$type}},"$directive\%attr($octalmode,$user,". "$group) $file\n"; } elsif ($type eq "directories") { @@ -397,36 +326,46 @@ foreach $file (<>) { } } -open OUT, ">$tag/SOURCES/LON-CAPA-$tag-$version/Makefile"; -open OUT2, ">$tag/BinaryRootMakefile"; +# -------------------------------------- Generate SRPM and BinaryRoot Makefiles + +open OUTS, ">$tag/SOURCES/$name-$version/Makefile"; +open OUTB, ">$tag/BinaryRootMakefile"; foreach $type ("directories","files","links") { - print OUT "$type\:\n"; - print OUT join("",@{$Makefile{$type}}); - print OUT "\n"; - print OUT2 "$type\:\n"; - print OUT2 join("",@{$BinaryRootMakefile{$type}}); - print OUT2 "\n"; - print SPEC join("",@{$dotspecfile{$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}; } -close OUT2; -close OUT; - +close OUTB; +close OUTS; close SPEC; +# ------------------ mirror copy (BinaryRoot) files under a temporary directory + `make -f $tag/BinaryRootMakefile directories`; `make -f $tag/BinaryRootMakefile files`; `make -f $tag/BinaryRootMakefile links`; -my $command="cd $currentdir/SOURCES; tar czvf LON-CAPA-$tag-$version.tar.gz ". - "LON-CAPA-$tag-$version"; +# ------------------------------------------------- roll everything into an RPM + +my $command="cd $currentdir/SOURCES; tar czvf $name-$version.tar.gz ". + "$name-$version"; print `$command`; $command="cd $currentdir/SPECS; rpm --rcfile=./rpmrc -ba ". - "LON-CAPA-$tag-$version.spec; cd ../RPMS/i386; cp ". - "LON-CAPA-$tag-$version-1.i386.rpm $invokingdir/."; + "$name-$version.spec; cd ../RPMS/i386; cp ". + "$name-$version-1.i386.rpm $invokingdir/."; print `$command`; + +# --------------------------------------------------------- clean everything up + print `cd $invokingdir; rm -Rf $tag`; +# ----- Subroutine: find_info - recursively gather information from a directory sub find_info { # only look for my ($file)=@_; @@ -445,3 +384,168 @@ sub find_info { } } + +# ------------------------- 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; + $cu=~/\<$tag\>(.*?)\<\/$tag\>/s; + $value=$1; $value=~s/^\s+//; + if ($clean) { + $value=~s/\n\s/ /g; + $value=~s/\s\n/ /g; + $value=~s/\n/ /g; + $value=~s/\s+$//; + } + return $value; +} + +# ----------------------------------------------------- Plain Old Documentation + +=head1 NAME + +make_rpm.pl - automatically generate an RPM software package + +=head1 SYNOPSIS + +Usage: [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 +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 +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). + +DOCUMENTATION_FILES, 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). + +PATHPREFIX, 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 +as vendor, summary, name, copyright, group, autoreqprov, requires, prereq, +description, and pre-installation scripts (see more in the POD; +perldoc make_rpml.pl). + +Examples: + +[prompt] 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 + would generate mybinfiles-1.0-1.i386.rpm + +[prompt] find romeo | perl make_rpm.pl romeo 1.0 '' '' '' customize.xml + would generate romeo with customizations from customize.xml. + +The 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: + + + Laboratory for Instructional Technology Education, Division of + Science and Mathematics Education, Michigan State University. + + Files for the component of LON-CAPA + LON-CAPA- + Michigan State University patents may apply. + Utilities/System + no + + PreReq: setup + PreReq: passwd + PreReq: util-linux + + + PreReq: LON-CAPA-setup + PreReq: apache + PreReq: /etc/httpd/conf/access.conf + + + Requires: LON-CAPA-base + + + This package is automatically generated by the make_rpm.pl perl + script (written by the LON-CAPA development team, www.lon-capa.org, + Scott Harrison). This implements the component for LON-CAPA. + For more on the LON-CAPA project, visit http://www.lon-capa.org/. + +
+ echo "***********************************************************************"
+ echo "LON-CAPA  LearningOnline with CAPA"
+ echo "http://www.lon-capa.org/"
+ echo " "
+ echo "Laboratory for Instructional Technology Education"
+ echo "Michigan State University"
+ echo " "
+ echo "** Michigan State University patents may apply **"
+ 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  component."
+ echo "Configuration files are sometimes part of the LON-CAPA-base RPM."
+ echo "***********************************************************************"
+ 
+ +=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 the simple way!) + +This script 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/*. + +Take in a file list (from standard input), +a description tag and version tag from command line argument +and temporarily generate a: + RPM .spec file + RPM Makefile + SourceRoot + +A resulting .rpm file is generated. + +=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. +(Finally! Making RPMs the simple way!) + +This script 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/*. + +=head1 PREREQUISITES + +This script requires the C module. + +=pod OSNAMES + +any + +=pod SCRIPT CATEGORIES + +UNIX/System Administration + +=cut