summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Master/tlpkg/dev/dev.multi-source-support-v2.patch814
1 files changed, 478 insertions, 336 deletions
diff --git a/Master/tlpkg/dev/dev.multi-source-support-v2.patch b/Master/tlpkg/dev/dev.multi-source-support-v2.patch
index e87a772a1f3..649177ba952 100644
--- a/Master/tlpkg/dev/dev.multi-source-support-v2.patch
+++ b/Master/tlpkg/dev/dev.multi-source-support-v2.patch
@@ -1,6 +1,482 @@
+Index: texmf/scripts/texlive/tlmgr.pl
+===================================================================
+--- texmf/scripts/texlive/tlmgr.pl (revision 22399)
++++ texmf/scripts/texlive/tlmgr.pl (working copy)
+@@ -124,6 +124,7 @@
+ "package-logfile" => "=s",
+ "persistent-downloads" => "!",
+ "no-execute-actions" => 1,
++ "pin-file" => "=s",
+ "pause" => 1,
+ "print-platform|print-arch" => 1,
+ "version" => 1,
+@@ -480,6 +481,12 @@
+ } elsif ($action =~ m/^option$/i) {
+ action_option();
+ finish(0);
++ } elsif ($action =~ m/^repository$/i) {
++ action_repository();
++ finish(0);
++ } elsif ($action =~ m/^candidates$/i) {
++ action_candidates();
++ finish(0);
+ } elsif ($action =~ m/^list$/i) {
+ action_list();
+ finish(0);
+@@ -1941,7 +1948,12 @@
+ # intersection, don't check A\B and B\A
+ next if $newpkgs_full{$p};
+ next if $removals_full{$p};
+- next if ($remotetlpdb->get_package($p)->category ne "Collection");
++ my $remotetlp = $remotetlpdb->get_package($p);
++ if (!defined($remotetlp)) {
++ tlwarn("Strange, $p mentioned but not found anywhere!\n");
++ next;
++ }
++ next if ($remotetlp->category ne "Collection");
+ my $tlp = $localtlpdb->get_package($p);
+ if (!defined($tlp)) {
+ if ($opts{"reinstall-forcibly-removed"}) {
+@@ -2042,12 +2054,15 @@
+ $ret = 1;
+ shift;
+ }
+- my ($pkg, $flag, $lrev, $rrev, @args) = @_;
++ my ($pkg, $flag, $lrev, $rrev, $size, $runtime, $esttot, $tag) = @_;
+ $lrev ||= "-";
+ $rrev ||= "-";
+ $flag ||= "?";
+- my $str = "$pkg\t$flag\t$lrev\t$rrev\t";
+- $str .= join("\t", @args) if (@args);
++ $size ||= "-";
++ $runtime ||= "-";
++ $esttot ||= "-";
++ $tag ||= "-";
++ my $str = join("\t", $pkg, $flag, $lrev, $rrev, $size, $runtime, $esttot, $tag);
+ $str .= "\n";
+ return($str) if $ret;
+ print $str;
+@@ -2571,19 +2586,32 @@
+ my $unwind_package;
+ my $remove_unwind_container = 0;
+ my $rev = $tlp->revision;
+- my $mediatlp = $remotetlpdb->get_package($pkg);
++ my $mediatlp;
++ my $maxtag;
++ if ($remotetlpdb->is_virtual) {
++ ($maxtag, undef, $mediatlp, undef) =
++ $remotetlpdb->virtual_candidate($pkg);
++ } else {
++ $mediatlp = $remotetlpdb->get_package($pkg);
++ }
+ if (!defined($mediatlp)) {
+ debug("$pkg cannot be found in $location\n");
+ next;
+ }
+ my $mediarev = $mediatlp->revision;
++ my $mediarevstr = $mediarev;
++ my @addargs = ();
++ if ($remotetlpdb->is_virtual) {
++ push @addargs, $maxtag;
++ $mediarevstr .= "\@$maxtag";
++ }
+ $nrupdated++;
+ if ($opts{"list"}) {
+ if ($::machinereadable) {
+- machine_line($pkg, $FLAG_UPDATE, $rev, $mediarev, $sizes{$pkg});
++ machine_line($pkg, $FLAG_UPDATE, $rev, $mediarev, $sizes{$pkg}, "-", "-", @addargs);
+ } else {
+ my $kb = int($sizes{$pkg} / 1024) + 1;
+- info("$pkg [${kb}k]: local: $rev, source: $mediarev (update)\n");
++ info("$pkg [${kb}k]: local: $rev, source: $mediarevstr (update)\n");
+ }
+ $updated{$pkg} = 1;
+ next;
+@@ -2624,10 +2652,10 @@
+ }
+
+ if ($::machinereadable) {
+- machine_line($pkg, $FLAG_UPDATE, $rev, $mediarev, $sizes{$pkg}, $estrem, $esttot);
++ machine_line($pkg, $FLAG_UPDATE, $rev, $mediarev, $sizes{$pkg}, $estrem, $esttot, @addargs);
+ } else {
+ my $kb = int ($sizes{$pkg} / 1024) + 1;
+- info("[$currnr/$totalnr, $estrem/$esttot] update: $pkg [${kb}k] ($rev -> $mediarev)");
++ info("[$currnr/$totalnr, $estrem/$esttot] update: $pkg [${kb}k] ($rev -> $mediarevstr)");
+ }
+ $donesize += $sizes{$pkg};
+ $currnr++;
+@@ -2670,7 +2698,7 @@
+ }
+ if ($remotetlpdb->install_package($pkg, $localtlpdb)) {
+ # installation succeeded because we got a reference
+- logpackage("update: $pkg ($rev -> $mediarev)");
++ logpackage("update: $pkg ($rev -> $mediarevstr)");
+ unlink($unwind_package) if $remove_unwind_container;
+ # remember successful update
+ $updated{$pkg} = 1;
+@@ -2698,7 +2726,7 @@
+ # now in fact we should do some cleanup, removing files and
+ # dirs from the new package before re-installing the old one.
+ # TODO
+- logpackage("failed update: $pkg ($rev -> $mediarev)");
++ logpackage("failed update: $pkg ($rev -> $mediarevstr)");
+ tlwarn("\n\nInstallation of new version of $pkg did fail, trying to unwind.\n");
+ if (win32()) {
+ # w32 is notorious for not releasing a file immediately
+@@ -2739,12 +2767,25 @@
+ unless $::machinereadable;
+ } else {
+ # install new packages
+- my $mediatlp = $remotetlpdb->get_package($pkg);
++ my $mediatlp;
++ my $maxtag;
++ if ($remotetlpdb->is_virtual) {
++ ($maxtag, undef, $mediatlp, undef) =
++ $remotetlpdb->virtual_candidate($pkg);
++ } else {
++ $mediatlp = $remotetlpdb->get_package($pkg);
++ }
+ if (!defined($mediatlp)) {
+ tlwarn("\nShould not happen: $pkg not found in $location");
+ next;
+ }
+ my $mediarev = $mediatlp->revision;
++ my $mediarevstr;
++ my @addargs;
++ if ($remotetlpdb->is_virtual) {
++ $mediarevstr = "$mediarev\@$maxtag";
++ push @addargs, $maxtag;
++ }
+ my ($estrem, $esttot);
+ if (!$opts{"list"}) {
+ ($estrem, $esttot) = TeXLive::TLUtils::time_estimate($totalsize,
+@@ -2754,14 +2795,16 @@
+ my @maargs = ($pkg, $FLAG_AUTOINSTALL, "-", $mediatlp->revision, $sizes{$pkg});
+ if (!$opts{"list"}) {
+ push @maargs, $estrem, $esttot;
++ } else {
++ push @maargs, undef, undef;
+ }
+- machine_line(@maargs);
++ machine_line(@maargs, @addargs);
+ } else {
+ my $kb = int($sizes{$pkg} / 1024) + 1;
+ if ($opts{"list"}) {
+- info("$pkg [${kb}k]: local: <absent>, source: " . $mediatlp->revision . " (auto-install)\n");
++ info("$pkg [${kb}k]: local: <absent>, source: $mediarevstr (auto-install)\n");
+ } else {
+- info("[$currnr/$totalnr, $estrem/$esttot] auto-install: $pkg [${kb}k]\n");
++ info("[$currnr/$totalnr, $estrem/$esttot] auto-install: $pkg ($mediarevstr) [${kb}k]\n");
+ }
+ }
+ $currnr++;
+@@ -2769,7 +2812,7 @@
+ next if ($opts{"dry-run"} || $opts{"list"});
+ if ($remotetlpdb->install_package($pkg, $localtlpdb)) {
+ # installation succeeded because we got a reference
+- logpackage("auto-install new: $pkg ($mediarev)");
++ logpackage("auto-install new: $pkg ($mediarevstr)");
+ $nrupdated++;
+ } else {
+ tlwarn("$0: couldn't install new package $pkg\n");
+@@ -2908,6 +2951,7 @@
+ if (!(@new || @updated)) {
+ info("tlmgr: no updates available\n");
+ if ($remotetlpdb->media ne "NET"
++ && $remotetlpdb->media ne "virtual"
+ && !$opts{"dry-run"}
+ && !$opts{"repository"}
+ ) {
+@@ -3123,7 +3167,150 @@
+ return;
+ }
+
++# REPOSITORY
++#
++# this action manages the list of repositories
++# tlmgr repository list -> lists repositories
++# tlmgr repository add path [tag] -> add repository with optional tag
++# tlmgr repository remove [path|tag] -> removes repository or tag
++# tlmgr repository set path[#tag] [path[#tag] ...] -> sets the list
++#
+
++sub array_to_repository {
++ my %r = @_;
++ my @ret;
++ for my $k (keys %r) {
++ my $v = $r{$k};
++ if ($k eq $v) {
++ push @ret, $k;
++ } else {
++ push @ret, "$v#$k";
++ }
++ }
++ return "@ret";
++}
++sub repository_to_array {
++ my $r = shift;
++ my %r;
++ for my $rr (split ' ', $r) {
++ if ($rr =~ m/^([^#]+)#(.*)$/) {
++ $r{$2} = $1;
++ } else {
++ $r{$rr} = $rr;
++ }
++ }
++ return %r;
++}
++sub action_repository {
++ init_local_db();
++ my $what = shift @ARGV;
++ $what = "list" if !defined($what);
++ my %repos = repository_to_array($localtlpdb->option("location"));
++ if ($what =~ m/^list$/i) {
++ print "List of repositories (with tags if set):\n";
++ for my $k (keys %repos) {
++ my $v = $repos{$k};
++ print "\t$v";
++ if ($k ne $v) {
++ print " ($k)";
++ }
++ print "\n";
++ }
++ return;
++ }
++ if ($what eq "add") {
++ my $p = shift @ARGV;
++ if (!defined($p)) {
++ tlwarn("You need to give a new repository aas argument to add\n");
++ return;
++ }
++ my $t = shift @ARGV;
++ $t = $p if (!defined($t));
++ if (defined($repos{$t})) {
++ tlwarn("This repository or its tag is already defined, no action\n");
++ return;
++ }
++ # TODO more checks needed?
++ # if there was till now only *one* repository and that without
++ # a tag, we give that one the "main" tag which is necessary
++ # for proper operation!
++ my @tags = keys %repos;
++ if ($#tags == 0) {
++ # we have only one repository, check if it has the main tag
++ my $maintag = $tags[0];
++ if ($maintag ne 'main') {
++ $repos{'main'} = $repos{$maintag};
++ delete $repos{$maintag};
++ }
++ }
++ $repos{$t} = $p;
++ $localtlpdb->option("location", array_to_repository(%repos));
++ $localtlpdb->save;
++ return;
++ }
++ if ($what eq "remove") {
++ my $p = shift @ARGV;
++ if (!defined($p)) {
++ tlwarn("Which repository should be removed?\n");
++ return;
++ }
++ my $found = 0;
++ for my $k (keys %repos) {
++ if ($k eq $p || $repos{$k} eq $p) {
++ $found = 1;
++ delete $repos{$k};
++ }
++ }
++ if (!$found) {
++ tlwarn("Cannot find the repository $p\n");
++ } else {
++ $localtlpdb->option("location", array_to_repository(%repos));
++ $localtlpdb->save;
++ }
++ return;
++ }
++ if ($what eq "set") {
++ %repos = repository_to_array("@ARGV");
++ $localtlpdb->option("location", array_to_repository(%repos));
++ $localtlpdb->save;
++ return;
++ }
++ # we are still here, unknown command to repository
++ tlwarn("tlmgr: unknown directive to tlmgr repository: $what\n");
++ return;
++}
++
++sub action_candidates {
++ my $what = shift @ARGV;
++ if (!defined($what)) {
++ tlwarn("tlmgr: action candidates needs a package name as argument\n");
++ return;
++ }
++ init_local_db();
++ init_tlmedia();
++ my @cand = $remotetlpdb->candidates($what);
++ if (@cand) {
++ my $first = shift @cand;
++ if (defined($first)) {
++ my ($t,$r) = split(/\//, $first, 2);
++ print "Install candidate for $what from $t ($r)\n";
++ } else {
++ print "No install candidate for $what found.\n";
++ }
++ # already shifted away the first element
++ if ($#cand >= 0) {
++ print "Other repositories providing this package:\n";
++ for my $a (@cand) {
++ my ($t,$r) = split(/\//, $a, 2);
++ print "$t ($r)\n";
++ }
++ }
++ } else {
++ print "Package $what not found.\n";
++ }
++ return;
++}
++
+ # OPTION
+ #
+ sub action_option {
+@@ -4470,6 +4657,74 @@
+ #
+ sub init_tlmedia
+ {
++ # first check if $location contains multiple locations
++ # in this case we go to virtual mode
++ #my %repos = repository_to_array($localtlpdb->option("location"));
++ my %repos = repository_to_array($location);
++ my @tags = keys %repos;
++ # check if we are only one tag/repo
++ if ($#tags == 0) {
++ # go to normal mode
++ _init_tlmedia();
++ return;
++ }
++ # we are still here, so we have more tags
++
++ # check that there is a main repository
++ if (!TeXLive::TLUtils::member('main', @tags)) {
++ tldie("Cannot find main repository, you have to tag one as main!\n");
++ }
++
++ # TODO TODO
++ # - abstract the set up of a single media tlpdb
++ # - make clear how to check for a already loaded remotetlpdb
++ $remotetlpdb = TeXLive::TLPDB->new();
++ $remotetlpdb->make_virtual;
++
++ my $locstr = $repos{'main'};
++ my $tlmdb = setup_one_remotetlpdb($locstr);
++ $remotetlpdb->virtual_add_tlpdb($tlmdb, "main");
++ for my $t (@tags) {
++ if ($t ne 'main') {
++ my $tlmdb = setup_one_remotetlpdb($repos{$t});
++ $remotetlpdb->virtual_add_tlpdb($tlmdb, $t);
++ $locstr .= " $repos{$t}";
++ }
++ }
++
++ # now check/setup pinning
++ # TODO for now no default pinning file!
++ if ($opts{"pin-file"}) {
++ my @pins = read_pinning_file($opts{"pin-file"});
++ if (@pins) {
++ $remotetlpdb->virtual_pinning(@pins);
++ }
++ } else {
++ # check for pinning file in TEXMFLOCAL/tlpkg/pinning.txt
++ chomp (my $TEXMFLOCAL = `kpsewhich -var-value=TEXMFLOCAL`);
++ debug("trying to load pinning file $TEXMFLOCAL/tlpkg/pinning.txt\n");
++ if (-r "$TEXMFLOCAL/tlpkg/pinning.txt") {
++ my @pins = read_pinning_file("$TEXMFLOCAL/tlpkg/pinning.txt");
++ if (@pins) {
++ info("tlmgr: using pinning file $TEXMFLOCAL/tlpkg/pinning.txt\n");
++ $remotetlpdb->virtual_pinning(@pins);
++ }
++ }
++ }
++
++
++ # this "location-url" line should not be changed since GUI programs
++ # depend on it:
++ print "location-url\t$locstr\n" if $::machinereadable;
++ info("tlmgr: package repository $locstr\n");
++
++}
++
++
++
++
++sub _init_tlmedia
++{
+ if (defined($remotetlpdb) && ($remotetlpdb->root eq $location)) {
+ # nothing to be done
+ return;
+@@ -4483,11 +4738,29 @@
+ $location =~ s,^$TeXLiveServerURL,$mirrorbase,;
+ }
+
++ $remotetlpdb = setup_one_remotetlpdb($location);
+ # this "location-url" line should not be changed since GUI programs
+ # depend on it:
+ print "location-url\t$location\n" if $::machinereadable;
+ info("tlmgr: package repository $location\n");
++}
+
++sub setup_one_remotetlpdb
++{
++ my $location = shift;
++ my $remotetlpdb;
++
++ # TODO
++ # check if that is already loaded!!!
++
++ # choose a mirror if we are asked.
++ if ($location =~ m/^ctan$/i) {
++ $location = give_ctan_mirror();
++ } elsif ($location =~ m,^$TeXLiveServerURL,) {
++ my $mirrorbase = TeXLive::TLUtils::give_ctan_mirror_base();
++ $location =~ s,^$TeXLiveServerURL,$mirrorbase,;
++ }
++
+ # if we talk about a net location try to download the hash of the tlpdb
+ # - if that is possible, check for the locally saved file and if the hash
+ # agrees load the local copy if present instead of the remote one,
+@@ -4632,8 +4905,30 @@
+ close($tlfh);
+ }
+ }
++
++ return($remotetlpdb);
+ }
+
++sub read_pinning_file {
++ my $pf = shift;
++ my @pins;
++ my $pfh;
++ if (!open($pfh, "<$pf")) {
++ tlwarn("Pinning file $pf cannot be read: $!\n");
++ return;
++ }
++ debug("Reading pinning file $pf\n");
++ while (my $l = TeXLive::TLUtils::get_full_line($pfh)) {
++ chomp($l);
++ # comments and empty lines are allowed
++ next if ($l =~ m/^\s*#/);
++ next if ($l =~ m/^\s*$/);
++ my ($a, $b) = split(/:/, $l);
++ push @pins, $remotetlpdb->make_pin_data_from_line($l);
++ }
++ close($pfh);
++ return @pins;
++}
+
+
+ # finish handles the -pause option (wait for input from stdin),
Index: tlpkg/TeXLive/TLPDB.pm
===================================================================
---- tlpkg/TeXLive/TLPDB.pm (revision 22343)
+--- tlpkg/TeXLive/TLPDB.pm (revision 22399)
+++ tlpkg/TeXLive/TLPDB.pm (working copy)
@@ -73,17 +73,27 @@
$tlpdb->install_package($pkg, $dest_tlpdb, $nopostinstall, $fallbacktlpdb);
@@ -754,7 +1230,7 @@ Index: tlpkg/TeXLive/TLPDB.pm
=head1 OPTIONS
Index: tlpkg/TeXLive/TLUtils.pm
===================================================================
---- tlpkg/TeXLive/TLUtils.pm (revision 22343)
+--- tlpkg/TeXLive/TLUtils.pm (revision 22399)
+++ tlpkg/TeXLive/TLUtils.pm (working copy)
@@ -62,6 +62,7 @@
TeXLive::TLUtils::setup_programs($bindir, $platform);
@@ -804,337 +1280,3 @@ Index: tlpkg/TeXLive/TLUtils.pm
=back
-Index: texmf/scripts/texlive/tlmgr.pl
-===================================================================
---- texmf/scripts/texlive/tlmgr.pl (revision 22344)
-+++ texmf/scripts/texlive/tlmgr.pl (working copy)
-@@ -124,6 +124,7 @@
- "package-logfile" => "=s",
- "persistent-downloads" => "!",
- "no-execute-actions" => 1,
-+ "pin-file" => "=s",
- "pause" => 1,
- "print-platform|print-arch" => 1,
- "version" => 1,
-@@ -480,6 +481,12 @@
- } elsif ($action =~ m/^option$/i) {
- action_option();
- finish(0);
-+ } elsif ($action =~ m/^repository$/i) {
-+ action_repository();
-+ finish(0);
-+ } elsif ($action =~ m/^candidates$/i) {
-+ action_candidates();
-+ finish(0);
- } elsif ($action =~ m/^list$/i) {
- action_list();
- finish(0);
-@@ -1941,7 +1948,12 @@
- # intersection, don't check A\B and B\A
- next if $newpkgs_full{$p};
- next if $removals_full{$p};
-- next if ($remotetlpdb->get_package($p)->category ne "Collection");
-+ my $remotetlp = $remotetlpdb->get_package($p);
-+ if (!defined($remotetlp)) {
-+ tlwarn("Strange, $p mentioned but not found anywhere!\n");
-+ next;
-+ }
-+ next if ($remotetlp->category ne "Collection");
- my $tlp = $localtlpdb->get_package($p);
- if (!defined($tlp)) {
- if ($opts{"reinstall-forcibly-removed"}) {
-@@ -2908,6 +2920,7 @@
- if (!(@new || @updated)) {
- info("tlmgr: no updates available\n");
- if ($remotetlpdb->media ne "NET"
-+ && $remotetlpdb->media ne "virtual"
- && !$opts{"dry-run"}
- && !$opts{"repository"}
- ) {
-@@ -3123,7 +3136,150 @@
- return;
- }
-
-+# REPOSITORY
-+#
-+# this action manages the list of repositories
-+# tlmgr repository list -> lists repositories
-+# tlmgr repository add path [tag] -> add repository with optional tag
-+# tlmgr repository remove [path|tag] -> removes repository or tag
-+# tlmgr repository set path[#tag] [path[#tag] ...] -> sets the list
-+#
-
-+sub array_to_repository {
-+ my %r = @_;
-+ my @ret;
-+ for my $k (keys %r) {
-+ my $v = $r{$k};
-+ if ($k eq $v) {
-+ push @ret, $k;
-+ } else {
-+ push @ret, "$v#$k";
-+ }
-+ }
-+ return "@ret";
-+}
-+sub repository_to_array {
-+ my $r = shift;
-+ my %r;
-+ for my $rr (split ' ', $r) {
-+ if ($rr =~ m/^([^#]+)#(.*)$/) {
-+ $r{$2} = $1;
-+ } else {
-+ $r{$rr} = $rr;
-+ }
-+ }
-+ return %r;
-+}
-+sub action_repository {
-+ init_local_db();
-+ my $what = shift @ARGV;
-+ $what = "list" if !defined($what);
-+ my %repos = repository_to_array($localtlpdb->option("location"));
-+ if ($what =~ m/^list$/i) {
-+ print "List of repositories (with tags if set):\n";
-+ for my $k (keys %repos) {
-+ my $v = $repos{$k};
-+ print "\t$v";
-+ if ($k ne $v) {
-+ print " ($k)";
-+ }
-+ print "\n";
-+ }
-+ return;
-+ }
-+ if ($what eq "add") {
-+ my $p = shift @ARGV;
-+ if (!defined($p)) {
-+ tlwarn("You need to give a new repository aas argument to add\n");
-+ return;
-+ }
-+ my $t = shift @ARGV;
-+ $t = $p if (!defined($t));
-+ if (defined($repos{$t})) {
-+ tlwarn("This repository or its tag is already defined, no action\n");
-+ return;
-+ }
-+ # TODO more checks needed?
-+ # if there was till now only *one* repository and that without
-+ # a tag, we give that one the "main" tag which is necessary
-+ # for proper operation!
-+ my @tags = keys %repos;
-+ if ($#tags == 0) {
-+ # we have only one repository, check if it has the main tag
-+ my $maintag = $tags[0];
-+ if ($maintag ne 'main') {
-+ $repos{'main'} = $repos{$maintag};
-+ delete $repos{$maintag};
-+ }
-+ }
-+ $repos{$t} = $p;
-+ $localtlpdb->option("location", array_to_repository(%repos));
-+ $localtlpdb->save;
-+ return;
-+ }
-+ if ($what eq "remove") {
-+ my $p = shift @ARGV;
-+ if (!defined($p)) {
-+ tlwarn("Which repository should be removed?\n");
-+ return;
-+ }
-+ my $found = 0;
-+ for my $k (keys %repos) {
-+ if ($k eq $p || $repos{$k} eq $p) {
-+ $found = 1;
-+ delete $repos{$k};
-+ }
-+ }
-+ if (!$found) {
-+ tlwarn("Cannot find the repository $p\n");
-+ } else {
-+ $localtlpdb->option("location", array_to_repository(%repos));
-+ $localtlpdb->save;
-+ }
-+ return;
-+ }
-+ if ($what eq "set") {
-+ %repos = repository_to_array("@ARGV");
-+ $localtlpdb->option("location", array_to_repository(%repos));
-+ $localtlpdb->save;
-+ return;
-+ }
-+ # we are still here, unknown command to repository
-+ tlwarn("tlmgr: unknown directive to tlmgr repository: $what\n");
-+ return;
-+}
-+
-+sub action_candidates {
-+ my $what = shift @ARGV;
-+ if (!defined($what)) {
-+ tlwarn("tlmgr: action candidates needs a package name as argument\n");
-+ return;
-+ }
-+ init_local_db();
-+ init_tlmedia();
-+ my @cand = $remotetlpdb->candidates($what);
-+ if (@cand) {
-+ my $first = shift @cand;
-+ if (defined($first)) {
-+ my ($t,$r) = split(/\//, $first, 2);
-+ print "Install candidate for $what from $t ($r)\n";
-+ } else {
-+ print "No install candidate for $what found.\n";
-+ }
-+ # already shifted away the first element
-+ if ($#cand >= 0) {
-+ print "Other repositories providing this package:\n";
-+ for my $a (@cand) {
-+ my ($t,$r) = split(/\//, $a, 2);
-+ print "$t ($r)\n";
-+ }
-+ }
-+ } else {
-+ print "Package $what not found.\n";
-+ }
-+ return;
-+}
-+
- # OPTION
- #
- sub action_option {
-@@ -4470,6 +4626,74 @@
- #
- sub init_tlmedia
- {
-+ # first check if $location contains multiple locations
-+ # in this case we go to virtual mode
-+ #my %repos = repository_to_array($localtlpdb->option("location"));
-+ my %repos = repository_to_array($location);
-+ my @tags = keys %repos;
-+ # check if we are only one tag/repo
-+ if ($#tags == 0) {
-+ # go to normal mode
-+ _init_tlmedia();
-+ return;
-+ }
-+ # we are still here, so we have more tags
-+
-+ # check that there is a main repository
-+ if (!TeXLive::TLUtils::member('main', @tags)) {
-+ tldie("Cannot find main repository, you have to tag one as main!\n");
-+ }
-+
-+ # TODO TODO
-+ # - abstract the set up of a single media tlpdb
-+ # - make clear how to check for a already loaded remotetlpdb
-+ $remotetlpdb = TeXLive::TLPDB->new();
-+ $remotetlpdb->make_virtual;
-+
-+ my $locstr = $repos{'main'};
-+ my $tlmdb = setup_one_remotetlpdb($locstr);
-+ $remotetlpdb->virtual_add_tlpdb($tlmdb, "main");
-+ for my $t (@tags) {
-+ if ($t ne 'main') {
-+ my $tlmdb = setup_one_remotetlpdb($repos{$t});
-+ $remotetlpdb->virtual_add_tlpdb($tlmdb, $t);
-+ $locstr .= " $repos{$t}";
-+ }
-+ }
-+
-+ # now check/setup pinning
-+ # TODO for now no default pinning file!
-+ if ($opts{"pin-file"}) {
-+ my @pins = read_pinning_file($opts{"pin-file"});
-+ if (@pins) {
-+ $remotetlpdb->virtual_pinning(@pins);
-+ }
-+ } else {
-+ # check for pinning file in TEXMFLOCAL/tlpkg/pinning.txt
-+ chomp (my $TEXMFLOCAL = `kpsewhich -var-value=TEXMFLOCAL`);
-+ debug("trying to load pinning file $TEXMFLOCAL/tlpkg/pinning.txt\n");
-+ if (-r "$TEXMFLOCAL/tlpkg/pinning.txt") {
-+ my @pins = read_pinning_file("$TEXMFLOCAL/tlpkg/pinning.txt");
-+ if (@pins) {
-+ info("tlmgr: using pinning file $TEXMFLOCAL/tlpkg/pinning.txt\n");
-+ $remotetlpdb->virtual_pinning(@pins);
-+ }
-+ }
-+ }
-+
-+
-+ # this "location-url" line should not be changed since GUI programs
-+ # depend on it:
-+ print "location-url\t$locstr\n" if $::machinereadable;
-+ info("tlmgr: package repository $locstr\n");
-+
-+}
-+
-+
-+
-+
-+sub _init_tlmedia
-+{
- if (defined($remotetlpdb) && ($remotetlpdb->root eq $location)) {
- # nothing to be done
- return;
-@@ -4483,11 +4707,29 @@
- $location =~ s,^$TeXLiveServerURL,$mirrorbase,;
- }
-
-+ $remotetlpdb = setup_one_remotetlpdb($location);
- # this "location-url" line should not be changed since GUI programs
- # depend on it:
- print "location-url\t$location\n" if $::machinereadable;
- info("tlmgr: package repository $location\n");
-+}
-
-+sub setup_one_remotetlpdb
-+{
-+ my $location = shift;
-+ my $remotetlpdb;
-+
-+ # TODO
-+ # check if that is already loaded!!!
-+
-+ # choose a mirror if we are asked.
-+ if ($location =~ m/^ctan$/i) {
-+ $location = give_ctan_mirror();
-+ } elsif ($location =~ m,^$TeXLiveServerURL,) {
-+ my $mirrorbase = TeXLive::TLUtils::give_ctan_mirror_base();
-+ $location =~ s,^$TeXLiveServerURL,$mirrorbase,;
-+ }
-+
- # if we talk about a net location try to download the hash of the tlpdb
- # - if that is possible, check for the locally saved file and if the hash
- # agrees load the local copy if present instead of the remote one,
-@@ -4632,8 +4874,30 @@
- close($tlfh);
- }
- }
-+
-+ return($remotetlpdb);
- }
-
-+sub read_pinning_file {
-+ my $pf = shift;
-+ my @pins;
-+ my $pfh;
-+ if (!open($pfh, "<$pf")) {
-+ tlwarn("Pinning file $pf cannot be read: $!\n");
-+ return;
-+ }
-+ debug("Reading pinning file $pf\n");
-+ while (my $l = TeXLive::TLUtils::get_full_line($pfh)) {
-+ chomp($l);
-+ # comments and empty lines are allowed
-+ next if ($l =~ m/^\s*#/);
-+ next if ($l =~ m/^\s*$/);
-+ my ($a, $b) = split(/:/, $l);
-+ push @pins, $remotetlpdb->make_pin_data_from_line($l);
-+ }
-+ close($pfh);
-+ return @pins;
-+}
-
-
- # finish handles the -pause option (wait for input from stdin),