diff options
author | Norbert Preining <preining@logic.at> | 2008-10-01 17:26:02 +0000 |
---|---|---|
committer | Norbert Preining <preining@logic.at> | 2008-10-01 17:26:02 +0000 |
commit | e758d5db577a87bfb7544b1b53f0221bfc928498 (patch) | |
tree | 0e07e875601b0c5171fdb3e59c2bb0ea4057531b /Master | |
parent | 595a59f25219699deb4372ed7ce67ce8831f22af (diff) |
rework of the tlmgr functioning as described
git-svn-id: svn://tug.org/texlive/trunk@10816 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rwxr-xr-x | Master/texmf/scripts/texlive/tlmgr.pl | 210 | ||||
-rw-r--r-- | Master/tlpkg/TeXLive/TLMedia.pm | 35 | ||||
-rw-r--r-- | Master/tlpkg/TeXLive/TLPDB.pm | 89 | ||||
-rwxr-xr-x | Master/tlpkg/bin/tl-update-containers | 4 |
4 files changed, 253 insertions, 85 deletions
diff --git a/Master/texmf/scripts/texlive/tlmgr.pl b/Master/texmf/scripts/texlive/tlmgr.pl index 4802381ad1f..b79b78e04d6 100755 --- a/Master/texmf/scripts/texlive/tlmgr.pl +++ b/Master/texmf/scripts/texlive/tlmgr.pl @@ -13,16 +13,7 @@ # tlmgr fileassoc pdf psv # tlmgr fileassoc ps psv # only setting is possible -# - tlmgr update collection-foobar should check for updates of all -# dependencies, too, so that tlmgr update collection-foobar will get updates -# to sub-packages anyway. -# - update and install should work differently: -# . create a list of all packages to be installed together with -# the depends closure operation -# . call TLMedia->install_package so that deps are NOT installed -# since all deps are actually installed from tlmgr itself -# - reinstall a package: assume that i want to donwgrade from a different -# mirror or I want to fix an accidentally removed file +# Not really necessary?!! # - ordering or collections removal (see below for details) # - (?) removal does not remove created format files from TEXMFSYSVAR # - after install/update show the number of bytes transfered @@ -32,6 +23,8 @@ # - move the remove_package function into TLPDB.pm, so that the remove_package # from TLPDB actually removes the files, too. Maybe some better names # are necessary. +# Maybe not a good idea ... not sure. +# my $svnrev = '$Revision$'; my $tlmgrrevision; @@ -293,18 +286,6 @@ sub remove_package { $localtlpdb->remove_package($pkg); merge_into(\%ret, $tlp->make_return_hash_from_executes("disable")); $ret{'mktexlsr'} = 1; - # remove those bin dependencies .ARCH - foreach my $d ($tlp->depends) { - if ($d eq "$pkg.ARCH") { - foreach my $a ($localtlpdb->available_architectures) { - if (defined($localtlpdb->get_package("$pkg.$a"))) { - debug ("remove $pkg.$a\n"); - merge_into(\%ret, - &remove_package("$pkg.$a", $localtlpdb, $force)); - } - } - } - } # should we save at each removal??? # advantage: the tlpdb actually reflects what is installed # disadvantage: removing a collection calls the save routine several times @@ -319,6 +300,26 @@ sub remove_package { return \%ret; } +# REMOVE +# +# tlmgr remove foo bar baz +# will remove the packages foo bar baz itself +# and will remove all .ARCH dependencies, too +# and if some of them are collections it will also remove the +# depending packs which are NOT Collections|Schemes!!! +# if some of them are referenced somewhere they will not be removed +# unless --force given +# +# tlmgr remove --no-depends foo bar baz +# will remove the packages foo bar baz itself without any dependencies +# but it will still remove all .ARCH dependency +# if some of them are referenced somewhere they will not be removed +# unless --force given +# +# tlmgr remove --really-no-depends foo bar baz +# willabsolutely only install foo bar baz not even taking .ARCH into +# account +# sub action_remove { if ($opt_gui) { action_gui("remove"); @@ -340,16 +341,24 @@ sub action_remove { # my %ret; my $opt_nodepends = 0; + my $opt_reallynodepends = 0; my $opt_force = 0; my $opt_dry = 0; Getopt::Long::Configure(qw(no_pass_through)); GetOptions("no-depends" => \$opt_nodepends, + "really-no-depends" => \$opt_reallynodepends, "force" => \$opt_force, "dry-run" => \$opt_dry) or pod2usage(2); + $opt_nodepends = 1 if $opt_reallynodepends; my %already_removed; my @more_removal; init_local_db(); - foreach my $pkg (@ARGV) { + my @packs = @ARGV; + # remove all .ARCH dependencies, too, unless $opt_reallynodepends + @packs = $localtlpdb->expand_dependencies("-only-arch", $localtlpdb, @packs) unless $opt_reallynodepends; + # remove deps unless $opt_nodepends + @packs = $localtlpdb->expand_dependencies("-no-collections", $localtlpdb, @packs) unless $opt_nodepends; + foreach my $pkg (sort @packs) { my $tlp = $localtlpdb->get_package($pkg); next if defined($already_removed{$pkg}); if (!defined($tlp)) { @@ -376,20 +385,6 @@ sub action_remove { # remove dependencies, too merge_into(\%ret, \%foo); $already_removed{$pkg} = 1; - if (!$opt_nodepends) { - foreach my $d ($tlp->depends) { - my $tlpdd = $localtlpdb->get_package($d); - if (defined($tlpdd)) { - if ($tlpdd->category !~ m/$MetaCategoriesRegexp/) { - info ("remove $d\n"); - if (!$opt_dry) { - merge_into(\%ret, &remove_package($d, $localtlpdb, $opt_force)); - } - $already_removed{$d} = 1; - } - } - } - } } } else { # save all the other packages into the @more_removal list to @@ -400,7 +395,7 @@ sub action_remove { } } } - foreach my $pkg (@more_removal) { + foreach my $pkg (sort @more_removal) { if (!defined($already_removed{$pkg})) { info ("remove $pkg\n"); if (!$opt_dry) { @@ -625,6 +620,24 @@ sub action_backup { } +# UPDATE +# +# tlmgr update foo +# if foo is of type Package|Documentation it will update only foo +# and the respective .ARCH dependencies +# if foo is of type Collection|Scheme it will update itself AND +# will check all depending packs of type NOT(COllection|Scheme) +# for necessary updates +# +# tlmgr update --no-depends foo +# as above, but will not check for depends of Collections/Schemes +# but it will still update .ARCH deps +# +# tlmgr update --really-no-depends foo +# will absolutely only update foo not even taking .ARCH into account +# +# TLMedia->install_package does ONLY INSTALL ONE PACKAGE, no deps whatsoever +# anymore!!!! That has all to be done by hand. sub action_update { if ($opt_gui) { action_gui("update"); @@ -632,6 +645,7 @@ sub action_update { init_local_db(1); # initialize the TLMedia from $location my $opt_nodepends = 0; + my $opt_reallynodepends = 0; my $opt_dry = 0; my $opt_all = 0; my $opt_list = 0; @@ -639,11 +653,13 @@ sub action_update { my $opt_backupdir; Getopt::Long::Configure(qw(no_pass_through)); GetOptions("no-depends" => \$opt_nodepends, + "really-no-depends" => \$opt_reallynodepends, "all" => \$opt_all, "list" => \$opt_list, "no-remove" => \$opt_noremove, "backupdir=s" => \$opt_backupdir, "dry-run" => \$opt_dry) or pod2usage(2); + $opt_nodepends = 1 if $opt_reallynodepends; my %ret; init_tlmedia(); my $mediatlpdb = $tlmediasrc->tlpdb; @@ -721,7 +737,11 @@ sub action_update { } my $updater_started = 0; my $nrupdated = 0; - foreach my $pkg (@todo) { + # update all .ARCH dependencies, too, unless $opt_reallynodepends + @todo = $mediatlpdb->expand_dependencies("-only-arch", $localtlpdb, @todo) unless $opt_reallynodepends; + # update deps unless $opt_nodepends + @todo = $mediatlpdb->expand_dependencies("-no-collections", $localtlpdb, @todo) unless $opt_nodepends; + foreach my $pkg (sort @todo) { next if ($pkg =~ m/^00texlive/); my $tlp = $localtlpdb->get_package($pkg); if (!defined($tlp)) { @@ -832,7 +852,7 @@ EOF # the remove_package should also remove empty dirs in case # a dir is changed into a file merge_into(\%ret, &remove_package($pkg, $localtlpdb, 1)); - my $foo = $tlmediasrc->install_package($pkg, $localtlpdb, $opt_nodepends, 0); + my $foo = $tlmediasrc->install_package($pkg, $localtlpdb); if (ref $foo) { # installation succeeded because we got a reference merge_into (\%ret, $foo); @@ -914,6 +934,34 @@ EOF return(\%ret); } +# INSTALL +# +# tlmgr install foo bar baz +# will create the closure under dependencies of {foo,bar,baz}, i.e. all +# dependencies recursively down to the last package, and install all +# the packages that are necessary +# +# tlmgr install --no-depends foo bar baz +# will *only* install these three packages (if they are not already installed +# but it will STILL INSTALL foo.ARCH if they are necessary!! +# +# tlmgr install --really-no-depends foo bar baz +# will absolutely only install these three packages, and will not even +# take .ARCH deps into account +# +# tlmgr install --reinstall ... +# behaves exactely like without --reinstall BUT the following two +# differences: +# . dependencies are not expanded from collection to collection, so +# if you reinstall a collection then all its dependencies of type +# Package will be reinstalled, too, but not the dependencies on +# other collection, because that would force the full reinstallation +# of the whole installation +# . it does not care for whether a package seems to be installed or +# not (that is the --reinstall) +# +# TLMedia->install_package does ONLY INSTALL ONE PACKAGE, no deps whatsoever +# anymore!!!! That has all to be done by hand. sub action_install { if ($opt_gui) { action_gui("install"); @@ -921,19 +969,41 @@ sub action_install { init_local_db(1); # initialize the TLMedia from $location my $opt_nodepends = 0; + my $opt_reallynodepends = 0; my $opt_dry = 0; + my $opt_reinstall = 0; Getopt::Long::Configure(qw(no_pass_through)); GetOptions("no-depends" => \$opt_nodepends, + "really-no-depends" => \$opt_reallynodepends, + "reinstall" => \$opt_reinstall, "dry-run" => \$opt_dry) or pod2usage(2); my %ret; init_tlmedia(); - foreach my $pkg (@ARGV) { - if ($opt_dry) { - print "install: $pkg\n"; - } else { - # install the packages and run postinstall actions (that is the 0) + my $tlmediatlpdb = $tlmediasrc->tlpdb; + $opt_nodepends = 1 if $opt_reallynodepends; + my @packs = @ARGV; + # first expand the .ARCH dependencies unless $opt_reallynodepends + @packs = $tlmediatlpdb->expand_dependencies("-only-arch", $localtlpdb, @ARGV) unless $opt_reallynodepends; + # now expand all others unless $opt_nodepends + # if $opt_reinstall do not collection->collection dependencies + if ($opt_reinstall) { + @packs = $tlmediatlpdb->expand_dependencies("-no-collections", $localtlpdb, @packs) unless $opt_nodepends; + } else { + @packs = $tlmediatlpdb->expand_dependencies($localtlpdb, @packs) unless $opt_nodepends; + } + foreach my $pkg (sort @packs) { + if (defined($localtlpdb->get_package($pkg))) { + if ($opt_reinstall) { + info("re-"); + } else { + debug("already installed: $pkg\n"); + next; + } + } + info("install: $pkg\n"); + if (!$opt_dry) { info("install: $pkg\n"); - merge_into(\%ret, $tlmediasrc->install_package($pkg, $localtlpdb, $opt_nodepends, 0)); + merge_into(\%ret, $tlmediasrc->install_package($pkg, $localtlpdb)); } } if ($opt_dry) { @@ -1097,7 +1167,7 @@ sub action_arch { print "Installing $pkg.$a\n"; } else { info("install: $pkg.$a\n"); - merge_into(\%ret, $tlmediasrc->install_package("$pkg.$a", $localtlpdb, 0, 0)); + merge_into(\%ret, $tlmediasrc->install_package("$pkg.$a", $localtlpdb)); } } } @@ -1106,11 +1176,11 @@ sub action_arch { if (TeXLive::TLUtils::member('win32', @todoarchs)) { # install the necessary win32 stuff info("install: bin-tlperl.win32\n"); - merge_into (\%ret, $tlmediasrc->install_package("bin-tlperl.win32", $localtlpdb, 1, 0)); + merge_into (\%ret, $tlmediasrc->install_package("bin-tlperl.win32", $localtlpdb)); info("install: bin-tlgs.win32\n"); - merge_into (\%ret, $tlmediasrc->install_package("bin-tlgs.win32", $localtlpdb, 1, 0)); + merge_into (\%ret, $tlmediasrc->install_package("bin-tlgs.win32", $localtlpdb)); info("install: bin-tlpsv.win32\n"); - merge_into (\%ret, $tlmediasrc->install_package("bin-tlpsv.win32", $localtlpdb, 1, 0)); + merge_into (\%ret, $tlmediasrc->install_package("bin-tlpsv.win32", $localtlpdb)); } # update the option_archs list of installed archs my @larchs = $localtlpdb->option_available_architectures; @@ -1696,11 +1766,28 @@ all packages that the given I<pkg>s are dependent on, also. Options: =over 8 +=item B<--reinstall> + +Reinstall a package (including dependencies for collections) even if it +seems to be already installed. Can be used to recover from accidently +removed files of a package. + +Note that when re-installing packages not all dependencies are reinstalled, +only dependencies on normal packages (not of category Scheme or Collection). + =item B<--no-depends> Do not install dependencies. (By default, installing a package ensures that all dependencies of this package are fulfilled.) +=item B<--really-no-depends> + +When you install a package which ships binary files the respective binary +package will also be installed. (So for package bin-foobar also the package +bin-foobar.i386-linux will be installed on an i386-linux system.) +This switch supresses this behaviour, and also implies C<--no-depends>. +Don't use it unless you are really sure what you are doing. + =item B<--dry-run> Nothing is actually installed; instead, the actions to be performed are @@ -1753,6 +1840,21 @@ be saved before updates are performed. Then you can restore later if the update turns out to be problematic; see the C<restore> action for details. +=item B<--no-depends> + +If you call for updating a package normally all depending packages +will also be checked for updates and updated if necessary. This switch +supresses this behaviour. + +=item B<--really-no-depends> + +When you update a package which ships binary files the respective binary +package will also be updated. (So for package bin-foobar also the package +bin-foobar.i386-linux will be updated on an i386-linux system.) +This switch supresses this behaviour, and also implies C<--no-depends>. +Don't use it unless you are really sure what you are doing. + + =back If the package on the server is older than the package already installed @@ -1823,6 +1925,14 @@ package, dependencies are never removed. Options: Do not remove dependent packages. +=item B<--really-no-depends> + +When you remove a package which ships binary files the respective binary +package will also be removed. (So for package bin-foobar also the package +bin-foobar.i386-linux will be removed on an i386-linux system.) +This switch supresses this behaviour, and also implies C<--no-depends>. +Don't use it unless you are really sure what you are doing. + =item B<--force> By default, removal of a package or collection that is a dependency of diff --git a/Master/tlpkg/TeXLive/TLMedia.pm b/Master/tlpkg/TeXLive/TLMedia.pm index 3d172abfd7b..60138d7eb93 100644 --- a/Master/tlpkg/TeXLive/TLMedia.pm +++ b/Master/tlpkg/TeXLive/TLMedia.pm @@ -89,14 +89,14 @@ sub new # returns a scalar (0) on error # returns a reference to a hash with actions on success sub install_package { - my ($self, $pkg, $totlpdb, $nodepends, $nopostinstall, $fallbackmedia) = @_; + my ($self, $pkg, $totlpdb, $nopostinstall, $fallbackmedia) = @_; my $fromtlpdb = $self->tlpdb; my $ret; die("TLMedia not initialized, cannot find tlpdb!") unless (defined($fromtlpdb)); my $tlpobj = $fromtlpdb->get_package($pkg); if (!defined($tlpobj)) { if (defined($fallbackmedia)) { - if ($ret = $fallbackmedia->install_package($pkg,$totlpdb, $nodepends, $nopostinstall)) { + if ($ret = $fallbackmedia->install_package($pkg,$totlpdb, $nopostinstall)) { debug("installed $pkg from fallback"); return $ret; } else { @@ -204,37 +204,6 @@ sub install_package { # compute the return value my %ret; merge_into(\%ret, $tlpobj->make_return_hash_from_executes("enable")); - # now install all the depends if they are not already present - # NOTE: installation of .ARCH dependencies is done in *ANY*CASE*, regardless - # of the $nodepends setting - foreach my $d ($tlpobj->depends) { - if ($d =~ m/^(.*)\.ARCH$/) { - # we only want to try to install a .ARCH package if it actually contains - # files - my $foo = $1; - foreach my $a ($totlpdb->available_architectures) { - if (defined($fromtlpdb->get_package("$foo.$a")) && - !defined($totlpdb->get_package("$foo.$a"))) { - merge_into(\%ret, - $self->install_package("$foo.$a", $totlpdb, $nodepends, $fallbackmedia, 0)); - } - } - } elsif ($d =~ m/^(.*).win32$/) { - # install only of win32 is under the available archs - if (TeXLive::TLUtils::member("win32",$totlpdb->available_architectures)) { - merge_into(\%ret, - $self->install_package($d, $totlpdb, $nodepends, $nopostinstall, $fallbackmedia)); - } - } else { - if (!$nodepends) { - if (!defined($totlpdb->get_package($d))) { - # we have to install it! - merge_into(\%ret, - $self->install_package($d, $totlpdb, $nodepends, $nopostinstall, $fallbackmedia)); - } - } - } - } if (!$nopostinstall) { # do the postinstallation actions if (defined($PostInstall{$pkg})) { diff --git a/Master/tlpkg/TeXLive/TLPDB.pm b/Master/tlpkg/TeXLive/TLPDB.pm index 27685233428..e3fa244396b 100644 --- a/Master/tlpkg/TeXLive/TLPDB.pm +++ b/Master/tlpkg/TeXLive/TLPDB.pm @@ -33,6 +33,8 @@ C<TeXLive::TLPDB> -- A database of TeX Live Packages $tlpdb->remove_package($pkg); $tlpdb->get_package("packagename"); $tlpdb->list_packages; + $tlpdb->expand_dependencies(["-only-arch",] $totlpdb, @list); + $tlpdb->expand_dependencies(["-no-collections",] $totlpdb, @list); $tlpdb->find_file("filename"); $tlpdb->collections; $tlpdb->schemes; @@ -446,6 +448,93 @@ sub list_packages { =pod +=item C<< $tlpdb->expand_dependencies >> + +This function takes as first argument the target TLPDB and then a list of +packages and returns the closure of this +list with respect to the depends operator. (Sorry, that was for +mathematicians) + +If the very first argument is "-only-arch" then it expands only dependencies +of the form .ARCH. + +=cut + +sub expand_dependencies { + my $self = shift; + my $only_arch = 0; + my $no_collections = 0; + my $first = shift; + my $totlpdb; + if ($first eq "-only-arch") { + $only_arch = 1; + $totlpdb = shift; + } elsif ($first eq "-no-collections") { + $no_collections = 1; + $totlpdb = shift; + } else { + $totlpdb = $first; + } + my %install = (); + my @archs = $totlpdb->available_architectures; + for my $p (@_) { + $install{$p} = 1; + } + my $changed = 1; + while ($changed) { + $changed = 0; + my @pre_select = keys %install; + ddebug("pre_select = @pre_select\n"); + for my $p (@pre_select) { + next if ($p =~ m/^00texlive/); + my $pkg = $self->get_package($p); + if (!defined($pkg)) { + debug("W: $p is mentioned somewhere but not available, disabling it!\n"); + $install{$p} = 0; + next; + } + for my $p_dep ($pkg->depends) { + ddebug("checking $p_dep in $p\n"); + my $tlpdd = $self->get_package($p_dep); + if (defined($tlpdd)) { + if ($tlpdd->category =~ m/$MetaCategoriesRegexp/) { + # we are taking a look at a dependency which is a collection + # or scheme, and if the option "-no-collections" is given + # we skip that one + ddebug("expand_deps: skipping $p_dep in $p due to -no-collections\n"); + next if $no_collections; + } + } + if ($p_dep =~ m/^(.*)\.ARCH$/) { + my $foo = "$1"; + foreach $a (@archs) { + $install{"$foo.$a"} = 1 if defined($self->get_package("$foo.$a")); + } + } elsif ($p_dep =~ m/^(.*)\.win32$/) { + # a win32 package should *only* be installed if we are installing + # the win32 arch + if (grep(/^win32$/,@archs)) { + $install{$p_dep} = 1; + } + } else { + $install{$p_dep} = 1 unless $only_arch; + } + } + } + + # check for newly selected packages + my @post_select = keys %install; + ddebug("post_select = @post_select\n"); + ddebug("nr pre select $#pre_select, nr post select $#post_select\n"); + if ($#pre_select != $#post_select) { + $changed = 1; + } + } + return(keys %install); +} + +=pod + =item C<< $tlpdb->find_file("filename") >> The C<find_file> returns a list of packages:filename diff --git a/Master/tlpkg/bin/tl-update-containers b/Master/tlpkg/bin/tl-update-containers index 1d3c8c43098..bbe6dba7961 100755 --- a/Master/tlpkg/bin/tl-update-containers +++ b/Master/tlpkg/bin/tl-update-containers @@ -56,7 +56,7 @@ sub main chomp(my $Master = `cd $mydir/../.. && pwd`); my $tlpdb = TeXLive::TLPDB->new("root" => $Master); die "cannot find tlpdb in $Master" unless defined($tlpdb); - my @packs = @ARGV ? @ARGV : $tlpdb->list_packages; + my @packs = $tlpdb->expand_dependencies("-only-arch", $tlpdb, @ARGV ? @ARGV : $tlpdb->list_packages); # get configuration of package splitting my $srcsplit = $tlpdb->config_src_container; @@ -87,7 +87,7 @@ sub main if ($opt_recreate) { # remake everything. if (@ARGV) { - @todopacks = @ARGV; + @todopacks = @packs; $nettlpdb = TeXLive::TLPDB->new; die "Cannot create new tlpdb" unless defined($nettlpdb); } else { |