refactor packaging into perl package so that it can be called from MacPerl. add basebrowser embed packaging to mac build. r=adamlock/sr=alecf/a=asa. bug#129737

This commit is contained in:
pinkerton%netscape.com 2002-03-19 22:05:19 +00:00
Родитель 2ef941a509
Коммит fb366798fa
4 изменённых файлов: 908 добавлений и 583 удалений

Просмотреть файл

@ -223,6 +223,7 @@ res:maccharset.properties
; required i18n libs
Components:strres.shlb
Components:nsIStringBundle.xpt
; required prefs files
defaults:pref:all.js

Просмотреть файл

@ -0,0 +1,274 @@
; Base Embedding Package File for MacOS CFM (built with CodeWarrior)
;
;
;
[Embed]
;
; NSPR:
;
Essential Files:NSPR20Debug.shlb
Essential Files:NSRuntimeDebug.shlb
Essential Files:NSStdLibDebug.shlb
;
; Javascript:
;
Essential Files:JavaScriptDebug.shlb
Essential Files:LiveConnectDebug.shlb
;
; DOM:
;
Components:domDebug.shlb
;
; XPCOM:
;
Essential Files:xpcomDebug.shlb
Essential Files:libregDebug.shlb
;
; Imaging:
;
Essential Files:zlibDebug.shlb
;
; Components: (need to trim fat)
;
; accessibility (out of process API support)
; see http:::www.mozilla.org:projects:ui:accessibility:vendors-win.html
; Components:accessibilityDebug.dll
; Components:accessibility.xpt
; appshell
Components:AppShellDebug.shlb
Components:appshell.xpt
; caps
Components:CapsDebug.shlb
Components:caps.xpt
; chrome
Components:ChomeRegistryDebug.shlb
Components:chrome.xpt
; cookies
Components:CookieDebug.shlb
Components:cookie.xpt
; docshell
Components:docshellDebug.shlb
Components:docshell.xpt
; dom
Components:domDebug.shlb
Components:dom.xpt
Components:dom_base.xpt
Components:dom_core.xpt
Components:dom_css.xpt
Components:dom_events.xpt
Components:dom_html.xpt
Components:dom_range.xpt
Components:dom_stylesheets.xpt
Components:dom_traversal.xpt
Components:dom_views.xpt
Components:dom_xbl.xpt
Components:dom_xul.xpt
; editor
Components:ComposerDebug.shlb
; Components:EditorCoreDebug.shlb ; why not?
Components:editor.xpt
Components:htmleditorDebug.shlb
; embedding
Components:webBrowserDebug.shlb
Components:embeddingbrowser.xpt
Components:EmbedComponentsDebug.shlb
Components:EmbedComponents.xpt
Components:EmbedBase.xpt
Components:webshell.xpt
; find functionality
; Optional - only if your code uses nsIWebBrowserFind
Components:TextServicesDebug.shlb
Components:txtsvc.xpt
; gfx
Essential Files:gfxDebug.shlb
Components:gfxComponentDebug.shlb
; javascript
Components:JSUrlDebug.shlb
Components:jsurl.xpt
; layout
Components:contentDebug.shlb
res:dtd:*
Components:layoutDebug.shlb
Components:htmlparserDebug.shlb
Components:htmlparser.xpt
Components:viewDebug.shlb
Components:content.xpt
Components:layout.xpt
; netwerk
Components:NeckoDebug.shlb
Components:necko.xpt
Components:Necko2Debug.shlb
Components:CacheDebug.shlb
Components:cache.xpt
; imagelib
Components:libimg2Debug.shlb
Components:libimg2.xpt
Components:gifdecoder2Debug.shlb
Components:jpegdecoder2Debug.shlb
Components:pngdecoder2Debug.shlb
Components:mngdecoderDebug.shlb
Components:gfx2Debug.shlb
Components:gfx2.xpt
; jar
Components:libjarDebug.shlb
Components:libjar.xpt
; prefs
Components:libprefDebug.shlb
Components:libpref.xpt
; plugins
; Optional - only if you need plugin support
Components:pluginDebug.shlb
Components:pluginClassicDebug.shlb
Components:plugin.xpt
Components:ojiDebug.shlb
Components:oji.xpt
; profile
Components:profileDebug.shlb
Components:profileservices.xpt
; wallet
; Optional - only if you need password persistence
Components:WalletDebug.shlb
Components:wallet.xpt
; psm2
; Optional - only if you need PSM2 support
Components:pipbootDebug.shlb
Components:pipboot.xpt
Components:PIPNSSDebug.shlb
Components:pipnss.xpt
Chrome:pipnss.jar
Components:PIPPKIDebug.shlb
Components:pippki.xpt
Chrome:pippki.jar
defaults:pref:security-prefs.js
Essential Files:NSS3Debug.shlb
Essential Files:SMIME3Debug.shlb
Essential Files:Softoken3Debug.shlb
Essential Files:SSL3Debug.shlb
; appcomps
; Optional - only if you want global history (requires mork) or
; directory viewer (off by default for ftp view)
Components:mozcomps.xpt
Components:morkDebug.shlb
; rdf
Components:RDFLibraryDebug.shlb
Components:rdf.xpt
; session history
Components:shistoryDebug.shlb
Components:shistory.xpt
; required l10n libraries
Components:intl.xpt
Components:locale.xpt
Components:unicharutilDebug.shlb
Components:unicharutil.xpt
Components:uconvDebug.shlb
Components:uconv.xpt
Components:lwbrkDebug.shlb
Components:nslocaleDebug.shlb
Components:nslocale.xpt
Components:ucvlatinDebug.shlb
Components:chardetDebug.shlb
Components:chardet.xpt
Components:UniversalchardetDebug.shlb
; optional - on english only systems
; Components:ucvjaDebug.shlb for japanese
; Components:ucvkoDebug.shlb for korean
; Components:ucvcnDebug.shlb for simplified chinese
; Components:ucvtwDebug.shlb for traditional chinese
; Components:ucvtw2Debug.shlb for traditional chinese
; Components:ucvibmDebug.shlb for ibm
res:language.properties
res:langGroups.properties
res:charsetData.properties
res:charsetalias.properties
res:maccharset.properties
; required i18n libs
Components:strresDebug.shlb
Components:nsIStringBundle.xpt
; required prefs files
defaults:pref:all.js
defaults:pref:initpref.js
defaults:pref:macprefs.js
; uriloader
Components:uriLoaderDebug.shlb
Components:uriLoader.xpt
; widget
Essential Files:WidgetSupportDebug.shlb
Components:widgetDebug.shlb
Components:widget.xpt
; xpconnect
Components:XPConnectDebug.shlb
Components:xpconnect.xpt
; xpcom
Components:xpcom.xpt
;
; Widget-Toolkit and Res (consult hyatt@netscape.com before modifying):
;
Chrome:embed.jar
;
; res:
;
res:html.css
res:quirk.css
res:viewsource.css
res:ua.css
res:forms.css
res:arrow.gif
res:arrowd.gif
res:loading-image.gif
res:broken-image.gif
res:builtin:htmlBindings.xml
res:builtin:platformHTMLBindings.xml
res:entityTables:html40Latin1.properties
res:entityTables:html40Special.properties
res:entityTables:html40Symbols.properties
res:entityTables:htmlEntityVersions.properties
res:entityTables:transliterate.properties

