Index: tlpkg/TeXLive/TLConfig.pm =================================================================== --- tlpkg/TeXLive/TLConfig.pm (revision 12914) +++ tlpkg/TeXLive/TLConfig.pm (working copy) @@ -30,6 +30,7 @@ @CriticalPackagesList @AllowedConfigOptions $WindowsMainMenuName + $RelocPrefix ); @EXPORT = @EXPORT_OK; } @@ -65,11 +66,13 @@ our $TeXLiveServerURL = "http://mirror.ctan.org"; our $TeXLiveServerPath = "systems/texlive/tlnet/$ReleaseYear"; our $TeXLiveURL = "$TeXLiveServerURL/$TeXLiveServerPath"; +our $RelocPrefix = "texmf-dist"; 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 +178,10 @@ A list of a config options that can be set in 00texlive.installation. +=item C<$TeXLive::TLConfig::RelocPrefix> + +the texmf-tree name that can be relocated. + =back =head1 SEE ALSO Index: tlpkg/TeXLive/TLPOBJ.pm =================================================================== --- tlpkg/TeXLive/TLPOBJ.pm (revision 12914) +++ tlpkg/TeXLive/TLPOBJ.pm (working copy) @@ -6,7 +6,8 @@ package TeXLive::TLPOBJ; -use TeXLive::TLConfig qw($DefaultCategory $CategoriesRegexp $MetaCategoriesRegexp $InfraLocation); +use TeXLive::TLConfig qw($DefaultCategory $CategoriesRegexp + $MetaCategoriesRegexp $InfraLocation $RelocPrefix); use TeXLive::TLUtils; use TeXLive::TLTREE; @@ -22,6 +23,7 @@ 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 +167,10 @@ $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 +311,7 @@ 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'}) && 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 +439,37 @@ } } +sub cancel_common_texmf_tree { + my $self = shift; + my @docfiles = $self->docfiles; + for (@docfiles) { s:^$RelocPrefix/::; } + $self->docfiles(@docfiles); + my @runfiles = $self->runfiles; + for (@runfiles) { s:^$RelocPrefix/::; } + $self->runfiles(@runfiles); + my @srcfiles = $self->srcfiles; + for (@srcfiles) { s:^$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 +479,18 @@ 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; @@ -895,6 +921,11 @@ 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 +1120,11 @@ 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 +1297,12 @@ 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 Index: tlpkg/TeXLive/TLMedia.pm =================================================================== --- tlpkg/TeXLive/TLMedia.pm (revision 12914) +++ tlpkg/TeXLive/TLMedia.pm (working copy) @@ -117,6 +117,7 @@ # even if opt_doc is false $real_opt_doc = 1; } + my $reloc = 1 if $tlpobj->relocated; my $container; my @installfiles; my $location = $self->location; @@ -155,7 +156,7 @@ } 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')) { @@ -173,12 +174,12 @@ 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 @@ -225,7 +226,7 @@ # 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; @@ -255,6 +256,8 @@ } 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 @@ -365,6 +368,7 @@ 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; Index: tlpkg/TeXLive/TLUtils.pm =================================================================== --- tlpkg/TeXLive/TLUtils.pm (revision 12914) +++ tlpkg/TeXLive/TLUtils.pm (working copy) @@ -950,6 +950,7 @@ my $starttime = time(); foreach my $package (@packs) { my $tlpobj = $tlpobjs{$package}; + my $reloc = $tlpobj->relocated; $n++; my $remtime = "??:??"; my $tottime = "??:??"; @@ -1016,7 +1017,7 @@ } 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 @@ 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 @@ 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 @@ } -=item C +=item C This function installs the files given in @$filelistref from C<$what> into C<$target>. @@ -1107,12 +1108,15 @@ 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 @@ # 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"; Index: tlpkg/bin/tl-update-containers =================================================================== --- tlpkg/bin/tl-update-containers (revision 12914) +++ tlpkg/bin/tl-update-containers (working copy) @@ -43,6 +43,7 @@ "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,34 @@ 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 = $opt_relative && # user option + !$deps_on_arch && # no $pkg.ARCH dep + $ctt && # see above + ($ctt eq $TeXLive::TLConfig::RelocPrefix); + # 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 +287,7 @@ $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 +306,7 @@ } 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 +314,10 @@ $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; # 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;