summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts
diff options
context:
space:
mode:
authorNorbert Preining <preining@logic.at>2013-04-13 05:32:44 +0000
committerNorbert Preining <preining@logic.at>2013-04-13 05:32:44 +0000
commit776874e7779ee459aecd4df8d2eddb68f492f17e (patch)
tree3365e588639069ebd6feab2ac8767ad53e4a1e33 /Master/texmf-dist/scripts
parentbdcdba5ebfbf898456bac0a46f10458b602673b5 (diff)
user mode for tlmgr
support a user mode for tlmgr that allows installation of packages into user trees. git-svn-id: svn://tug.org/texlive/trunk@29883 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts')
-rwxr-xr-xMaster/texmf-dist/scripts/texlive/tlmgr.pl253
1 files changed, 227 insertions, 26 deletions
diff --git a/Master/texmf-dist/scripts/texlive/tlmgr.pl b/Master/texmf-dist/scripts/texlive/tlmgr.pl
index 9252b732658..3dac77e69e5 100755
--- a/Master/texmf-dist/scripts/texlive/tlmgr.pl
+++ b/Master/texmf-dist/scripts/texlive/tlmgr.pl
@@ -133,6 +133,8 @@ sub main {
"no-execute-actions" => 1,
"pin-file" => "=s",
"pause" => 1,
+ "usermode" => 1,
+ "usertree" => "=s",
"print-platform|print-arch" => 1,
"version" => 1,
"help" => 1,
@@ -387,13 +389,30 @@ for the full story.\n";
pod2usage(-msg => $msg, -exitstatus => 1, -verbose => 1, @noperldoc);
}
+ #
+ # the main tree we will be working on
+ $::maintree = $Master;
+ if ($opts{"usermode"}) {
+ # we could also try to detect that we don't have write permissions
+ # and switch to user mode automatically
+ if (defined($opts{"usertree"})) {
+ $::maintree = $opts{"usertree"};
+ } else {
+ chomp($::maintree = `kpsewhich -var-value TEXMFHOME`);
+ }
+ }
+
# besides doing normal logging if -logfile is specified, we try to log
# package related actions (install, remove, update) to
# the package-log file TEXMFSYSVAR/web2c/tlmgr.log
$packagelogged = 0; # how many msgs we logged
chomp (my $texmfsysvar = `kpsewhich -var-value=TEXMFSYSVAR`);
$packagelogfile = $opts{"package-logfile"};
- $packagelogfile ||= "$texmfsysvar/web2c/tlmgr.log";
+ if ($opts{"usermode"}) {
+ $packagelogfile ||= "$::maintree/web2c/tlmgr.log";
+ } else {
+ $packagelogfile ||= "$texmfsysvar/web2c/tlmgr.log";
+ }
#
# Try to open the packagelog file, but do NOT die when that does not work
if (!open(PACKAGELOG, ">>$packagelogfile")) {
@@ -575,6 +594,9 @@ sub execute_action {
} elsif ($action =~ m/^info$/i) {
action_info(@ARGV);
finish(0);
+ } elsif ($action =~ m/^init-usertree$/i) {
+ action_init_usertree();
+ finish(0);
} elsif ($action =~ m/^remove$/i) {
action_remove();
} elsif ($action =~ /^paper$/) {
@@ -644,6 +666,8 @@ sub handle_execute_actions
{
my $errors = 0;
+ my $sysmode = ($opts{"usermode"} ? "" : "-sys");
+
if ($::files_changed) {
$errors += do_cmd_and_check("mktexlsr");
if (defined($localtlpdb->get_package('context'))) {
@@ -671,7 +695,7 @@ sub handle_execute_actions
my $dest = "$TEXMFDIST/web2c/updmap.cfg";
TeXLive::TLUtils::create_updmap($localtlpdb, $dest);
}
- $errors += do_cmd_and_check("updmap-sys") if $updmap_run_needed;
+ $errors += do_cmd_and_check("updmap$sysmode") if $updmap_run_needed;
}
# format relevant things
@@ -769,7 +793,7 @@ sub handle_execute_actions
# first regenerate all formats --byengine
for my $e (keys %updated_engines) {
log ("updating formats based on $e\n");
- $errors += do_cmd_and_check("fmtutil-sys --no-error-if-no-format --byengine $e");
+ $errors += do_cmd_and_check("fmtutil$sysmode --no-error-if-no-format --byengine $e");
}
# now rebuild all other formats
for my $f (keys %do_enable) {
@@ -777,7 +801,7 @@ sub handle_execute_actions
# ignore disabled formats
next if !$::execute_actions{'enable'}{'formats'}{$f}{'mode'};
log ("(re)creating format dump $f\n");
- $errors += do_cmd_and_check("fmtutil-sys --byfmt $f");
+ $errors += do_cmd_and_check("fmtutil$sysmode --byfmt $f");
$done_formats{$f} = 1;
}
}
@@ -797,7 +821,7 @@ sub handle_execute_actions
}
if ($localtlpdb->option("create_formats")
&& !$::regenerate_all_formats) {
- $errors += do_cmd_and_check("fmtutil-sys --byhyphen $lang");
+ $errors += do_cmd_and_check("fmtutil$sysmode --byhyphen $lang");
}
}
}
@@ -806,7 +830,7 @@ sub handle_execute_actions
#
if ($::regenerate_all_formats) {
info("Regenerating all formats, this may take some time ...");
- $errors += do_cmd_and_check("fmtutil-sys --all");
+ $errors += do_cmd_and_check("fmtutil$sysmode --all");
info("done\n");
$::regenerate_all_formats = 0;
}
@@ -975,8 +999,13 @@ sub action_remove {
#
sub action_paper {
init_local_db();
- chomp(my $texmfsysconfig = `kpsewhich -var-value=TEXMFSYSCONFIG`);
- $ENV{"TEXMFCONFIG"} = $texmfsysconfig;
+ my $texmfconfig;
+ if ($opts{"usermode"}) {
+ chomp($texmfconfig = `kpsewhich -var-value=TEXMFCONFIG`);
+ } else {
+ chomp($texmfconfig = `kpsewhich -var-value=TEXMFSYSCONFIG`);
+ }
+ $ENV{"TEXMFCONFIG"} = $texmfconfig;
my $action = shift @ARGV;
if ($action =~ m/^paper$/i) { # generic paper
@@ -988,7 +1017,7 @@ sub action_paper {
"as in: tlmgr pdftex paper --list\n");
} elsif (!defined($newpaper)) { # tlmgr paper => show all current sizes.
- TeXLive::TLPaper::paper_all($texmfsysconfig,undef);
+ TeXLive::TLPaper::paper_all($texmfconfig,undef);
} elsif ($newpaper !~ /^(a4|letter)$/) { # tlmgr paper junk => complain.
$newpaper = "the empty string" if !defined($newpaper);
@@ -996,7 +1025,7 @@ sub action_paper {
} else { # tlmgr paper {a4|letter} => do it.
return if !check_on_writable();
- TeXLive::TLPaper::paper_all($texmfsysconfig,$newpaper);
+ TeXLive::TLPaper::paper_all($texmfconfig,$newpaper);
}
} else { # program-specific paper
@@ -1013,7 +1042,7 @@ sub action_paper {
return if !check_on_writable();
}
unshift(@ARGV, "--list") if $opts{"list"};
- TeXLive::TLPaper::do_paper($prog,$texmfsysconfig,@ARGV);
+ TeXLive::TLPaper::do_paper($prog,$texmfconfig,@ARGV);
}
}
@@ -1021,6 +1050,10 @@ sub action_paper {
# PATH
#
sub action_path {
+ if ($opts{"usermode"}) {
+ tlwarn("action `path' not supported in usermode!\n");
+ exit 1;
+ }
my $what = shift @ARGV;
if (!defined($what) || ($what !~ m/^(add|remove)$/i)) {
$what = "" if ! $what;
@@ -1277,6 +1310,7 @@ sub action_info {
print "longdesc: ", $tlp->longdesc, "\n" if ($tlp->longdesc);
print "installed: ", ($installed ? "Yes" : "No"), "\n";
print "revision: ", $tlp->revision, "\n" if ($installed);
+ print "relocatable: ", ($tlp->relocated ? "Yes" : "No"), "\n";
print "cat-version: ", $tlp->cataloguedata->{'version'}, "\n"
if $tlp->cataloguedata->{'version'};
print "cat-date: ", $tlp->cataloguedata->{'date'}, "\n"
@@ -2318,7 +2352,10 @@ sub action_update {
# check for updates to tlmgr and die unless either --force or --list or --self
# is given
- my @critical = check_for_critical_updates($localtlpdb, $remotetlpdb);
+ my @critical;
+ if (!$opts{"usermode"}) {
+ @critical = check_for_critical_updates($localtlpdb, $remotetlpdb);
+ }
my $dry_run_cont = $opts{"dry-run"} && ($opts{"dry-run"} < 0);
if ( !$dry_run_cont && !$opts{"self"} && @critical) {
critical_updates_warning();
@@ -3270,16 +3307,18 @@ sub action_install {
init_tlmedia_or_die();
# check for updates to tlmgr itself, and die unless --force is given
- if (check_for_critical_updates( $localtlpdb, $remotetlpdb)) {
- critical_updates_warning();
- if ($opts{"force"}) {
- tlwarn("Continuing due to --force\n");
- } else {
- if ($::gui_mode) {
- # return here and don't do any updates
- return;
+ if (!$opts{"usermode"}) {
+ if (check_for_critical_updates( $localtlpdb, $remotetlpdb)) {
+ critical_updates_warning();
+ if ($opts{"force"}) {
+ tlwarn("Continuing due to --force\n");
} else {
- die "tlmgr: Not continuing, please see warning above!\n";
+ if ($::gui_mode) {
+ # return here and don't do any updates
+ return;
+ } else {
+ die "tlmgr: Not continuing, please see warning above!\n";
+ }
}
}
}
@@ -3298,7 +3337,7 @@ sub action_install {
@packs = $remotetlpdb->expand_dependencies("-only-arch", $localtlpdb, @ARGV) unless $opts{"no-depends-at-all"};
# now expand all others unless $opts{"no-depends"}
# if $opts{"reinstall"} do not collection->collection dependencies
- if ($opts{"reinstall"}) {
+ if ($opts{"reinstall"} || $opts{"usermode"}) {
@packs = $remotetlpdb->expand_dependencies("-no-collections", $localtlpdb, @packs) unless $opts{"no-depends"};
} else {
@packs = $remotetlpdb->expand_dependencies($localtlpdb, @packs) unless $opts{"no-depends"};
@@ -3379,6 +3418,15 @@ sub action_install {
foreach my $pkg (@todo) {
my $flag = $FLAG_INSTALL;
my $re = "";
+ my $tlp = $remotetlpdb->get_package($pkg);
+ if (!defined($tlp)) {
+ info("Unknown package $pkg\n");
+ next;
+ }
+ if (!$tlp->relocated && $opts{"usermode"}) {
+ info("Package $pkg is not relocatable, cannot install it in user mode!\n");
+ next;
+ }
if (defined($localtlpdb->get_package($pkg))) {
if ($opts{"reinstall"}) {
$re = "re";
@@ -3986,11 +4034,11 @@ sub action_option {
# now also save the TLPOBJ of 00texlive.installation
my $tlpo = $localtlpdb->get_package("00texlive.installation");
if ($tlpo) {
- if (open(TOFD, ">$Master/tlpkg/tlpobj/00texlive.installation.tlpobj")) {
+ if (open(TOFD, ">$::maintree/tlpkg/tlpobj/00texlive.installation.tlpobj")) {
$tlpo->writeout(\*TOFD);
close(TOFD);
} else {
- tlwarn("Cannot save 00texlive.installation to $Master/tlpkg/tlpobj/00texlive.installation.tlpobj\n");
+ tlwarn("Cannot save 00texlive.installation to $::maintree/tlpkg/tlpobj/00texlive.installation.tlpobj\n");
}
}
} else {
@@ -4023,6 +4071,10 @@ sub action_platform {
warn("action `platform' not supported on Windows\n");
return();
}
+ if ($opts{"usermode"}) {
+ tlwarn("action `platform' not supported in usermode\n");
+ exit 1;
+ }
my $what = shift @ARGV;
init_local_db(1);
info("platform: dry run, no changes will be made\n") if $opts{"dry-run"};
@@ -4174,6 +4226,10 @@ sub action_platform {
# GENERATE
#
sub action_generate {
+ if ($opts{"usermode"}) {
+ tlwarn("action `generate' not supported in usermode!\n");
+ exit 1;
+ }
my $what = shift @ARGV;
init_local_db();
@@ -5055,6 +5111,37 @@ sub action_postaction {
}
}
+# INIT USER TREE
+# sets up the user tree for tlmgr in user mode
+sub action_init_usertree {
+ init_local_db();
+ my $tlpdb = TeXLive::TLPDB->new;
+ my $usertree;
+ if ($opts{"usertree"}) {
+ $usertree = $opts{"usertree"};
+ } else {
+ chomp($usertree = `kpsewhich -var-value TEXMFHOME`);
+ }
+ if (-r "$usertree/$InfraLocation/$DatabaseName") {
+ tldie("$prg: user mode database already set up in\n$prg: $usertree/$InfraLocation/$DatabaseName\n$prg: not overwriting it.\n");
+ }
+ $tlpdb->root($usertree);
+ # copy values from main installation over
+ my $maininsttlp = $localtlpdb->get_package("00texlive.installation");
+ my $inst = $maininsttlp->copy;
+ $tlpdb->add_tlpobj($inst);
+ # remove all available architectures
+ $tlpdb->setting( "available_architectures", "");
+ # specify that we are in user mode
+ $tlpdb->setting( "usertree", 1 );
+ $tlpdb->save;
+ #
+ # we need to create web2c dir for TLMedia to succeed setting up
+ # and for tlmgr.log file
+ mkdir ("$usertree/web2c");
+ mkdir ("$usertree/tlpkg/tlpobj");
+}
+
# CONF
# tries to mimic texconfig conf but can also set values for both tlmgr
# and texmf conf files.
@@ -5178,8 +5265,8 @@ sub init_local_db {
# to make sure that the settings in the local tlpdb do not overwrite
# stuff changed via the GUI
return if defined $localtlpdb;
- $localtlpdb = TeXLive::TLPDB->new ( root => $Master );
- die("cannot setup TLPDB in $Master") unless (defined($localtlpdb));
+ $localtlpdb = TeXLive::TLPDB->new ( root => $::maintree );
+ die("cannot setup TLPDB in $::maintree") unless (defined($localtlpdb));
# setup the programs, for w32 we need the shipped wget/xz etc, so we
# pass the location of these files to setup_programs.
if (!setup_programs("$Master/tlpkg/installer", $localtlpdb->platform)) {
@@ -5747,6 +5834,7 @@ sub packagecmp {
}
sub check_on_writable {
+ return 1 if $opts{"usermode"};
if (!TeXLive::TLUtils::dir_writable("$Master/tlpkg")) {
tlwarn("You don't have permission to change the installation in any way,\n");
tlwarn("specifically, the directory $Master/tlpkg/ is not writable.\n");
@@ -5921,6 +6009,15 @@ In GUI mode, this switch makes C<tlmgr> report any missing, or more
likely untranslated, messages to standard error. This can help
translators to see what remains to be done.
+=item B<--usermode>
+
+Activates the user mode, see L<USER MODE> below.
+
+=item B<--usertree> I<dir>
+
+Uses I<dir> as user tree in user mode, seel L<USER MODE> below.
+
+
=back
The standard options for TeX Live programs are also accepted:
@@ -6973,6 +7070,110 @@ If the package on the server is older than the package already installed
downgrade. Also, packages for uninstalled platforms are not installed.
+
+=head2 init-usertree
+
+sets up the default user tree (C<TEXMFHOME>) or the one specified
+on the command line using C<--usertree> for user mode management.
+See L<USER MODE> below.
+
+
+=head1 USER MODE
+
+B<WARNING> B<WARNING> B<WARNING>
+This is very much work in progress
+and experimental. Expect breakage, and the need to reinstall your
+user tree a new.
+
+C<tlmgr> provides a restricted way to manage arbitrary texmf trees
+in the same way as the installation. This allows a user without write
+permissions to the installation location to update/install packages
+into a user tree.
+
+C<tlmgr> is set into user mode by giving the command line option
+C<--usermode>. It will not switch automatically, nor does it support
+a config file by now. Thus, this option has to be given every time.
+
+This mode of C<tlmgr> works on a user tree, which by default will be
+the value of C<TEXMFHOME>, but can be overridden with the command line
+option C<--usertree>. In the following when we speak of the user tree
+we mean either C<TEXMFHOME> or the one given on the command line.
+
+Not all actions are allowed in user mode, C<tlmgr> will warn you and
+not carry out this action. The actions of C<tlmgr> can be classified into
+those that don't need write permissions and thus are working the same
+in user mode or normal mode. Currently these are
+B<help>, B<version>, B<search>, B<show>, B<list>, B<check>, B<print-arch>.
+
+Most of the actions dealing with package management on the other hand
+need write permissions, and behave differently:
+B<install>, B<update>, B<remove>, B<option>, B<paper>, B<generate>,
+B<backup>, B<restore>, B<uninstall>, B<symlinks>.
+
+Currently not supported (and probably will never be) is the B<arch>
+action.
+
+As for the B<gui> action it is currently not supported, but might be
+in future.
+
+Before using C<tlmgr> in user mode, you have to set up the user tree
+with the B<init-usertree> action. This will create C<USERTREE/web2c>,
+C<USERTREE/tlpkg/tlpobj> and set up a minimal C<USERTREE/tlpkg/texlive.tlpdb>.
+From then on you can use the supported actions as normal by adding
+the C<--usermode> command line switch.
+
+In user mode the file C<USERTREE/tlpkg/texlive.tlpdb> contains only the
+packages that have been installed into the user tree C<USERTREE> using
+C<tlmgr>, plus additional options in the virtual package
+00texlive.installation (like with the main installation's texlive.tlpdb).
+
+All actions on packages in user mode can only be carried out on packages
+that are marked as B<relocatable>. Basically that means that the contained
+files all reside in the C<texmd-dist> tree. B<NOTE> That already excludes
+all binary packages! Of the currently about 1900 packages the majority,
+currently about 1750, are relocatable, i.e., they can be installed into
+a user tree.
+
+Description of changes of actions in user mode:
+
+=head2 install
+
+in usermode the tlmgr action install will check that the package
+and all depending packages are either all relocated, or those that
+are not relocated are already installed in the system installation.
+If this is true it will unpack all containers to be installed into
+the user tree (TEXMFHOME or the value of --user-tree) and add the
+respective packages to the user texlive.tlpdb (creating it if there
+has non be created till now).
+
+Currently installing a collection installs all depending packages,
+but in contrast to normal mode does not install depending collections.
+So in *normal* mode tlmgr install collection-context would install
+collection-metapost, c-basic, c-documentation-base, too. In *usermode*
+only the packages mentioned in collection-context are installed.
+
+=head2 backup, restore, remove, update
+
+in usermode the tlmgr action update will check that all packages
+to be updated are installed in the user tree, otherwise it behaves
+exactely like the system tlmgr.
+
+=head2 option
+
+only acts upon the user's texlive.tlpdb
+
+=head2 paper
+
+changes configuration files in user tree
+
+=head2 generate
+
+creates configuration files in user tree
+
+B<WARNING WARNING WARNING> Be again warned that this is very experimental!
+
+
+
=head1 TLMGR CONFIGURATION FILE
A small subset of the command line options can be set in a config file