summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNorbert Preining <preining@logic.at>2008-10-01 17:26:02 +0000
committerNorbert Preining <preining@logic.at>2008-10-01 17:26:02 +0000
commite758d5db577a87bfb7544b1b53f0221bfc928498 (patch)
tree0e07e875601b0c5171fdb3e59c2bb0ea4057531b
parent595a59f25219699deb4372ed7ce67ce8831f22af (diff)
rework of the tlmgr functioning as described
git-svn-id: svn://tug.org/texlive/trunk@10816 c570f23f-e606-0410-a88d-b1316a301751
-rwxr-xr-xMaster/texmf/scripts/texlive/tlmgr.pl210
-rw-r--r--Master/tlpkg/TeXLive/TLMedia.pm35
-rw-r--r--Master/tlpkg/TeXLive/TLPDB.pm89
-rwxr-xr-xMaster/tlpkg/bin/tl-update-containers4
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 {