Просмотреть файл

@ -0,0 +1,624 @@
#!perl -w
package Packager;
require 5.004;
use strict;
use File::stat;
use Cwd;
use File::Basename;
use File::Copy;
use File::Find;
use File::Path;
use File::stat;
require Exporter;
use vars qw(@ISA @EXPORT);
# Package that generates a jar manifest from an input file
@ISA = qw(Exporter);
@EXPORT = qw(
Copy
);
# initialize variables
my($saved_cwd) = cwd();
my($component) = ""; # current component being copied
my(@components) = (); # list of components to copy
my($components) = ""; # string version of @components
my($PD) = ""; # file Path Delimiter ( /, \, or :)
my($altdest) = ""; # alternate file destination
my($line) = ""; # line being processed
my($srcdir) = ""; # root directory being copied from
my($destdir) = ""; # root directory being copied to
my($package) = ""; # file listing files to copy
my($os) = ""; # os type (MacOS, MSDOS, Unix, OS/2)
my($lineno) = 0; # line # of package file for error text
my($debug) = 0; # controls amount of debug output
my($dirflag) = 0; # flag: are we copying a directory?
my($help) = 0; # flag: if set, print usage
my($flat) = 0; # copy everything into the package dir, not into separate
# component dirs
#
# Copy
#
# Loop over each line in the specified manifest, copying into $destdir
#
sub Copy {
($srcdir, $destdir, $package, $os, $flat, $help, $debug, @components) = @_;
check_arguments();
open (MANIFEST,"<$package") ||
die "Error: couldn't open file $package for reading: $!. Exiting...\n";
LINE: while (<MANIFEST>) {
$line = "";
$altdest = "";
$lineno++;
s/\;.*//; # it's a comment, kill it.
s/^\s+//; # nuke leading whitespace
s/\s+$//; # nuke trailing whitespace
($debug >= 2) && print "\n";
($debug >= 8) && print "line $lineno:$_\n";
# it's a blank line, skip it.
/^$/ && do {
($debug >= 10) && print "blank line.\n";
next LINE;
};
# it's a new component
/^\[/ && do {
($debug >= 10) && print "component.\n";
$component = $_;
do_component();
next LINE;
};
# make sure a component is defined before doing any copies or deletes.
if (( $component eq "" ) && ($components eq "" )) {
die "Error: item $_ outside a component ($package, $lineno). Exiting...\n";
}
# skip line if we're only copying specific components and outside
# those components
if (( $component eq "" ) && ($components ne "" )) {
($debug >= 10) && print "Not in specifed component. Skipping $_\n";
next LINE;
}
if ($line eq "") {
$line = $_; # if $line not set, set it.
}
if ($os ne "MSDOS") { # hack - need to fix for dos
$line =~ s/^$PD//; # strip any leading path delimiter
}
# delete the file or directory following the '-'
/^-/ && do {
$line =~ s/^-//; # strip leading '-'
($debug >= 10) && print "delete: $destdir$PD$component$PD$line\n";
do_delete ("$destdir", "$component", "$line");
next LINE;
};
# file/directory being copied to different target location
/\,/ && do {
/.*\,.*\,.*/ &&
die "Error: multiple commas not allowed ($package, $lineno): $_.\n";
($line, $altdest) = split (/\s*\,\s*/, $line, 2);
$line =~ s/$PD*$//; # strip any trailing path delimiters
$altdest =~ s/$PD*$//; # strip any trailing delimiter
($debug >= 10) && print "relocate: $line => $altdest.\n";
};
# if it has wildcards, do recursive copy.
/(?:\*|\?)/ && do {
($debug >= 10) && print "wildcard copy.\n";
if ($os eq "MacOS") {
if (/:\*$/) {
($debug >= 4) && print "Mac and wildcard is \":*\" so strip and copy entire directory.\n";
$line =~ s/:\*$//; # Mac doesn't like wildcards, so strip off any ":*" at the end of the line
# and copy the whole directory.
do_copydir ("$srcdir$PD$line");
}
} else {
do_wildcard ("$srcdir$PD$line");
}
next LINE;
};
# if it's a single file, copy it.
( -f "$srcdir$PD$line" ) && do {
($debug >= 10) && print "file copy.\n";
do_copyfile ();
next LINE;
};
# if it's a directory, do recursive copy.
(-d "$srcdir$PD$line") && do {
($debug >= 10) && print "directory copy.\n";
do_copydir ("$srcdir$PD$line");
next LINE;
};
# if we hit this, it's either a file in the package file that is
# not in the src directory, or it is not a valid entry.
warn "Warning: package error or possible missing or unnecessary file: $line ($package, $lineno).\n";
} # LINE
close (MANIFEST);
chdir ($saved_cwd);
}
#
# Delete the given file or directory
#
sub do_delete
{
my ($targetpath) = $_[0];
my ($targetcomp) = $_[1];
my ($targetfile) = $_[2];
my ($target) = ($flat) ? "$targetpath$PD$targetfile" : "$targetpath$PD$targetcomp$PD$targetfile";
($debug >= 2) && print "do_delete():\n";
($debug >= 1) && print "-$targetfile\n";
if ( -f $target ) {
(! -w $target ) &&
die "Error: delete failed: $target not writeable ($package, $component, $lineno). Exiting...\n";
($debug >= 4) && print " unlink($target)\n";
unlink ($target) ||
die "Error: unlink() failed: $!. Exiting...\n";
} elsif ( -d $target ) {
(! -w $target ) &&
die "Error: delete failed: $target not writeable ($package, $component, $lineno). Exiting...\n";
($debug >= 4) && print " rmtree($target)\n";
rmtree ($target, 0, 0) ||
die "Error: rmtree() failed: $!. Exiting...\n";
} else {
warn "Warning: delete failed: $target is not a file or directory ($package, $component, $lineno).\n";
}
}
#
# Copy an individual file from the srcdir to the destdir.
#
# This is called by both the individual and batch/recursive copy routines,
# using $dirflag to check if called from do_copydir. Batch copy can pass in
# directories, so be sure to check first and break if it isn't a file.
#
sub do_copyfile
{
my ($destpath) = ""; # destination directory path
my ($destpathcomp) = ""; # ditto, but possibly including component dir
my ($destname) = ""; # destination file name
my ($destsuffix) = ""; # destination file name suffix
my ($altpath) = ""; # alternate destination directory path
my ($altname) = ""; # alternate destination file name
my ($altsuffix) = ""; # alternate destination file name suffix
my ($srcpath) = ""; # source file directory path
my ($srcname) = ""; # source file name
my ($srcsuffix) = ""; # source file name suffix
my ($curdir) = getcwd; # need current dir on OS/2 to switch back
($debug >= 2) && print "do_copyfile():\n";
# set srcname correctly depending on how called
if ( $dirflag ) {
($srcname, $srcpath, $srcsuffix) = fileparse("$File::Find::name", '\..*?$');
} else {
($srcname, $srcpath, $srcsuffix) = fileparse("$srcdir$PD$line", '\..*?$');
}
($debug >= 4) && print " fileparse(src): $srcpath $srcname $srcsuffix\n";
# return if srcname is a directory from do_copydir
if ( -d "$srcpath$srcname$srcsuffix" ) {
($debug >= 10) && print " return: $srcpath$srcname$srcsuffix is a directory\n";
return;
}
# set the destination path, if alternate destination given, use it.
if ($flat) {
$destpathcomp = "$destdir";
} else {
# double-check that we have a valid component before appending the path
# delimiter. If $component is empty, we'd end up placing an extra : at
# the end, which unix ignores, but on mac sends us up an extra level.
if ( $component ne "" ) {
$destpathcomp = "$destdir$PD$component";
}
else {
$destpathcomp = "$destdir";
}
}
if ( $altdest ne "" ) {
if ( $dirflag ) { # directory copy to altdest
($destname, $destpath, $destsuffix) = fileparse("$destpathcomp$PD$altdest$PD$File::Find::name", '\..*?$');
# Todo: add MSDOS hack
$destpath =~ s/$srcdir$PD$line$PD//; # rm info added by find
($debug >= 5) &&
print " dir copy to altdest: $destpath $destname $destsuffix\n";
} else { # single file copy to altdest
($destname, $destpath, $destsuffix) = fileparse("$destpathcomp$PD$altdest", '\..*?$');
($debug >= 5) &&
print " file copy to altdest: $destpath $destname $destsuffix\n";
}
} else {
if ( $dirflag ) { # directory copy, no altdest
($destname, $destpath, $destsuffix) = fileparse("$destpathcomp$PD$File::Find::name", '\..*?$');
# avert your eyes now, butt-ugly hack
if ( $os eq "MSDOS" ) {
$destpath =~ s/\\/\//g;
$srcdir =~ s/\\/\//g;
$PD = "/";
$destpath =~ s/$srcdir$PD//g;
$destpath =~ s/\//\\/g;
$srcdir =~ s/\//\\/g;
$PD = "\\";
} elsif ( $os eq "OS2") {
#Don't Look! Seriously...
$destpath =~ s/\\/\//g;
$srcdir =~ s/\\/\//g;
$PD = "/";
$destpath =~ s/$srcdir$PD//g;
$destpath = "$srcdir$PD$destpath";
$PD = "\\";
} else {
$destpath =~ s/$srcdir$PD//;
}
# end stupid MSDOS hack
($debug >= 5) &&
print " dir copy w/o altdest: $destpath $destname $destsuffix\n";
} else { # single file copy, no altdest
($destname, $destpath, $destsuffix) = fileparse("$destpathcomp$PD$line", '\..*?$');
($debug >= 5) &&
print " file copy w/o altdest: $destpath $destname $destsuffix\n";
}
}
#Ensure correct directory
if ($os eq "OS2") {
chdir($saved_cwd);
}
# create the destination path if it doesn't exist
if (! -d "$destpath" ) {
($debug >= 5) && print " mkpath($destpath)\n";
#OS2 hack. Sorry... Chop off "/"
chop($destpath);
mkpath ($destpath, 0, 0755) ||
die "Error: mkpath() failed: $!. Exiting...\n";
# Put delimeter back for copying...
$destpath = "$destpath$PD";
}
# path exists, source and destination known, time to copy
if ((-f "$srcpath$srcname$srcsuffix") && (-r "$srcpath$srcname$srcsuffix")) {
if ( $debug >= 1 ) {
if ( $dirflag ) {
print "$destname$destsuffix\n"; # from unglob
} else {
print "$line\n"; # from single file
}
if ( $debug >= 3 ) {
print " copy\t$srcpath$srcname$srcsuffix =>\n\t\t$destpath$destname$destsuffix\n";
}
}
unlink("$destpath$destname$destsuffix") if ( -e "$destpath$destname$destsuffix");
copy ("$srcpath$srcname$srcsuffix", "$destpath$destname$destsuffix") ||
die "Error: copy of file $srcpath$srcname$srcsuffix failed ($package, $component, $lineno): $!. Exiting...\n";
# if this is unix, set the dest file permissions
if ( $os eq "Unix" ) {
# read permissions
my($st) = stat("$srcpath$srcname$srcsuffix") ||
die "Error: can't stat $srcpath$srcname$srcsuffix: $! Exiting...\n";
# set permissions
($debug >= 2) && print " chmod ".$st->mode." $destpath$destname$destsuffix\n";
chmod ($st->mode, "$destpath$destname$destsuffix") ||
warn "Warning: chmod of $destpath$destname$destsuffix failed: $!. Exiting...\n";
}
} else {
warn "Error: file $srcpath$srcname$srcsuffix is not a file or is not readable ($package, $component, $lineno).\n";
}
#Resetting dir...
if ($os eq "OS2") {
chdir($curdir);
}
}
#
# Expand any wildcards and copy files and/or directories
#
# todo: pass individual files to do_copyfile, not do_copydir
#
sub do_wildcard
{
my ($entry) = $_[0];
my (@list) = ();
my ($item) = "";
($debug >= 2) && print "do_wildcard():\n";
if ( $entry =~ /(?:\*|\?)/ ) { # it's a wildcard,
if ($os eq "MacOS") {
warn "Warning: globbing on Mac not supported.\nWorkaround is to copy entire directory.\n";
@list = <$entry>;
} elsif ( $os eq "OS2") {
#warn "Warning: globbing on OS/2 not supported.\nWorkaround is to copy entire directory.\n";
@list = $entry;
chop($list[0]);
} else {
@list = glob($entry); # expand it
}
($debug >= 4) && print " glob: $entry => @list\n";
foreach $item ( @list ) { # now copy each item in list
if ( -f $item ) {
($debug >= 10) && print " do_copyfile: $item\n";
# glob adds full path to item like find() in copydir so
# take advantage of existing code in copyfile by using
# $dirflag and $File::Find::name.
$File::Find::name = $item;
$dirflag = 1;
do_copyfile();
$dirflag = 0;
$File::Find::name = "";
} elsif ( -d $item ) {
($debug >= 10) && print " do_copydir($item)\n";
do_copydir ($item);
} else {
warn "Warning: $item is not a file or directory ($package, $component, $lineno). Skipped...\n";
}
}
}
}
#
# Recursively copy directories specified.
#
sub do_copydir
{
my ($entry) = $_[0];
$dirflag = 1; # flag indicating directory copy in progress
($debug >= 2) && print "do_copydir():\n";
if (! -d "$entry" ) {
warn "Warning: $entry is not a directory ($package, $component, $lineno). Skipped...\n";
}
($debug >= 4) && print " find($entry)\n";
find (\&do_copyfile, $entry);
$dirflag = 0;
}
#
# Handle new component
#
sub do_component
{
($debug >= 2) && print "do_component():\n";
( $component =~ /^\[.*(?:\s|\[|\])+.*\]/ ) && # no brackets or ws
die "Error: malformed component $component. Exiting...\n";
$component =~ s/^\[(.*)\]/$1/; # strip []
if ( $components ne "") {
if ( $components =~ /$component/ ) {
($debug >= 10) && print "Component $component is in $components.\n";
} else {
($debug >= 10) && print "Component $component not in $components.\n";
$component = "";
return; # named specific components and this isn't it
}
}
if ($debug >= 1) {
print "[$component]\n";
}
# create component directory
if (!$flat) {
if ( -d "$destdir$PD$component" ) {
warn "Warning: component directory \"$component\" already exists in \"$destdir\".\n";
} else {
($debug >= 4) && print " mkdir $destdir$PD$component\n";
mkdir ("$destdir$PD$component", 0755) ||
die "Error: couldn't create component directory \"$component\": $!. Exiting...\n";
}
}
}
#
# Check that arguments to script are valid.
#
sub check_arguments
{
my ($exitval) = 0;
($debug >= 2) && print "check_arguments():\n";
# if --help print usage
if ($help) {
print_usage();
exit (1);
}
# make sure required variables are set:
# check source directory
if ( $srcdir eq "" ) {
print "Error: source directory (--source) not specified.\n";
$exitval += 8;
} elsif ((! -d $srcdir) || (! -r $srcdir)) {
print "Error: source directory \"$srcdir\" is not a directory or is unreadable.\n";
$exitval = 1;
}
# check destination directory
if ( $destdir eq "" ) {
print "Error: destination directory (--destination) not specified.\n";
$exitval += 8;
} elsif ((! -d $destdir) || (! -w $destdir)) {
print "Error: destination directory \"$destdir\" is not a directory or is not writeable.\n";
$exitval += 2;
}
# check destdir not a subdir of srcdir
# hack - workaround for bug 14558 that should be fixed eventually.
if (0) { # todo - write test
print "Error: destination directory must not be subdirectory of the source directory.\n";
$exitval += 32;
}
# check package file
if ( $package eq "" ) {
print "Error: package file (--file) not specified.\n";
$exitval += 8;
} elsif (!(-f $package) || !(-r $package)) {
print "Error: package file \"$package\" is not a file or is unreadable.\n";
$exitval += 4;
}
# check OS == {mac|unix|dos|os2}
if ($os eq "") {
print "Error: OS type (--os) not specified.\n";
$exitval += 8;
} elsif ( $os =~ /mac/i ) {
$os = "MacOS";
$PD = ":";
fileparse_set_fstype ($os);
} elsif ( $os =~ /dos/i ) {
$os = "MSDOS";
$PD = "\\";
fileparse_set_fstype ($os);
} elsif ( $os =~ /unix/i ) {
$os = "Unix"; # can be anything but MacOS, MSDOS, or VMS
$PD = "/";
fileparse_set_fstype ($os);
} elsif ( $os =~ /os2/i) {
$os = "OS2";
$PD = "/";
fileparse_set_fstype($os);
} else {
print "Error: OS type \"$os\" unknown.\n";
$exitval += 16;
}
# turn components array into a string for regexp
if ( @components > 0 ) {
$components = join (",",@components);
} else {
$components = "";
}
if ($debug > 4) {
print ("source dir:\t$srcdir\ndest dir:\t$destdir\npackage:\t$package\nOS:\t$os\ncomponents:\t$components\n");
}
if ($exitval) {
print "See \'$0 --help\' for more information.\n";
print "Exiting...\n";
exit ($exitval);
}
}
#
# display usage information
#
sub print_usage
{
($debug >= 2) && print "print_usage():\n";
print <<EOC
$0
Copy files from the source directory to component directories
in the destination directory as specified by the package file.
Options:
-s, --source <source directory>
Specifies the directory from which to copy the files
specified in the file passed via --file.
Required.
-d, --destination <destination directory>
Specifies the directory in which to create the component
directories and copy the files specified in the file passed
via --file.
Required.
NOTE: Source and destination directories must be absolute paths.
Relative paths will NOT work. Also, the destination directory
must NOT be a subdirectory of the source directory.
-f, --file <package file>
Specifies the file listing the components to be created in
the destination directory and the files to copy from the
source directory to each component directory in the
destination directory.
Required.
-o, --os [dos|mac|unix|os2]
Specifies which type of system this is. Used for parsing
file specifications from the package file.
Required.
-c, --component <component name>
Specifies a specific component in the package file to copy
rather than copying all the components in the package file.
Can be used more than once for multiple components (e.g.
"-c browser -c mail" to copy mail and news only).
Optional.
-l, --flat
Suppresses creation of components dirs, but stuffes everything
directly into the package destination dir. This is useful
for creating tarballs.
-h, --help
Prints this information.
Optional.
--debug [1-10]
Controls verbosity of debugging output, 10 being most verbose.
1 : same as --verbose.
2 : includes function calls.
3 : includes source and destination for each copy.
Optional.
-v, --verbose
Print component names and files copied/deleted.
Optional.
e.g.
$0 --os unix --source /builds/mozilla/dist --destination /h/lithium/install --file packages-win --os unix --verbose
Note: options can be specified by either a leading '--' or '-'.
EOC
}

Просмотреть файл

@ -34,20 +34,11 @@
# - change var names to standard form
# load modules
use Cwd;
use File::Basename;
use File::Copy;
use File::Find;
use File::Path;
use File::stat;
use Getopt::Long;
use File::Basename;
# initialize variables
$saved_cwd = cwd();
$component = ""; # current component being copied
%components = (); # list of components to copy
$PD = ""; # file Path Delimiter ( /, \, or :)
$altdest = ""; # alternate file destination
$line = ""; # line being processed
$srcdir = ""; # root directory being copied from
$destdir = ""; # root directory being copied to
@ -56,7 +47,6 @@ $os = ""; # os type (MacOS, MSDOS, Unix, OS/2)
$verbose = 0; # shorthand for --debug 1
$lineno = 0; # line # of package file for error text
$debug = 0; # controls amount of debug output
$dirflag = 0; # flag: are we copying a directory?
$help = 0; # flag: if set, print usage
@ -86,504 +76,18 @@ if ($verbose && !($debug)) {
if (! $return)
{
die "Error: couldn't parse command line options. See \'$0 --help' for options.\nExiting...\n";
} else {
check_arguments();
}
#
# main loop
#
open (MANIFEST,"<$package") ||
die "Error: couldn't open file $package for reading: $!. Exiting...\n";
LINE: while (<MANIFEST>) {
$line = "";
$altdest = "";
$lineno++;
s/\;.*//; # it's a comment, kill it.
s/^\s+//; # nuke leading whitespace
s/\s+$//; # nuke trailing whitespace
($debug >= 2) && print "\n";
($debug >= 8) && print "line $lineno:$_\n";
# it's a blank line, skip it.
/^$/ && do {
($debug >= 10) && print "blank line.\n";
next LINE;
};
# it's a new component
/^\[/ && do {
($debug >= 10) && print "component.\n";
$component = $_;
do_component ();
next LINE;
};
# make sure a component is defined before doing any copies or deletes.
if (( $component eq "" ) && ($components eq "" )) {
die "Error: item $_ outside a component ($package, $lineno). Exiting...\n";
}
# skip line if we're only copying specific components and outside
# those components
if (( $component eq "" ) && ($components ne "" )) {
($debug >= 10) && print "Not in specifed component. Skipping $_\n";
next LINE;
}
if ($line eq "") {
$line = $_; # if $line not set, set it.
}
if ($os ne "MSDOS") { # hack - need to fix for dos
$line =~ s/^$PD//; # strip any leading path delimiter
}
# delete the file or directory following the '-'
/^-/ && do {
$line =~ s/^-//; # strip leading '-'
($debug >= 10) && print "delete: $destdir$PD$component$PD$line\n";
do_delete ("$destdir", "$component", "$line");
next LINE;
};
# file/directory being copied to different target location
/\,/ && do {
/.*\,.*\,.*/ &&
die "Error: multiple commas not allowed ($package, $lineno): $_.\n";
($line, $altdest) = split (/\s*\,\s*/, $line, 2);
$line =~ s/$PD*$//; # strip any trailing path delimiters
$altdest =~ s/$PD*$//; # strip any trailing delimiter
($debug >= 10) && print "relocate: $line => $altdest.\n";
};
# if it has wildcards, do recursive copy.
/(?:\*|\?)/ && do {
($debug >= 10) && print "wildcard copy.\n";
if ($os eq "MacOS") {
if (/:\*$/) {
($debug >= 4) && print "Mac and wildcard is \":*\" so strip and copy entire directory.\n";
$line =~ s/:\*$//; # Mac doesn't like wildcards, so strip off any ":*" at the end of the line
# and copy the whole directory.
do_copydir ("$srcdir$PD$line");
}
} else {
do_wildcard ("$srcdir$PD$line");
}
next LINE;
};
# if it's a single file, copy it.
( -f "$srcdir$PD$line" ) && do {
($debug >= 10) && print "file copy.\n";
do_copyfile ();
next LINE;
};
# if it's a directory, do recursive copy.
(-d "$srcdir$PD$line") && do {
($debug >= 10) && print "directory copy.\n";
do_copydir ("$srcdir$PD$line");
next LINE;
};
# if we hit this, it's either a file in the package file that is
# not in the src directory, or it is not a valid entry.
warn "Warning: package error or possible missing or unnecessary file: $line ($package, $lineno).\n";
} # LINE
close (MANIFEST);
chdir ($saved_cwd);
exit (0);
#
# Delete the given file or directory
#
sub do_delete
{
my ($targetpath) = $_[0];
my ($targetcomp) = $_[1];
my ($targetfile) = $_[2];
my ($target) = ($flat) ? "$targetpath$PD$targetfile" : "$targetpath$PD$targetcomp$PD$targetfile";
($debug >= 2) && print "do_delete():\n";
($debug >= 1) && print "-$targetfile\n";
if ( -f $target ) {
(! -w $target ) &&
die "Error: delete failed: $target not writeable ($package, $component, $lineno). Exiting...\n";
($debug >= 4) && print " unlink($target)\n";
unlink ($target) ||
die "Error: unlink() failed: $!. Exiting...\n";
} elsif ( -d $target ) {
(! -w $target ) &&
die "Error: delete failed: $target not writeable ($package, $component, $lineno). Exiting...\n";
($debug >= 4) && print " rmtree($target)\n";
rmtree ($target, 0, 0) ||
die "Error: rmtree() failed: $!. Exiting...\n";
} else {
warn "Warning: delete failed: $target is not a file or directory ($package, $component, $lineno).\n";
}
}
#
# Copy an individual file from the srcdir to the destdir.
#
# This is called by both the individual and batch/recursive copy routines,
# using $dirflag to check if called from do_copydir. Batch copy can pass in
# directories, so be sure to check first and break if it isn't a file.
#
sub do_copyfile
{
my ($destpath) = ""; # destination directory path
my ($destpathcomp) = ""; # ditto, but possibly including component dir
my ($destname) = ""; # destination file name
my ($destsuffix) = ""; # destination file name suffix
my ($altpath) = ""; # alternate destination directory path
my ($altname) = ""; # alternate destination file name
my ($altsuffix) = ""; # alternate destination file name suffix
my ($srcpath) = ""; # source file directory path
my ($srcname) = ""; # source file name
my ($srcsuffix) = ""; # source file name suffix
my ($curdir) = getcwd; # need current dir on OS/2 to switch back
($debug >= 2) && print "do_copyfile():\n";
# set srcname correctly depending on how called
if ( $dirflag ) {
($srcname, $srcpath, $srcsuffix) = fileparse("$File::Find::name", '\..*?$');
} else {
($srcname, $srcpath, $srcsuffix) = fileparse("$srcdir$PD$line", '\..*?$');
}
($debug >= 4) && print " fileparse(src): $srcpath $srcname $srcsuffix\n";
# return if srcname is a directory from do_copydir
if ( -d "$srcpath$srcname$srcsuffix" ) {
($debug >= 10) && print " return: $srcpath$srcname$srcsuffix is a directory\n";
return;
}
# set the destination path, if alternate destination given, use it.
if ($flat) {
$destpathcomp = "$destdir";
} else {
$destpathcomp = "$destdir$PD$component";
}
if ( $altdest ne "" ) {
if ( $dirflag ) { # directory copy to altdest
($destname, $destpath, $destsuffix) = fileparse("$destpathcomp$PD$altdest$PD$File::Find::name", '\..*?$');
# Todo: add MSDOS hack
$destpath =~ s/$srcdir$PD$line$PD//; # rm info added by find
($debug >= 5) &&
print " dir copy to altdest: $destpath $destname $destsuffix\n";
} else { # single file copy to altdest
($destname, $destpath, $destsuffix) = fileparse("$destpathcomp$PD$altdest", '\..*?$');
($debug >= 5) &&
print " file copy to altdest: $destpath $destname $destsuffix\n";
}
} else {
if ( $dirflag ) { # directory copy, no altdest
($destname, $destpath, $destsuffix) = fileparse("$destpathcomp$PD$File::Find::name", '\..*?$');
# avert your eyes now, butt-ugly hack
if ( $os eq "MSDOS" ) {
$destpath =~ s/\\/\//g;
$srcdir =~ s/\\/\//g;
$PD = "/";
$destpath =~ s/$srcdir$PD//g;
$destpath =~ s/\//\\/g;
$srcdir =~ s/\//\\/g;
$PD = "\\";
} elsif ( $os eq "OS2") {
#Don't Look! Seriously...
$destpath =~ s/\\/\//g;
$srcdir =~ s/\\/\//g;
$PD = "/";
$destpath =~ s/$srcdir$PD//g;
$destpath = "$srcdir$PD$destpath";
$PD = "\\";
} else {
$destpath =~ s/$srcdir$PD//;
}
# end stupid MSDOS hack
($debug >= 5) &&
print " dir copy w/o altdest: $destpath $destname $destsuffix\n";
} else { # single file copy, no altdest
($destname, $destpath, $destsuffix) = fileparse("$destpathcomp$PD$line", '\..*?$');
($debug >= 5) &&
print " file copy w/o altdest: $destpath $destname $destsuffix\n";
}
}
#Ensure correct directory
if ($os eq "OS2") {
chdir($saved_cwd);
}
# create the destination path if it doesn't exist
if (! -d "$destpath" ) {
($debug >= 5) && print " mkpath($destpath)\n";
#OS2 hack. Sorry... Chop off "/"
if ($os eq "OS2" ) {
chop($destpath);
}
mkpath ($destpath, 0, 0755) ||
die "Error: mkpath() failed: $!. Exiting...\n";
# Put "/" back for copying...
if ($os eq "OS2") {
$destpath = "$destpath/";
}
}
# path exists, source and destination known, time to copy
if ((-f "$srcpath$srcname$srcsuffix") && (-r "$srcpath$srcname$srcsuffix")) {
if ( $debug >= 1 ) {
if ( $dirflag ) {
print "$destname$destsuffix\n"; # from unglob
} else {
print "$line\n"; # from single file
}
if ( $debug >= 3 ) {
print " copy\t$srcpath$srcname$srcsuffix =>\n\t\t$destpath$destname$destsuffix\n";
}
}
unlink("$destpath$destname$destsuffix") if ( -e "$destpath$destname$destsuffix");
copy ("$srcpath$srcname$srcsuffix", "$destpath$destname$destsuffix") ||
die "Error: copy of file $srcpath$srcname$srcsuffix failed ($package, $component, $lineno): $!. Exiting...\n";
# if this is unix, set the dest file permissions
if ( $os eq "Unix" ) {
# read permissions
$st = stat("$srcpath$srcname$srcsuffix") ||
die "Error: can't stat $srcpath$srcname$srcsuffix: $! Exiting...\n";
# set permissions
($debug >= 2) && print " chmod ".$st->mode." $destpath$destname$destsuffix\n";
chmod ($st->mode, "$destpath$destname$destsuffix") ||
warn "Warning: chmod of $destpath$destname$destsuffix failed: $!. Exiting...\n";
}
} else {
warn "Error: file $srcpath$srcname$srcsuffix is not a file or is not readable ($package, $component, $lineno).\n";
}
#Resetting dir...
if ($os eq "OS2") {
chdir($curdir);
}
}
#
# Expand any wildcards and copy files and/or directories
#
# todo: pass individual files to do_copyfile, not do_copydir
#
sub do_wildcard
{
my ($entry) = $_[0];
my (@list) = ();
my ($item) = "";
($debug >= 2) && print "do_wildcard():\n";
if ( $entry =~ /(?:\*|\?)/ ) { # it's a wildcard,
if ($os eq "MacOS") {
warn "Warning: globbing on Mac not supported.\nWorkaround is to copy entire directory.\n";
@list = <$entry>;
} elsif ( $os eq "OS2") {
#warn "Warning: globbing on OS/2 not supported.\nWorkaround is to copy entire directory.\n";
@list = $entry;
chop($list[0]);
} else {
@list = glob($entry); # expand it
}
($debug >= 4) && print " glob: $entry => @list\n";
foreach $item ( @list ) { # now copy each item in list
if ( -f $item ) {
($debug >= 10) && print " do_copyfile: $item\n";
# glob adds full path to item like find() in copydir so
# take advantage of existing code in copyfile by using
# $dirflag and $File::Find::name.
$File::Find::name = $item;
$dirflag = 1;
do_copyfile();
$dirflag = 0;
$File::Find::name = "";
} elsif ( -d $item ) {
($debug >= 10) && print " do_copydir($item)\n";
do_copydir ($item);
} else {
warn "Warning: $item is not a file or directory ($package, $component, $lineno). Skipped...\n";
}
}
}
}
#
# Recursively copy directories specified.
#
sub do_copydir
{
my ($entry) = $_[0];
$dirflag = 1; # flag indicating directory copy in progress
($debug >= 2) && print "do_copydir():\n";
if (! -d "$entry" ) {
warn "Warning: $entry is not a directory ($package, $component, $lineno). Skipped...\n";
}
($debug >= 4) && print " find($entry)\n";
find (\&do_copyfile, $entry);
$dirflag = 0;
}
#
# Handle new component
#
sub do_component
{
($debug >= 2) && print "do_component():\n";
( $component =~ /^\[.*(?:\s|\[|\])+.*\]/ ) && # no brackets or ws
die "Error: malformed component $component. Exiting...\n";
$component =~ s/^\[(.*)\]/$1/; # strip []
if ( $components ne "") {
if ( $components =~ /$component/ ) {
($debug >= 10) && print "Component $component is in $components.\n";
} else {
($debug >= 10) && print "Component $component not in $components.\n";
$component = "";
return; # named specific components and this isn't it
}
}
if ($debug >= 1) {
print "[$component]\n";
}
# create component directory
if (!$flat) {
if ( -d "$destdir$PD$component" ) {
warn "Warning: component directory \"$component\" already exists in \"$destdir\".\n";
} else {
($debug >= 4) && print " mkdir $destdir$PD$component\n";
mkdir ("$destdir$PD$component", 0755) ||
die "Error: couldn't create component directory \"$component\": $!. Exiting...\n";
}
}
}
#
# Check that arguments to script are valid.
#
sub check_arguments
{
my ($exitval) = 0;
($debug >= 2) && print "check_arguments():\n";
# if --help print usage
if ($help) {
print_usage();
exit (1);
}
# make sure required variables are set:
# check source directory
if ( $srcdir eq "" ) {
print "Error: source directory (--source) not specified.\n";
$exitval += 8;
} elsif ((! -d $srcdir) || (! -r $srcdir)) {
print "Error: source directory \"$srcdir\" is not a directory or is unreadable.\n";
$exitval = 1;
}
# check destination directory
if ( $destdir eq "" ) {
print "Error: destination directory (--destination) not specified.\n";
$exitval += 8;
} elsif ((! -d $destdir) || (! -w $destdir)) {
print "Error: destination directory \"$destdir\" is not a directory or is not writeable.\n";
$exitval += 2;
}
# check destdir not a subdir of srcdir
# hack - workaround for bug 14558 that should be fixed eventually.
if (0) { # todo - write test
print "Error: destination directory must not be subdirectory of the source directory.\n";
$exitval += 32;
}
# check package file
if ( $package eq "" ) {
print "Error: package file (--file) not specified.\n";
$exitval += 8;
} elsif (!(-f $package) || !(-r $package)) {
print "Error: package file \"$package\" is not a file or is unreadable.\n";
$exitval += 4;
}
# check OS == {mac|unix|dos|os2}
if ($os eq "") {
print "Error: OS type (--os) not specified.\n";
$exitval += 8;
} elsif ( $os =~ /mac/i ) {
$os = "MacOS";
$PD = ":";
fileparse_set_fstype ($os);
} elsif ( $os =~ /dos/i ) {
$os = "MSDOS";
$PD = "\\";
fileparse_set_fstype ($os);
} elsif ( $os =~ /unix/i ) {
$os = "Unix"; # can be anything but MacOS, MSDOS, or VMS
$PD = "/";
fileparse_set_fstype ($os);
} elsif ( $os =~ /os2/i) {
$os = "OS2";
$PD = "/";
fileparse_set_fstype($os);
} else {
print "Error: OS type \"$os\" unknown.\n";
$exitval += 16;
}
# turn components array into a string for regexp
if ( @components > 0 ) {
$components = join (",",@components);
} else {
$components = "";
}
if ($debug > 4) {
print ("source dir:\t$srcdir\ndest dir:\t$destdir\npackage:\t$package\nOS:\t$os\ncomponents:\t$components\n");
}
if ($exitval) {
print "See \'$0 --help\' for more information.\n";
print "Exiting...\n";
exit ($exitval);
}
# ensure that Packager.pm is in @INC, since we might not be called from
# mozilla/xpinstall/packager.
$top_path = $0;
if ( $os eq "dos" ) {
$top_path =~ s/\\/\//g;
}
push(@INC, dirname($top_path));
require Packager;
Packager::Copy($srcdir, $destdir, $package, $os, $flat, $help, $debug, @components);
#
# This is called by GetOptions when there are extra command line arguments
@ -595,82 +99,4 @@ sub do_badargument
}
#
# display usage information
#
sub print_usage
{
($debug >= 2) && print "print_usage():\n";
print <<EOC
$0
Copy files from the source directory to component directories
in the destination directory as specified by the package file.
Options:
-s, --source <source directory>
Specifies the directory from which to copy the files
specified in the file passed via --file.
Required.
-d, --destination <destination directory>
Specifies the directory in which to create the component
directories and copy the files specified in the file passed
via --file.
Required.
NOTE: Source and destination directories must be absolute paths.
Relative paths will NOT work. Also, the destination directory
must NOT be a subdirectory of the source directory.
-f, --file <package file>
Specifies the file listing the components to be created in
the destination directory and the files to copy from the
source directory to each component directory in the
destination directory.
Required.
-o, --os [dos|mac|unix|os2]
Specifies which type of system this is. Used for parsing
file specifications from the package file.
Required.
-c, --component <component name>
Specifies a specific component in the package file to copy
rather than copying all the components in the package file.
Can be used more than once for multiple components (e.g.
"-c browser -c mail" to copy mail and news only).
Optional.
-l, --flat
Suppresses creation of components dirs, but stuffes everything
directly into the package destination dir. This is useful
for creating tarballs.
-h, --help
Prints this information.
Optional.
--debug [1-10]
Controls verbosity of debugging output, 10 being most verbose.
1 : same as --verbose.
2 : includes function calls.
3 : includes source and destination for each copy.
Optional.
-v, --verbose
Print component names and files copied/deleted.
Optional.
e.g.
$0 --os unix --source /builds/mozilla/dist --destination /h/lithium/install --file packages-win --os unix --verbose
Note: options can be specified by either a leading '--' or '-'.
EOC
}
# EOF