Annotation of loncom/build/make_rpm.pl, revision 1.19
1.1 harris41 1: #!/usr/bin/perl
2:
1.16 harris41 3: # -------------------------------------------------------- Documentation notice
4: # Run "perldoc ./make_rpm.pl" in order to best view the software documentation
5: # internalized in this program.
6:
7: # --------------------------------------------------------- License Information
1.12 harris41 8: # The LearningOnline Network with CAPA
1.13 harris41 9: # make_rpm.pl - make RedHat package manager file (A CLEAN AND CONFIGURABLE WAY)
1.12 harris41 10: #
1.19 ! harris41 11: # $Id: make_rpm.pl,v 1.18 2002/04/10 05:58:17 harris41 Exp $
1.12 harris41 12: #
13: # Written by Scott Harrison, harris41@msu.edu
14: #
15: # Copyright Michigan State University Board of Trustees
16: #
17: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
18: #
19: # LON-CAPA is free software; you can redistribute it and/or modify
20: # it under the terms of the GNU General Public License as published by
21: # the Free Software Foundation; either version 2 of the License, or
22: # (at your option) any later version.
23: #
24: # LON-CAPA is distributed in the hope that it will be useful,
25: # but WITHOUT ANY WARRANTY; without even the implied warranty of
26: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27: # GNU General Public License for more details.
28: #
29: # You should have received a copy of the GNU General Public License
30: # along with LON-CAPA; if not, write to the Free Software
31: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32: #
33: # http://www.lon-capa.org/
34: #
35: # YEAR=2000
36: # 9/30,10/2,12/11,12/12,12/21 - Scott Harrison
37: # YEAR=2001
38: # 1/8,1/10,1/13,1/23,5/16 - Scott Harrison
39: # YEAR=2002
1.16 harris41 40: # 1/4,1/8,1/9,2/13,4/7 - Scott Harrison
1.12 harris41 41: #
42: ###
43:
1.15 harris41 44: # make_rpm.pl automatically generate RPM software packages
45: # from a target image directory and file listing. POD
46: # documentation is at the end of this file.
1.1 harris41 47:
1.13 harris41 48: ###############################################################################
49: ## ##
50: ## ORGANIZATION OF THIS PERL SCRIPT ##
51: ## ##
52: ## 1. Check to see if RPM builder application is available ##
1.16 harris41 53: ## 2. Read in command-line arguments ##
54: ## 3. Generate temporary directories (subdirs of first command-line argument)##
1.13 harris41 55: ## 4. Initialize some variables ##
1.16 harris41 56: ## 5. Create a stand-alone rpm building environment ##
1.13 harris41 57: ## 6. Perform variable initializations and customizations ##
58: ## 7. Print header information for .spec file ##
59: ## 8. Process file list and generate information ##
60: ## 9. Generate SRPM and BinaryRoot Makefiles ##
61: ## 10. mirror copy (BinaryRoot) files under a temporary directory ##
62: ## 11. roll everything into an rpm ##
63: ## 12. clean everything up ##
1.15 harris41 64: ## 13. subroutines ##
65: ## 13a. find_info - recursively gather information from a directory ##
66: ## 13b. grabtag - grab a tag from an XML string ##
1.13 harris41 67: ## 14. Plain Old Documentation ##
68: ## ##
69: ###############################################################################
70:
71: use strict;
72:
73: # ------------------------ Check to see if RPM builder application is available
74:
1.16 harris41 75: unless (-e '/usr/lib/rpm/rpmrc') { # part of the expected rpm software package
76: print(<<END);
77: **** ERROR **** This script only works with a properly installed RPM builder
1.12 harris41 78: application.
1.1 harris41 79: Cannot find /usr/lib/rpm/rpmrc, so cannot generate customized rpmrc file.
80: Script aborting.
81: END
1.16 harris41 82: exit(1);
1.1 harris41 83: }
84:
1.16 harris41 85: # ---------------------------------------------- Read in command-line arguments
1.13 harris41 86:
87: my ($tag,$version,$configuration_files,$documentation_files,
88: $pathprefix,$customize)=@ARGV;
1.16 harris41 89: @ARGV=(); # read standard input based on a pipe, not a command-line argument
1.18 harris41 90:
91: # standardize pathprefix argument
92: $pathprefix=~s/\/$//; # OTHERWISE THE BEGINNING SLASH MIGHT BE REMOVED
1.3 harris41 93:
1.16 harris41 94: if (!$version) {# version should be defined and string length greater than zero
95: print(<<END);
1.13 harris41 96: See "perldoc make_rpm.pl" for more information.
97:
1.15 harris41 98: Usage:
99: <STDIN> | perl make_rpm.pl <TAG> <VERSION> [CONFIGURATION_FILES]
1.13 harris41 100: [DOCUMENTATION_FILES] [PATHPREFIX] [CUSTOMIZATION_XML]
1.15 harris41 101:
1.13 harris41 102: Standard input provides the list of files to work with.
103: TAG, required descriptive tag. For example, a kerberos software
1.16 harris41 104: package might be tagged as "krb4". (This value is also used in
105: the generation of a temporary directory; you cannot have
106: a pre-existing directory named ./TAG.)
1.13 harris41 107: VERSION, required version. Needed to generate version information
1.16 harris41 108: for the RPM. It is recommended that this be in the format N.M where N and
109: M are integers.
1.13 harris41 110: CONFIGURATION_FILES, optional comma-separated listing of files to
111: be treated as configuration files by RPM (and thus subject to saving
112: during RPM upgrades).
113: DOCUMENTATION_FILES, optional comma-separated listing of files to be
114: treated as documentation files by RPM (and thus subject to being
115: placed in the /usr/doc/RPM-NAME directory during RPM installation).
116: PATHPREFIX, optional path to be removed from file listing. This
117: is in case you are building an RPM from files elsewhere than
118: root-level. Note, this still depends on a root directory hierarchy
119: after PATHPREFIX.
120: CUSTOMIZATION_XML, allows for customizing various pieces of information such
121: as vendor, summary, name, copyright, group, autoreqprov, requires, prereq,
1.16 harris41 122: description, and pre-installation scripts (see more in the POD,
123: "perldoc make_rpm.pl").
1.13 harris41 124: END
1.16 harris41 125: exit(1);
1.1 harris41 126: }
127:
1.16 harris41 128: # ----- Generate temporary directories (subdirs of first command-line argument)
129:
130: # Do some error-checking related to important first command-line argument.
131: if ($tag=~/\W/) { # non-alphanumeric characters cause problems
132: print(<<END);
133: **** ERROR **** Invalid tag name "$tag"
134: (The first command-line argument must be alphanumeric characters without
135: spaces.)
136: END
137: exit(1);
138: }
139: if (-e $tag) { # do not overwrite or conflict with existing data
140: print(<<END);
141: **** ERROR **** a file or directory "./$tag" already exists
142: (This program needs to generate a temporary directory named "$tag".)
143: END
144: exit(1);
145: }
146:
147: print('Generating temporary directory ./'.$tag."\n");
148: mkdir($tag,0755) or die("**** ERROR **** cannot generate $tag directory\n");
149: mkdir("$tag/BuildRoot",0755);
150: mkdir("$tag/SOURCES",0755);
151: mkdir("$tag/SPECS",0755);
152: mkdir("$tag/BUILD",0755);
153: mkdir("$tag/SRPMS",0755);
154: mkdir("$tag/RPMS",0755);
155: mkdir("$tag/RPMS/i386",0755);
1.1 harris41 156:
1.13 harris41 157: # -------------------------------------------------------- Initialize variables
158:
1.1 harris41 159: my $file;
1.16 harris41 160: my $binaryroot=$tag.'/BinaryRoot';
1.1 harris41 161: my ($type,$size,$octalmode,$user,$group);
162:
1.16 harris41 163: my $currentdir=`pwd`; chomp($currentdir); my $invokingdir=$currentdir;
164: $currentdir.='/'.$tag;
1.1 harris41 165:
1.16 harris41 166: # ------------------------------- Create a stand-alone rpm building environment
1.13 harris41 167:
1.16 harris41 168: print('Creating stand-alone rpm build environment.'."\n");
169: open(IN,'</usr/lib/rpm/rpmrc') or die('Cannot open /usr/lib/rpm/rpmrc'."\n");
1.13 harris41 170: my @lines=<IN>;
1.16 harris41 171: close(IN);
1.1 harris41 172:
1.16 harris41 173: open(RPMRC,">$tag/SPECS/rpmrc");
1.13 harris41 174: foreach my $line (@lines) {
1.1 harris41 175: if ($line=~/^macrofiles/) {
1.16 harris41 176: chomp($line);
1.11 harris41 177: $line.=":$currentdir/SPECS/rpmmacros\n";
1.1 harris41 178: }
1.16 harris41 179: print(RPMRC $line);
1.1 harris41 180: }
1.16 harris41 181: close(RPMRC);
1.1 harris41 182:
1.16 harris41 183: open(RPMMACROS,">$tag/SPECS/rpmmacros");
184: print(RPMMACROS <<END);
1.1 harris41 185: \%_topdir $currentdir
186: \%__spec_install_post \\
187: /usr/lib/rpm/brp-strip \\
188: /usr/lib/rpm/brp-strip-comment-note \\
189: \%{nil}
190: END
1.16 harris41 191: close(RPMMACROS);
1.1 harris41 192:
1.13 harris41 193: # ------------------------- Perform variable initializations and customizations
194:
1.16 harris41 195: my $cu=''; # string that holds customization XML file contents
196: if (length($customize)>0) {
197: print('Reading in XML-formatted customizations from '.$customize."\n");
198: open(IN,"<$customize") or
199: (
200: print(`cd $invokingdir; rm -Rf $tag`) and
201: die('Cannot open customization file "'.$customize.'"'."\n")
202: );
1.13 harris41 203: my @clines=(<IN>);
204: $cu=join('',@clines);
1.16 harris41 205: close(IN);
1.13 harris41 206: }
207:
1.16 harris41 208: # tv - temporary variable (if it exists inside the XML document) then use it,
209: # otherwise don't overwrite existing values of variables
210: my $tv='';
211:
212: # (Sure. We could use HTML::TokeParser here... but that wouldn't be fun now,
1.13 harris41 213: # would it?)
214: my $name=$tag;
215: # read in name from customization if available
216: $tv=grabtag('name',$cu,1); $name=$tv if $tv;
217: $name=~s/\<tag \/\>/$tag/g;
218:
1.16 harris41 219: # (When in doubt, be paranoid about overwriting things.)
220: if (-e "$name-$version-1.i386.rpm") {
221: print(`cd $invokingdir; rm -Rf $tag`); # clean temporary filespace in use
222: die("**** ERROR **** $name-$version-1.i386.rpm already exists.\n");
223: }
1.13 harris41 224:
1.16 harris41 225: my $requires='';
1.13 harris41 226: # read in relevant requires info from customization file (if applicable)
227: # note that "PreReq: item" controls order of CD-ROM installation (if you
228: # are making a customized CD-ROM)
229: # "Requires: item" just enforces dependencies from the command-line invocation
230: $tv=grabtag('requires',$cu,1); $requires=$tv if $tv;
231: # do more require processing here
232: $requires=~s/\s*\<\/item\>\s*//g;
233: $requires=~s/\s*\<item\>\s*/\n/g;
234: $requires=~s/^\s+//s;
235:
1.16 harris41 236: my $summary='Files for the '.$name.' software package.';
1.13 harris41 237: # read in summary from customization if available
238: $tv=grabtag('summary',$cu,1); $summary=$tv if $tv;
239: $summary=~s/\<tag \/\>/$tag/g;
240:
1.14 harris41 241: my $autoreqprov='no';
242: # read in autoreqprov from customization if available
243: $tv=grabtag('autoreqprov',$cu,1); $autoreqprov=$tv if $tv;
244:
1.13 harris41 245: my $copyright="not specified here";
246: # read in copyright from customization if available
247: $tv=grabtag('copyright',$cu,1); $copyright=$tv if $tv;
248: $copyright=~s/\<tag \/\>/$tag/g;
249:
1.16 harris41 250: open(SPEC,">$tag/SPECS/$name-$version.spec");
1.13 harris41 251:
252: my $vendor='Me';
253: # read in vendor from customization if available
254: $tv=grabtag('vendor',$cu,1); $vendor=$tv if $tv;
255: $vendor=~s/\<tag \/\>/$tag/g;
256:
257: my $description="$name software package";
258: # read in description from customization if available
259: $tv=grabtag('description',$cu,0); $description=$tv if $tv;
260: $description=~s/\<tag \/\>/$tag/g;
261:
1.16 harris41 262: my $pre='';
1.13 harris41 263: # read in pre-installation script if available
264: $tv=grabtag('pre',$cu,0); $pre=$tv if $tv;
265: $pre=~s/\<tag \/\>/$tag/g;
1.1 harris41 266:
1.13 harris41 267: # ------------------------------------- Print header information for .spec file
1.19 ! harris41 268: print('Print header information for .spec file'."\n");
1.12 harris41 269:
1.16 harris41 270: print(SPEC <<END);
1.13 harris41 271: Summary: $summary
272: Name: $name
1.1 harris41 273: Version: $version
274: Release: 1
1.12 harris41 275: Vendor: $vendor
1.1 harris41 276: BuildRoot: $currentdir/BuildRoot
1.13 harris41 277: Copyright: $copyright
1.1 harris41 278: Group: Utilities/System
1.13 harris41 279: Source: $name-$version.tar.gz
1.14 harris41 280: AutoReqProv: $autoreqprov
1.7 harris41 281: $requires
1.1 harris41 282: # requires: filesystem
283: \%description
1.13 harris41 284: $description
1.1 harris41 285:
286: \%prep
287: \%setup
288:
289: \%build
290: rm -Rf "$currentdir/BuildRoot"
291:
292: \%install
293: make ROOT="\$RPM_BUILD_ROOT" SOURCE="$currentdir/BinaryRoot" directories
294: make ROOT="\$RPM_BUILD_ROOT" SOURCE="$currentdir/BinaryRoot" files
295: make ROOT="\$RPM_BUILD_ROOT" SOURCE="$currentdir/BinaryRoot" links
296:
297: \%pre
1.13 harris41 298: $pre
1.1 harris41 299:
300: \%post
301: \%postun
302:
303: \%files
304: END
305:
1.13 harris41 306: # ------------------------------------ Process file list and gather information
1.19 ! harris41 307: print('Process standard input file list and gather information.'."\n");
1.13 harris41 308:
309: my %BinaryRootMakefile;
310: my %Makefile;
311: my %dotspecfile;
312:
1.16 harris41 313: foreach my $file (<>) {
314: chomp($file);
1.4 harris41 315: my $comment="";
316: if ($file=~/\s+\#(.*)$/) {
317: $file=~s/\s+\#(.*)$//;
318: $comment=$1;
319: }
1.13 harris41 320: my $directive="";
321: if ($comment=~/config\(noreplace\)/) {
322: $directive="\%config(noreplace) ";
323: }
324: elsif ($comment=~/config/) {
325: $directive="\%config ";
326: }
327: elsif ($comment=~/doc/) {
328: $directive="\%doc";
1.4 harris41 329: }
1.1 harris41 330: if (($type,$size,$octalmode,$user,$group)=find_info($file)) {
331: $octalmode="0" . $octalmode if length($octalmode)<4;
332: if ($pathprefix) {
333: $file=~s/^$pathprefix//;
334: }
335: if ($type eq "files") {
1.16 harris41 336: push(@{$BinaryRootMakefile{$type}},"\tinstall -D -m $octalmode ".
337: "$pathprefix$file $binaryroot$file\n");
338: push(@{$Makefile{$type}},"\tinstall -D -m $octalmode ".
339: "\$(SOURCE)$file \$(ROOT)$file\n");
340: push(@{$dotspecfile{$type}},"$directive\%attr($octalmode,$user,".
341: "$group) $file\n");
1.1 harris41 342: }
343: elsif ($type eq "directories") {
1.16 harris41 344: push(@{$BinaryRootMakefile{$type}},"\tinstall -m $octalmode -d ".
345: "$binaryroot$file\n");
346: push(@{$Makefile{$type}},"\tinstall -m $octalmode -d ".
347: "\$(SOURCE)$file \$(ROOT)$file\n");
348: push(@{$dotspecfile{$type}},"\%dir \%attr($octalmode,$user,".
349: "$group) $file\n");
1.1 harris41 350: }
351: elsif ($type eq "links") {
1.12 harris41 352: my $link=$size; # I use the size variable to pass the link value
353: # from the subroutine find_info
1.1 harris41 354: $link=~s/^$pathprefix//;
1.16 harris41 355: push(@{$BinaryRootMakefile{$type}},
356: "\tln -s $link $binaryroot$file\n");
357: push(@{$Makefile{$type}},"\tln -s $link \$(ROOT)$file\n");
358: push(@{$dotspecfile{$type}},"\%attr(-,$user,$group) $file\n");
1.1 harris41 359: }
360: }
361: }
362:
1.13 harris41 363: # -------------------------------------- Generate SRPM and BinaryRoot Makefiles
1.19 ! harris41 364: print('Generate SRPM and BinaryRoot Makefiles.'."\n");
1.13 harris41 365:
1.16 harris41 366: # Generate a much needed directory.
367: # This directory is meant to hold all source code information
368: # necessary for converting .src.rpm files into .i386.rpm files.
369: mkdir("$tag/SOURCES/$name-$version",0755);
370:
371: open(OUTS,">$tag/SOURCES/$name-$version/Makefile");
372: open(OUTB, ">$tag/BinaryRootMakefile");
1.1 harris41 373: foreach $type ("directories","files","links") {
1.16 harris41 374: print(OUTS "$type\:\n");
375: print(OUTS join("",@{$Makefile{$type}})) if $Makefile{$type};
376: print(OUTS "\n");
377: print(OUTB "$type\:\n");
378: print(OUTB join("",@{$BinaryRootMakefile{$type}}))
1.13 harris41 379: if $BinaryRootMakefile{$type};
1.16 harris41 380: print(OUTB "\n");
381: print(SPEC join("",@{$dotspecfile{$type}})) if $dotspecfile{$type};
1.1 harris41 382: }
1.16 harris41 383: close(OUTB);
384: close(OUTS);
1.1 harris41 385:
1.16 harris41 386: close(SPEC);
1.1 harris41 387:
1.13 harris41 388: # ------------------ mirror copy (BinaryRoot) files under a temporary directory
1.19 ! harris41 389: print('Mirror copy (BinaryRoot) files.'."\n");
1.1 harris41 390:
391: `make -f $tag/BinaryRootMakefile directories`;
392: `make -f $tag/BinaryRootMakefile files`;
393: `make -f $tag/BinaryRootMakefile links`;
394:
1.13 harris41 395: # ------------------------------------------------- roll everything into an RPM
1.16 harris41 396: print('Build a tarball and then run the rpm -ba command.'."\n");
1.13 harris41 397: my $command="cd $currentdir/SOURCES; tar czvf $name-$version.tar.gz ".
398: "$name-$version";
1.16 harris41 399: print(`$command`);
1.12 harris41 400: $command="cd $currentdir/SPECS; rpm --rcfile=./rpmrc -ba ".
1.16 harris41 401: "$name-$version.spec; cd ../RPMS/i386; cp -v ".
1.13 harris41 402: "$name-$version-1.i386.rpm $invokingdir/.";
1.16 harris41 403: print(`$command`);
1.13 harris41 404:
405: # --------------------------------------------------------- clean everything up
1.16 harris41 406: print('Removing temporary ./'.$tag.' directory'."\n");
407: print(`cd $invokingdir; rm -Rf $tag`);
1.13 harris41 408:
1.16 harris41 409: # -------------------------------------------------------- Yeah! We're all done
410: print('Success. Script complete.'."\n");
1.1 harris41 411:
1.15 harris41 412: # ----------------------------------------------------------------- SUBROUTINES
1.13 harris41 413: # ----- Subroutine: find_info - recursively gather information from a directory
1.1 harris41 414: sub find_info {
415: my ($file)=@_;
1.16 harris41 416: my $line='';
1.1 harris41 417: if (($line=`find $file -type f -prune`)=~/^$file\n/) {
418: $line=`find $file -type f -prune -printf "\%s\t\%m\t\%u\t\%g"`;
1.16 harris41 419: return("files",split(/\t/,$line));
1.1 harris41 420: }
421: elsif (($line=`find $file -type d -prune`)=~/^$file\n/) {
422: $line=`find $file -type d -prune -printf "\%s\t\%m\t\%u\t\%g"`;
1.16 harris41 423: return("directories",split(/\t/,$line));
1.1 harris41 424: }
425: elsif (($line=`find $file -type l -prune`)=~/^$file\n/) {
1.6 harris41 426: $line=`find $file -type l -prune -printf "\%l\t\%m\t\%u\t\%g"`;
1.16 harris41 427: return("links",split(/\t/,$line));
1.1 harris41 428: }
1.16 harris41 429: die("**** ERROR **** $file is neither a directory, soft link, or file.\n");
1.1 harris41 430: }
1.13 harris41 431:
432: # ------------------------- Subroutine: grabtag - grab a tag from an xml string
433: sub grabtag {
434: my ($tag,$text,$clean)=@_;
435: # meant to be quick and dirty as opposed to a formal state machine parser
1.16 harris41 436: my $value='';
1.13 harris41 437: $cu=~/\<$tag\>(.*?)\<\/$tag\>/s;
438: $value=$1; $value=~s/^\s+//;
1.16 harris41 439: if ($clean==1) {
1.13 harris41 440: $value=~s/\n\s/ /g;
441: $value=~s/\s\n/ /g;
442: $value=~s/\n/ /g;
443: $value=~s/\s+$//;
444: }
1.16 harris41 445: return($value);
1.13 harris41 446: }
447:
448: # ----------------------------------------------------- Plain Old Documentation
449:
450: =head1 NAME
451:
1.16 harris41 452: make_rpm.pl - cleanly generate an rpm in a simple one-line command
1.13 harris41 453:
454: =head1 SYNOPSIS
455:
1.16 harris41 456: Usage: <STDIN> | make_rpm.pl <TAG> <VERSION>
457: [CONFIGURATION_FILES] [DOCUMENTATION_FILES]
458: [PATHPREFIX] [CUSTOMIZATION_XML]
459:
460: =head2 The standard input stream
461:
462: I<STDIN>, the standard input stream, provides the list of files to work
463: with. This list of file names must give the complete filesystem
464: path starting from '/'.
465:
466: =over 4
467:
468: =item * For instance, the following is invalid:
469:
470: romeodir/file1.txt # ** INVALID! ** missing leading filesystem path
471: romeodir/file2.txt
472: romeodir/file3.txt
473:
474: =item * Whereas, the following is valid:
475:
476: /home/joe/romeodir/file1.txt
477: /home/joe/romeodir/file2.txt
478: /home/joe/romeodir/file3.txt
479:
480: =item * In terms of the B<find> command,
481:
482: "find romeodir | perl make_rpm.pl [COMMAND-LINE ARGUMENTS]"
483:
484: is incorrect, whereas
485:
486: "find /home/joe/romeodir |perl make_rpm.pl [COMMAND-LINE ARGUMENTS]"
487:
488: or
489:
490: "find `pwd`/romeodir |perl make_rpm.pl [COMMAND-LINE ARGUMENTS]"
491:
492: is correct.
493:
494: =back
495:
496: The standard input stream can also
497: specify configuration files and documentation files through
498: '#'-style commenting.
499:
500: For example, the following file listing encodes some of these directives:
501:
502: /home/joe/romeodir/buildloc/etc/romeo/user.conf # config(noreplace)
503: /home/joe/romeodir/buildloc/etc/romeo/juliet.conf # config
504: /home/joe/romeodir/buildloc/doc/man/man.1/romeo.1 # doc
505: /home/joe/romeodir/buildloc/doc/man/man.1/romeo_talks.1 # doc
506: /home/joe/romeodir/buildloc/usr/local/bin/where_art_thou
507: /home/joe/romeodir/buildloc/usr/local/bin/romeo_talks
508:
509: The I<config> directive controls how files are replaced
510: and/or backed up when a user attempts to install (B<rpm -i>) the F<.rpm>
511: file generated by B<make_rpm.pl>. The I<doc> directive controls how a
512: given file is placed inside special documentation directories
513: on the filesystem during rpm installation (B<rpm -i>).
514: (If you want to learn more on how the B<rpm> tool gives configuration and
515: documentation files special treatment, you should read about "Directives"
516: in Edward Bailey's well-known "Maximum RPM" book available online
517: at http://www.rpm.org/max-rpm/s1-rpm-inside-files-list-directives.html.)
1.13 harris41 518:
1.16 harris41 519: =head2 Description of command-line arguments
1.13 harris41 520:
1.16 harris41 521: I<TAG> ($tag), B<required> descriptive tag. For example, a kerberos software
1.13 harris41 522: package might be tagged as "krb4".
523:
1.16 harris41 524: I<VERSION> ($version), B<required> version. Needed to generate version
525: information for the RPM. This should be in the format N.M where N and M are
1.13 harris41 526: integers.
527:
1.16 harris41 528: I<CONFIGURATION_FILES>, B<optional> comma-separated listing of files to
1.13 harris41 529: be treated as configuration files by RPM (and thus subject to saving
1.16 harris41 530: during RPM upgrades). Configuration files can also be specified in
531: the standard input stream (as described in L<"The standard input stream">).
1.13 harris41 532:
1.16 harris41 533: I<DOCUMENTATION_FILES>, B<optional> comma-separated listing of files to be
1.13 harris41 534: treated as documentation files by RPM (and thus subject to being
1.16 harris41 535: placed in the F</usr/doc/RPM-NAME> directory during RPM installation).
536: Documentation files can also be specified in
537: the standard input stream (as described in L<"The standard input stream">).
1.13 harris41 538:
1.16 harris41 539: I<PATHPREFIX>, B<optional> path to be removed from file listing. This
1.13 harris41 540: is in case you are building an RPM from files elsewhere than
541: root-level. Note, this still depends on a root directory hierarchy
542: after PATHPREFIX.
543:
1.16 harris41 544: I<CUSTOMIZATION_XML>, B<optional> filename where XML-ish information exists.
545: Allows for customizing various pieces of information such
1.13 harris41 546: as vendor, summary, name, copyright, group, autoreqprov, requires, prereq,
1.16 harris41 547: description, and pre-installation scripts
548: (see L<"Customizing descriptive data of your RPM software package">).
1.13 harris41 549:
1.16 harris41 550: =head2 Examples
1.13 harris41 551:
1.16 harris41 552: bash$ find /notreallyrootdir | perl make_rpm.pl \
553: makemoney 3.1 '' \
554: '/usr/doc/man/man3/makemoney.3' \
555: /notreallyrootdir
1.13 harris41 556: would generate makemoney-3.1-1.i386.rpm
557:
1.16 harris41 558: bash$ find /usr/local/bin | \
559: perl make_rpm.pl mybinfiles 1.0
1.13 harris41 560: would generate mybinfiles-1.0-1.i386.rpm
561:
1.16 harris41 562: bash$ find /home/joe/romeodir/buildloc | \
563: perl make_rpm.pl romeo \
564: 1.0 '' '' '/home/joe/romeodir/buildloc' customize.xml
1.13 harris41 565: would generate romeo with customizations from customize.xml.
566:
1.16 harris41 567: The I<CUSTOMIZATION_XML> argument represents a way to customize the
1.13 harris41 568: numerous variables associated with RPMs. This argument represents
569: a file name. (Parsing is done in an unsophisticated fashion using
1.16 harris41 570: regular expressions.) See
571: L<"Customizing descriptive data of your RPM software package">.
572:
573: =head1 Customizing descriptive data of your RPM software package
574:
575: RPMS can be (and often are) packaged with descriptive data
576: describing authorship, dependencies, descriptions, etc.
577:
578: The following values can be tagged inside an XML file
579: (specified by the 6th command-line argument)
580: and made part of the RPM package information
581: (B<rpm -qi E<lt>package-nameE<gt>>).
582:
583: =over 4
584:
585: =item * vendor
586:
587: =item * summary
588:
589: =item * name
590:
591: (overrides the <TAG> argument value; see
592: L<"Description of command-line arguments>)
593:
594: =item * copyright
595:
596: =item * group
597:
598: (the software package group;
599: e.g. Applications/System, User Interface/X, Development/Libraries,
600: etc.)
601:
602: =item * requires
603:
604: Contains all the dependency information (see the example below).
605:
606: =item * description
607:
608: =item * pre
609:
610: Commands to be executed prior to software package installation.
611:
612: =back
613:
614: Here is an example (note that B<make_rpm.pl> automatically substitutes
615: any "<tag />" string with the first command-line argument described
616: in L<"Description of command-line arguments">):
1.13 harris41 617:
618: <vendor>
619: Laboratory for Instructional Technology Education, Division of
620: Science and Mathematics Education, Michigan State University.
621: </vendor>
622: <summary>Files for the <tag /> component of LON-CAPA</summary>
623: <name>LON-CAPA-<tag /></name>
624: <copyright>Michigan State University patents may apply.</copyright>
625: <group>Utilities/System</group>
626: <AutoReqProv>no</AutoReqProv>
627: <requires tag='setup'>
628: <item>PreReq: setup</item>
629: <item>PreReq: passwd</item>
630: <item>PreReq: util-linux</item>
631: </requires>
632: <requires tag='base'>
633: <item>PreReq: LON-CAPA-setup</item>
634: <item>PreReq: apache</item>
635: <item>PreReq: /etc/httpd/conf/access.conf</item>
636: </requires>
637: <requires>
638: <item>Requires: LON-CAPA-base</item>
639: </requires>
640: <description>
641: This package is automatically generated by the make_rpm.pl perl
642: script (written by the LON-CAPA development team, www.lon-capa.org,
643: Scott Harrison). This implements the <tag /> component for LON-CAPA.
644: For more on the LON-CAPA project, visit http://www.lon-capa.org/.
645: </description>
646: <pre>
1.16 harris41 647: echo "************************************************************"
1.13 harris41 648: echo "LON-CAPA LearningOnline with CAPA"
649: echo "http://www.lon-capa.org/"
650: echo " "
651: echo "Laboratory for Instructional Technology Education"
652: echo "Michigan State University"
653: echo " "
654: echo "** Michigan State University patents may apply **"
655: echo " "
656: echo "This installation assumes an installation of Redhat 6.2"
657: echo " "
1.16 harris41 658: echo "The files in this package are for the <tag /> component."
659: echo "***********************************************************"
1.13 harris41 660: </pre>
661:
662: =head1 DESCRIPTION
663:
664: Automatically generate an RPM software package from a list of files.
665:
1.16 harris41 666: B<make_rpm.pl> builds the RPM in a very clean and configurable fashion.
667: (Finally! Making RPMs outside of F</usr/src/redhat> without a zillion
1.15 harris41 668: file intermediates left over!)
1.13 harris41 669:
1.16 harris41 670: B<make_rpm.pl> generates and then deletes temporary
1.15 harris41 671: files needed to build an RPM with.
672: It works cleanly and independently from pre-existing
1.16 harris41 673: directory trees such as F</usr/src/redhat/*>.
1.13 harris41 674:
1.16 harris41 675: Input to the script is simple. B<make_rpm.pl> accepts five kinds of
676: information, three of which are mandatory:
1.15 harris41 677:
678: =over 4
679:
680: =item *
681:
1.16 harris41 682: (required) a list of files that are to be part of the software package;
1.15 harris41 683:
1.16 harris41 684: =item *
685:
686: (required) the absolute filesystem location of these files
687: (see L<"The standard input stream">);
688:
689: =item *
1.15 harris41 690:
1.16 harris41 691: (required) a descriptive tag and a version tag for the naming of the
692: RPM software package;
1.15 harris41 693:
694: =item *
695:
1.16 harris41 696: (optional) documentation and configuration files;
1.15 harris41 697:
698: =item *
699:
700: and (optional) an XML file that defines the additional metadata
701: associated with the RPM software package.
702:
703: =back
704:
1.16 harris41 705: A temporary directory named $tag (first argument described in
706: L<"Description of command-line arguments">) is
707:
708: =over 4
709:
710: =item *
711:
712: generated under the directory from which you run B<make_rpm.pl>.
713:
714: For example, user "joe" running
715:
716: cat file_list.txt | make_rpm.pl krb4 1.0
717:
718: would temporarily generate F</home/joe/krb4/>.
719:
720: =item *
721:
722: F</home/joe/krb4/> is deleted after the *.rpm
723: file is generated.
724:
725: =back
726:
727: The RPM will typically be named $name-$version.i386.rpm
728: where $name=$tag. (The $name can be overridden in the customization
729: XML file; see
730: L<"Customizing descriptive data of your RPM software package">.)
731:
732: Here are some of the items are generated inside
733: the $tag directory during the construction of an RPM:
734:
735: =over 4
736:
737: =item *
738:
739: RPM .spec file (F<./$tag/SPECS/$name-$version.spec>)
740:
741: =item *
742:
743: RPM Makefile (F<./$tag/SOURCES/$name-$version/Makefile>)
744:
745: This is the Makefile that is called by the rpm
746: command in building the .i386.rpm from the .src.rpm.
747: The following directories are generated and/or used:
1.15 harris41 748:
749: =over 4
750:
751: =item *
752:
1.16 harris41 753: SOURCE directory: F<./$tag/BinaryRoot/>
754:
755: =item *
756:
757: TARGET directory: F<./$tag/BuildRoot/>
758:
759: =back
760:
761: =item *
762:
763: BinaryRootMakefile (F<./$tag/BinaryRootMakefile>)
764:
765: This is the Makefile that this script creates and calls
766: to build the F<$tag/BinaryRoot/> directory from the existing
767: filesystem.
768: The following directories are generated and/or used:
769:
770: =over 4
1.15 harris41 771:
772: =item *
773:
1.16 harris41 774: SOURCE directory: / (your entire filesystem)
1.15 harris41 775:
776: =item *
777:
1.16 harris41 778: TARGET directory: F<./$tag/BinaryRoot/>
1.15 harris41 779:
780: =back
1.13 harris41 781:
1.16 harris41 782: =back
783:
784: The final output of B<make_rpm.pl> is a binary F<.rpm> file.
785: The F<./tag> directory is deleted (along with the F<.src.rpm>
786: file). The typical file name generated by B<make_rpm.pl> is
787: F<$tag-$version.i386.rpm>.
1.13 harris41 788:
1.16 harris41 789: B<make_rpm.pl> is compatible with either rpm version 3.* or rpm version 4.*.
1.15 harris41 790:
1.13 harris41 791: =head1 README
792:
793: Automatically generate an RPM software package from a list of files.
794:
1.16 harris41 795: B<make_rpm.pl> builds the RPM in a very clean and configurable fashion.
796: (Making RPMs "the simple way" in a one-line command.)
1.13 harris41 797:
1.16 harris41 798: B<make_rpm.pl> generates and then deletes temporary
1.13 harris41 799: files (and binary root directory tree) to build an RPM with.
800: It is designed to work cleanly and independently from pre-existing
801: directory trees such as /usr/src/redhat/*.
802:
803: =head1 PREREQUISITES
804:
805: This script requires the C<strict> module.
806:
1.16 harris41 807: =head1 AUTHOR
808:
809: Scott Harrison
810: harris41@msu.edu
811:
812: Please let me know how/if you are finding this script useful and
813: any/all suggestions. -Scott
814:
815: =head1 LICENSE
816:
817: Written by Scott Harrison, harris41@msu.edu
818:
819: Copyright Michigan State University Board of Trustees
820:
821: This file is part of the LearningOnline Network with CAPA (LON-CAPA).
822:
823: This is free software; you can redistribute it and/or modify
824: it under the terms of the GNU General Public License as published by
825: the Free Software Foundation; either version 2 of the License, or
826: (at your option) any later version.
827:
828: This file is distributed in the hope that it will be useful,
829: but WITHOUT ANY WARRANTY; without even the implied warranty of
830: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
831: GNU General Public License for more details.
832:
833: The GNU Public License is available for review at
834: http://www.gnu.org/copyleft/gpl.html.
835:
836: For information on the LON-CAPA project, please visit
837: http://www.lon-capa.org/.
838:
839: =head1 OSNAMES
1.13 harris41 840:
1.15 harris41 841: Linux
1.13 harris41 842:
1.16 harris41 843: =head1 SCRIPT CATEGORIES
1.13 harris41 844:
1.17 harris41 845: UNIX/System_administration
1.13 harris41 846:
847: =cut
1.16 harris41 848:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>