From 5a3831586101dade699ec29670ed2bf374c658ed Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Wed, 6 May 2009 21:22:09 +0000 Subject: support relocatable packages if tl-update-containers is called with -relative hopefully fix all scripts and tlmgr to work correctly git-svn-id: svn://tug.org/texlive/branches/branch2009-dev@12958 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf/scripts/texlive/tlmgr.pl | 13 ++++- Master/tlpkg/TeXLive/TLConfig.pm | 14 +++++ Master/tlpkg/TeXLive/TLMedia.pm | 22 ++++++-- Master/tlpkg/TeXLive/TLPOBJ.pm | 84 ++++++++++++++++++++++-------- Master/tlpkg/TeXLive/TLUtils.pm | 17 ++++-- Master/tlpkg/bin/check-duplicated-runfiles | 6 ++- Master/tlpkg/bin/tl-update-containers | 32 ++++++++++-- Master/tlpkg/bin/tlpfiles | 3 +- Master/tlpkg/bin/tlpkg-ctan-check | 3 +- Master/tlpkg/bin/tlprm | 3 +- 10 files changed, 157 insertions(+), 40 deletions(-) diff --git a/Master/texmf/scripts/texlive/tlmgr.pl b/Master/texmf/scripts/texlive/tlmgr.pl index 5d6755aea4a..762b67bc13c 100755 --- a/Master/texmf/scripts/texlive/tlmgr.pl +++ b/Master/texmf/scripts/texlive/tlmgr.pl @@ -834,8 +834,13 @@ sub action_search { $tlpdb = $localtlpdb; } foreach my $pkg ($tlpdb->list_packages) { + my $tlp = $tlpdb->get_package($pkg); if ($opts{"file"}) { - my @ret = grep(m;$r;, $tlpdb->get_package($pkg)->all_files); + my @files = $tlp->all_files; + if ($tlp->relocated) { + for (@files) { s:^$RelocPrefix/:$RelocTree/:; } + } + my @ret = grep(m;$r;, @files); if (@ret) { print "$pkg:\n"; foreach (@ret) { @@ -2343,7 +2348,11 @@ sub check_files { # ignore files in the installer next if ($p eq "00texlive.installer"); my $tlp = $localtlpdb->get_package($p); - for my $f ($tlp->all_files) { + my @files = $tlp->all_files; + if ($tlp->relocated) { + for (@files) { s:^$RelocPrefix/:$RelocTree/:; } + } + for my $f (@files) { push @{$filetopacks{$f}}, $p; } } diff --git a/Master/tlpkg/TeXLive/TLConfig.pm b/Master/tlpkg/TeXLive/TLConfig.pm index fdc15944d18..a148fc0ae31 100644 --- a/Master/tlpkg/TeXLive/TLConfig.pm +++ b/Master/tlpkg/TeXLive/TLConfig.pm @@ -30,6 +30,8 @@ BEGIN { @CriticalPackagesList @AllowedConfigOptions $WindowsMainMenuName + $RelocPrefix + $RelocTree ); @EXPORT = @EXPORT_OK; } @@ -65,11 +67,14 @@ our $Archive = "archive"; our $TeXLiveServerURL = "http://mirror.ctan.org"; our $TeXLiveServerPath = "systems/texlive/tlnet/$ReleaseYear"; our $TeXLiveURL = "$TeXLiveServerURL/$TeXLiveServerPath"; +our $RelocTree = "texmf-dist"; +our $RelocPrefix = "RELOC"; our $WinSpecialUpdatePackagesRegexp = '^(texlive\.infra|bin-tlperl\.win32$|bin-texlive)'; + our @CriticalPackagesList = qw/texlive.infra bin-texlive/; push(@CriticalPackagesList, "bin-tlperl.win32") if ($^O=~/^MSWin(32|64)$/i); @@ -175,6 +180,15 @@ since they are too central, currently bin-texlive and texlive.infra. A list of a config options that can be set in 00texlive.installation. +=item C<$TeXLive::TLConfig::RelocTree> + +the texmf-tree name that can be relocated, defaults to "texmf-dist" + +=item C<$TeXLive::TLConfig::RelocPrefix> + +The string that replaces the RelocTree in the tlpdb if a package is +reloaced, defaults to "RELOC". + =back =head1 SEE ALSO diff --git a/Master/tlpkg/TeXLive/TLMedia.pm b/Master/tlpkg/TeXLive/TLMedia.pm index 260b7646cfe..1aff9af6f11 100644 --- a/Master/tlpkg/TeXLive/TLMedia.pm +++ b/Master/tlpkg/TeXLive/TLMedia.pm @@ -116,6 +116,7 @@ sub install_package { # even if opt_doc is false $real_opt_doc = 1; } + my $reloc = 1 if $tlpobj->relocated; my $container; my @installfiles; my $location = $self->location; @@ -154,7 +155,7 @@ sub install_package { } elsif (&media eq 'NET') { $container = "$location/$Archive/$pkg.$DefaultContainerExtension"; } - $self->_install_package($container,\@installfiles,$totlpdb) || return(0); + $self->_install_package($container,$reloc,\@installfiles,$totlpdb) || return(0); # if we are installing from CD or NET we have to fetch the respective # source and doc packages $pkg.source and $pkg.doc and install them, too if (($media eq 'NET') || ($media eq 'CD')) { @@ -172,12 +173,12 @@ sub install_package { if ($container_src_split && $opt_src && $tlpobj->srcfiles) { my $srccontainer = $container; $srccontainer =~ s/(\.tar\.xz|\.zip)$/.source$1/; - $self->_install_package($srccontainer,\@installfiles,$totlpdb) || return(0); + $self->_install_package($srccontainer,$reloc,\@installfiles,$totlpdb) || return(0); } if ($container_doc_split && $real_opt_doc && $tlpobj->docfiles) { my $doccontainer = $container; $doccontainer =~ s/(\.tar\.xz|\.zip)$/.doc$1/; - $self->_install_package($doccontainer,\@installfiles,$totlpdb) || return(0); + $self->_install_package($doccontainer,$reloc,\@installfiles,$totlpdb) || return(0); } } # we don't want to have wrong information in the tlpdb, so remove the @@ -220,7 +221,7 @@ sub install_package { # returns 1 on success and 0 on error # sub _install_package { - my ($self, $what, $filelistref, $totlpdb) = @_; + my ($self, $what, $reloc, $filelistref, $totlpdb) = @_; my $media = $self->media; my $target = $totlpdb->root; @@ -250,6 +251,8 @@ sub _install_package { } elsif ($what =~ m,\.tar(\.xz)?$,) { my $type = defined($1) ? "xz" : "tar"; + $target .= "/$TeXLive::TLConfig::RelocPrefix" if $reloc; + # this is the case when we install from CD or the NET, or a backup # # in all other cases we create temp files .tar.xz (or use the present @@ -347,6 +350,16 @@ sub remove_package { push @files, "tlpkg/tlpobj/$pkg.doc.tlpobj"; } # + # some packages might be relocated, thus having the RELOC prefix + # in user mode we just remove the prefix, in normal mode we + # replace it with texmf-dist + # since we don't have user mode + if ($tlp->relocated) { + for (@files) { + s:^$RelocPrefix/:$RelocTree/:; + } + } + # # we want to check that a file is only listed in one package, so # in case that a file to be removed is listed in another package # we will warn and *not* remove it @@ -360,6 +373,7 @@ sub remove_package { my @goodfiles = (); my @badfiles = (); for my $f (@files) { + # in usermode we have to add texmf-dist again for comparison if (defined($allfiles{$f})) { # this file should be removed but is mentioned somewhere, too push @badfiles, $f; diff --git a/Master/tlpkg/TeXLive/TLPOBJ.pm b/Master/tlpkg/TeXLive/TLPOBJ.pm index 92feea61427..86b097df993 100644 --- a/Master/tlpkg/TeXLive/TLPOBJ.pm +++ b/Master/tlpkg/TeXLive/TLPOBJ.pm @@ -6,7 +6,9 @@ package TeXLive::TLPOBJ; -use TeXLive::TLConfig qw($DefaultCategory $CategoriesRegexp $MetaCategoriesRegexp $InfraLocation); +use TeXLive::TLConfig qw($DefaultCategory $CategoriesRegexp + $MetaCategoriesRegexp $InfraLocation + $RelocPrefix $RelocTree); use TeXLive::TLUtils; use TeXLive::TLTREE; @@ -22,6 +24,7 @@ sub new { shortdesc => $params{'shortdesc'}, longdesc => $params{'longdesc'}, catalogue => $params{'catalogue'}, + relocated => $params{'relocated'}, runfiles => defined($params{'runfiles'}) ? $params{'runfiles'} : [], runsize => $params{'runsize'}, srcfiles => defined($params{'srcfiles'}) ? $params{'srcfiles'} : [], @@ -165,6 +168,10 @@ sub from_fh { $self->{'category'} = "$1"; $lastcmd = "category"; next; + } elsif ($line =~ /^relocated\s+([01])\s*/o) { + $self->relocated("$1"); + $lastcmd = "relocated"; + next; } elsif ($line =~ /^revision\s+(.*)\s*/o) { $self->{'revision'} = "$1"; $lastcmd = "revision"; @@ -305,6 +312,7 @@ sub writeout { defined($self->{'catalogue'}) && print $fd "catalogue $self->{'catalogue'}\n"; defined($self->{'shortdesc'}) && print $fd "shortdesc $self->{'shortdesc'}\n"; defined($self->{'license'}) && print $fd "license $self->{'license'}\n"; + defined($self->{'relocated'}) && $self->{'relocated'} && print $fd "relocated 1\n"; # ugly hack to get rid of use FileHandle; see man perlform #format_name $fd "multilineformat"; select((select($fd),$~ = "multilineformat")[0]); @@ -432,6 +440,37 @@ sub writeout_simple { } } +sub cancel_common_texmf_tree { + my $self = shift; + my @docfiles = $self->docfiles; + for (@docfiles) { s:^$RelocTree/:$RelocPrefix/:; } + $self->docfiles(@docfiles); + my @runfiles = $self->runfiles; + for (@runfiles) { s:^$RelocTree/:$RelocPrefix/:; } + $self->runfiles(@runfiles); + my @srcfiles = $self->srcfiles; + for (@srcfiles) { s:^$RelocTree/:$RelocPrefix/:; } + $self->srcfiles(@srcfiles); + # if there are bin files they have definitely NOT the + # texmf-dist prefix, so we cannot cancel it anyway +} + +sub common_texmf_tree { + my $self = shift; + my $tltree; + my @files = $self->all_files; + foreach ($self->all_files) { + my $tmp; + ($tmp) = split m@/@; + if (defined($tltree) && ($tltree ne $tmp)) { + return; + } else { + $tltree = $tmp; + } + } + return $tltree; +} + sub make_container { my ($self,$type,$instroot,$destdir,$containername,$relative) = @_; @@ -441,30 +480,18 @@ sub make_container { if (!defined($containername)) { $containername = $self->name; } - my @files = (); + my @files = $self->all_files; my $compresscmd; my $tlpobjdir = "$InfraLocation/tlpobj"; - my %binf = %{$self->{'binfiles'}}; - foreach (keys %binf) { - push @files, @{$binf{$_}}; - } - push @files, $self->runfiles; - push @files, $self->docfiles; - push @files, $self->srcfiles; @files = TeXLive::TLUtils::sort_uniq(@files); # we do relative packages ONLY if the files do NOT span multiple # texmf trees. check this here my $tltree; if ($relative) { - foreach (@files) { - my $tmp; - ($tmp) = split m@/@; - if (defined($tltree) && ($tltree ne $tmp)) { - die ("$0: package $containername spans multiple trees, " - . "relative generation not allowed"); - } else { - $tltree = $tmp; - } + $tltree = $self->common_texmf_tree; + if (!defined($tltree)) { + die ("$0: package $containername spans multiple trees, " + . "relative generation not allowed"); } my @nf; map { s@^$tltree/@@ ; push @nf, $_; } @files; @@ -483,7 +510,9 @@ sub make_container { # and put the tlpobj into the root! if ($relative) { chdir("./$tltree"); - $tlpobjdir = "."; + # we don't need to change the $tlpobjdir because we put it in + # all cases into tlpkg/tlpobj + #$tlpobjdir = "./tlpkg/tlpobj"; } # we add the .tlpobj into the .tlpobj directory my $removetlpobjdir = 0; @@ -895,6 +924,11 @@ sub revision { if (@_) { $self->{'revision'} = shift } return $self->{'revision'}; } +sub relocated { + my $self = shift; + if (@_) { $self->{'relocated'} = shift } + return ($self->{'relocated'} ? 1 : 0); +} sub catalogue { my $self = shift; if (@_) { $self->{'catalogue'} = shift } @@ -1089,9 +1123,11 @@ Please see L documentation for the specification. The only differences are that the various C<*pattern> keys are invalid, and instead there are the respective C<*files> keys described below. Furthermore some more I is allowed: C which specifies the maximum of -all last changed revision of files contained in the package, and anything +all last changed revision of files contained in the package, anything starting with C specifying information coming from the -TeX Catalogue. +TeX Catalogue, and C taking either 0 or 1 indicating that +this packages has been relocated, i.e., in the containers the +initial C directory has been stripped off. All these keys have in common that they are followed by a list of files I by one space. They differ only in the first line itself @@ -1264,6 +1300,12 @@ or the filehandle if given: debugging function for comparison with C/C, will go away. +=item C + +if all files of the package are from the same texmf tree, this tree +is returned, otherwise an undefined value. That is also a check +whether a package is relocatable. + =item C creates a container file of the all files in the C diff --git a/Master/tlpkg/TeXLive/TLUtils.pm b/Master/tlpkg/TeXLive/TLUtils.pm index 6ccda6d597a..dce52e140dd 100644 --- a/Master/tlpkg/TeXLive/TLUtils.pm +++ b/Master/tlpkg/TeXLive/TLUtils.pm @@ -950,6 +950,7 @@ sub install_packages { my $starttime = time(); foreach my $package (@packs) { my $tlpobj = $tlpobjs{$package}; + my $reloc = $tlpobj->relocated; $n++; my $remtime = "??:??"; my $tottime = "??:??"; @@ -1016,7 +1017,7 @@ sub install_packages { } elsif ($media eq 'NET') { $container = "$root/$Archive/$package.$DefaultContainerExtension"; } - if (!install_package($container, $tlpobj->containersize, + if (!install_package($container, $reloc, $tlpobj->containersize, $tlpobj->containermd5, \@installfiles, $totlpdb->root, $vars{'this_platform'})) { # we already warn in install_package that something bad happened, @@ -1038,7 +1039,7 @@ sub install_packages { if ($container_src_split && $opt_src && $tlpobj->srcfiles) { my $srccontainer = $container; $srccontainer =~ s/(\.tar\.xz|\.zip)$/.source$1/; - if (!install_package($srccontainer, $tlpobj->srccontainersize, + if (!install_package($srccontainer, $reloc, $tlpobj->srccontainersize, $tlpobj->srccontainermd5, \@installfiles, $totlpdb->root, $vars{'this_platform'})) { return 0; @@ -1047,7 +1048,7 @@ sub install_packages { if ($container_doc_split && $real_opt_doc && $tlpobj->docfiles) { my $doccontainer = $container; $doccontainer =~ s/(\.tar\.xz|\.zip)$/.doc$1/; - if (!install_package($doccontainer, + if (!install_package($doccontainer, $reloc, $tlpobj->doccontainersize, $tlpobj->doccontainermd5, \@installfiles, $totlpdb->root, $vars{'this_platform'})) { @@ -1084,7 +1085,7 @@ sub install_packages { } -=item C +=item C This function installs the files given in @$filelistref from C<$what> into C<$target>. @@ -1107,12 +1108,15 @@ file on the system and is likewise piped through C and C. In both of these cases currently the list C<$@filelistref> currently is not taken into account (should be fixed!). +if C<$reloc> is true the container (NET or CD mode) is packaged in a way +that the initial texmf-dist is missing. + Returns 1 on success and 0 on error. =cut sub install_package { - my ($what, $whatsize, $whatmd5, $filelistref, $target, $platform) = @_; + my ($what, $reloc, $whatsize, $whatmd5, $filelistref, $target, $platform) = @_; my @filelist = @$filelistref; @@ -1139,6 +1143,9 @@ sub install_package { # in all other cases we create temp files .tar.xz (or use the present # one), xzdec them, and then call tar + # if we are unpacking a relocated container we adjust the target + $target .= "/$TeXLive::TLConfig::RelocPrefix" if $reloc; + my $fn = basename($what); mkdirhier("$target/temp"); my $xzfile = "$target/temp/$fn"; diff --git a/Master/tlpkg/bin/check-duplicated-runfiles b/Master/tlpkg/bin/check-duplicated-runfiles index d212c68e589..05a51860283 100755 --- a/Master/tlpkg/bin/check-duplicated-runfiles +++ b/Master/tlpkg/bin/check-duplicated-runfiles @@ -11,7 +11,7 @@ BEGIN { unshift (@INC, "$mydir/.."); } -use TeXLive::TLConfig; +use TeXLive::TLConfig qw/$RelocPrefix $RelocTree/; use TeXLive::TLPOBJ; use TeXLive::TLPDB; @@ -31,7 +31,9 @@ my @runtime_files = (); foreach my $tlpn ($tlpdb->list_packages) { next if ($tlpn =~ /$non_normal/); my $tlp = $tlpdb->get_package($tlpn); - push @runtime_files, $tlp->runfiles; + my @files = $tlp->runfiles; + if ($tlp->relocated) { for (@files) { s:^$RelocPrefix/:$RelocTree/:; } } + push @runtime_files, @files; } # build the duplicates list diff --git a/Master/tlpkg/bin/tl-update-containers b/Master/tlpkg/bin/tl-update-containers index 2f1cb1b9d4b..e5c7376bd14 100755 --- a/Master/tlpkg/bin/tl-update-containers +++ b/Master/tlpkg/bin/tl-update-containers @@ -43,6 +43,7 @@ GetOptions( "location=s" => \$opt_location, "no-setup" => \$opt_nosetup, "recreate" => \$opt_recreate, + "relative" => \$opt_relative, "version" => \$opt_version, "help|?" => \$opt_help) or pod2usage(1); @@ -235,14 +236,35 @@ sub main debug("updating $pkg containers ...\n"); # we have to make a copy otherwise the src/doc files in the original # tlpobj are removed, and thus also in the tlpdb to be saved!!! + my $objcopy = $obj->copy; + + # if we try to create relative containers we check the package + # for residing only in texmf-dist, and being relocatable, and + # not having a dependency on $pkg.ARCH + # TLPOBJ->common_texmf_tree returns the string of the + # common temxf tree or undefined, so we can use it in && + my $ctt = $objcopy->common_texmf_tree; + my $deps_on_arch = 0; + for ($objcopy->depends) { + if (m/^$pkg\.ARCH$/) { + $deps_on_arch = 1; + last; + } + } + my $do_relative = 0; + $do_relative = $opt_relative && # user option + ($deps_on_arch?0:1) && # no $pkg.ARCH dep + (defined($ctt)?1:0) && # see above + (($ctt eq $TeXLive::TLConfig::RelocTree) ? 1 : 0); + # only for texmf-dist if ($srcsplit) { if (!$opt_dry) { my $objsrc = $obj->srcfiles_package; $objcopy->clear_srcfiles; if ($objsrc) { my ($s,$m) = $objsrc->make_container($type, $Master, $opt_containerdir, - "$pkg.source", $opt_relative); + "$pkg.source", $do_relative); if ($s > 0) { # something was created # important, we have to add it to the original $obj @@ -266,7 +288,7 @@ sub main $objcopy->clear_docfiles; if ($objdoc) { my ($s,$m) = $objdoc->make_container($type, $Master, - $opt_containerdir, "$pkg.doc", $opt_relative); + $opt_containerdir, "$pkg.doc", $do_relative); if ($s > 0) { # something was created $obj->doccontainersize($s); @@ -285,7 +307,7 @@ sub main } if (!$opt_dry) { my ($s,$m) = $objcopy->make_container($type, $Master, $opt_containerdir, - $pkg, $opt_relative); + $pkg, $do_relative); if ($s > 0) { $obj->containersize($s); } @@ -293,6 +315,10 @@ sub main $obj->containermd5($m); } } + # if the container has been build relocatable we save that information + $obj->relocated($do_relative); + # and remove the common prefix from the files in the tlpobj + $obj->cancel_common_texmf_tree if $do_relative; # add the updated (or new) TLPOBJ to NET TLPDB # that way the other container sizes are not destroyed $nettlpdb->add_tlpobj($obj) unless $opt_dry; diff --git a/Master/tlpkg/bin/tlpfiles b/Master/tlpkg/bin/tlpfiles index e41b6cf4c7e..d5407b45aab 100755 --- a/Master/tlpkg/bin/tlpfiles +++ b/Master/tlpkg/bin/tlpfiles @@ -17,7 +17,7 @@ BEGIN { use strict; -use TeXLive::TLConfig; +use TeXLive::TLConfig qw/$RelocPrefix $RelocTree/; use TeXLive::TLPDB; use Pod::Usage; use Getopt::Long; @@ -58,6 +58,7 @@ sub main die "$0: no TeX Live package named $pkg in $Master.\n" if ! $obj; my @files = $obj->all_files; + if ($obj->relocated) { for (@files) { s:^$RelocPrefix/:$RelocTree/:; } } print "$_\n" foreach @files; return 0; diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index 27c1902bc83..d30f0a5444f 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -9,7 +9,7 @@ BEGIN { unshift (@INC, "$mydir/.."); } -use TeXLive::TLConfig; +use TeXLive::TLConfig qw/$RelocPrefix $RelocTree/; use TeXLive::TLPOBJ; use TeXLive::TLPDB; @@ -323,6 +323,7 @@ sub do_tlp push @tpm_files, $tlp->runfiles; push @tpm_files, $tlp->docfiles; push @tpm_files, $tlp->srcfiles; + if ($tlp->relocated) { for (@tpm_files) { s:^$RelocPrefix/:$RelocTree/:; } } # we don't push bin files, should we? my @compared = (); diff --git a/Master/tlpkg/bin/tlprm b/Master/tlpkg/bin/tlprm index cfa18ba3ca4..859a2edd122 100755 --- a/Master/tlpkg/bin/tlprm +++ b/Master/tlpkg/bin/tlprm @@ -18,7 +18,7 @@ BEGIN { use strict; -use TeXLive::TLConfig; +use TeXLive::TLConfig qw/$RelocPrefix $RelocTree/; use TeXLive::TLPDB; use TeXLive::TLPSRC; use TeXLive::TLUtils; @@ -50,6 +50,7 @@ sub main } my @files = $obj->all_files; + if ($tlp->relocated) { for (@files) { s:^$RelocPrefix/:$RelocTree/:; } } my $tlpsrc = new TeXLive::TLPSRC; $tlpsrc->from_file ($f); push (@files, $tlpsrc->_srcfile); # also want to remove the tlpsrc file. -- cgit v1.2.3