diff options
author | Norbert Preining <preining@logic.at> | 2009-08-25 09:41:44 +0000 |
---|---|---|
committer | Norbert Preining <preining@logic.at> | 2009-08-25 09:41:44 +0000 |
commit | 16e3c94d7360d4ad8d5106fadc3fabfbc797bf02 (patch) | |
tree | 95dcd72b88cccffb280e30a306bd696a06c927ef /Master | |
parent | ab85c7eb4fde78db5439fe75ae612246064c77fc (diff) |
add progress bars for tlmgr install and tlmgr update,
separate out the time estimation code and reuse it
git-svn-id: svn://tug.org/texlive/trunk@14854 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rwxr-xr-x | Master/texmf/scripts/texlive/tlmgr.pl | 119 | ||||
-rw-r--r-- | Master/tlpkg/TeXLive/TLUtils.pm | 77 |
2 files changed, 149 insertions, 47 deletions
diff --git a/Master/texmf/scripts/texlive/tlmgr.pl b/Master/texmf/scripts/texlive/tlmgr.pl index aa5cf5312d6..197df381139 100755 --- a/Master/texmf/scripts/texlive/tlmgr.pl +++ b/Master/texmf/scripts/texlive/tlmgr.pl @@ -5,9 +5,6 @@ # This file is licensed under the GNU General Public License version 2 # or any later version. # -# TODO: -# - tlmgr should have a "progress" bar for the update --all and install -# etc options, echoing number of total packages etc etc. my $svnrev = '$Revision$'; my $datrev = '$Date$'; @@ -102,6 +99,8 @@ our $FLAG_FORCIBLE_REMOVED = "f"; our $FLAG_UPDATE = "u"; our $FLAG_REVERSED_UPDATE = "r"; our $FLAG_AUTOINSTALL = "a"; +our $FLAG_INSTALL = "i"; +our $FLAG_REINSTALL = "I"; # option variables $::gui_mode = 0; @@ -256,7 +255,7 @@ sub main { # --machine-readable is only supported by update. # - if ($::machinereadable && $action ne "update") { + if ($::machinereadable && $action ne "update" && $action ne "install") { tlwarn("tlmgr: --machine-readable output not supported for $action\n"); } @@ -1771,6 +1770,10 @@ sub action_update { } + my $starttime = time(); + my $donesize = 0; + my $totalsize = $sizes{'__TOTAL__'}; + # install all the new packages first my @new_packs; my @new_colls; @@ -1798,16 +1801,22 @@ sub action_update { next; } my $mediarev = $mediatlp->revision; + my ($estrem, $esttot); + if (!$opts{"list"}) { + ($estrem, $esttot) = TeXLive::TLUtils::time_estimate($totalsize, + $donesize, $starttime); + } if ($::machinereadable) { - machine_line($pkg, $FLAG_AUTOINSTALL, "-", $mediatlp->revision, $sizes{$pkg}); + machine_line($pkg, $FLAG_AUTOINSTALL, "-", $mediatlp->revision, $sizes{$pkg}, $estrem, $esttot); } else { if ($opts{"list"}) { info("$pkg: local: <absent>, source: " . $mediatlp->revision . " (auto-install)\n"); } else { - info("[$currnr/$totalnr] auto-install: $pkg\n"); + info("[$currnr/$totalnr, $estrem/$esttot] auto-install: $pkg\n"); } } $currnr++; + $donesize += $sizes{$pkg}; next if ($opts{"dry-run"} || $opts{"list"}); if ($tlmediasrc->install_package($pkg, $localtlpdb)) { # installation succeeded because we got a reference @@ -1878,12 +1887,20 @@ sub action_update { } } + my ($estrem, $esttot); + if (!$opts{"list"}) { + ($estrem, $esttot) = TeXLive::TLUtils::time_estimate($totalsize, + $donesize, $starttime); + } + if ($::machinereadable) { - machine_line($pkg, $FLAG_UPDATE, $rev, $mediarev, $sizes{$pkg}); + machine_line($pkg, $FLAG_UPDATE, $rev, $mediarev, $sizes{$pkg}, $estrem, $esttot); } else { - info("[$currnr/$totalnr] update: $pkg ($rev -> $mediarev)"); + info("[$currnr/$totalnr, $estrem/$esttot] update: $pkg ($rev -> $mediarev)"); } + $donesize += $sizes{$pkg}; $currnr++; + if ($opts{"dry-run"}) { info("\n") unless $::machinereadable; $updated{$pkg} = 1; @@ -2118,21 +2135,72 @@ sub action_install { } } @inst_packs = sort packagecmp @inst_packs; - foreach my $pkg (@inst_packs, @inst_colls, @inst_schemes) { + + my $starttime = time(); + # count packages + my $totalnr = 0; + my %revs; + my @todo; + for my $pkg (@inst_packs, @inst_colls, @inst_schemes) { + my $pkgrev = 0; + my $mediatlp = $tlmediatlpdb->get_package($pkg); + if (!defined($mediatlp)) { + tlwarn("package $pkg not present at installation location.\n"); + next; + } + if (defined($localtlpdb->get_package($pkg))) { + if ($opts{"reinstall"}) { + $totalnr++; + $revs{$pkg} = $mediatlp->revision; + push @todo, $pkg; + } else { + debug("already installed: $pkg\n"); + } + } else { + $totalnr++; + $revs{$pkg} = $mediatlp->revision; + push @todo, $pkg; + } + } + # return if there is nothing to install! + return if (!@todo); + + my $currnr = 1; + my %sizes = %{$tlmediatlpdb->sizes_of_packages( + $localtlpdb->option("install_srcfiles"), + $localtlpdb->option("install_docfiles"), @todo)}; + defined($sizes{'__TOTAL__'}) || ($sizes{'__TOTAL__'} = 0); + my $totalsize = $sizes{'__TOTAL__'}; + my $donesize = 0; + + print "total-bytes\t$sizes{'__TOTAL__'}\n" if $::machinereadable; + print "end-of-header\n" if $::machinereadable; + + foreach my $pkg (@todo) { + my $flag = $FLAG_INSTALL; my $re = ""; if (defined($localtlpdb->get_package($pkg))) { if ($opts{"reinstall"}) { $re = "re"; + $flag = $FLAG_REINSTALL; } else { - debug("already installed: $pkg\n"); + debug("already installed (but didn't we say that already?): $pkg\n"); next; } } - info("${re}install: $pkg\n"); + my ($estrem, $esttot) = TeXLive::TLUtils::time_estimate($totalsize, + $donesize, $starttime); + if ($::machinereadable) { + machine_line($pkg, $flag, "-", $revs{$pkg}, $sizes{$pkg}, $estrem, $esttot); + } else { + info("[$currnr/$totalnr, $estrem/$esttot] ${re}install: $pkg\n"); + } if (!$opts{"dry-run"}) { $tlmediasrc->install_package($pkg, $localtlpdb); logpackage("${re}install: $pkg"); } + $donesize += $sizes{$pkg}; + $currnr++; } if ($opts{"dry-run"}) { # stop here, don't do any postinstall actions @@ -4458,13 +4526,15 @@ messages for human consumption are written to stderr (normally they are written to stdout). The idea is that a program can get all the information it needs by reading stdout. -Currently this option only applies to the L<update|/"update -[I<option>]... [I<pkg>]..."> action. The output format is as follows: +Currently this option only applies to the +L<update|/"update [I<option>]... [I<pkg>]..."> and +L<install|"install [I<option>]... I<pkg>..."> actions. +The output format is as follows: fieldname "\t" value ... "end-of-header" - pkgname status localrev serverrev size + pkgname status localrev serverrev size estrem esttot ... "end-of-updates" other output from post actions, not in machine readable form @@ -4477,7 +4547,9 @@ The I<localrev> and I<serverrev> fields for each package are the revision numbers in the location installation and server repository, respectively. The I<size> field is the number of bytes to be downloaded, i.e., the size of the compressed tar file for a network -installation, not the unpacked size. +installation, not the unpacked size. The estrem and esttot fields +are only present for updated and auto-install packages, and contain +the estimated remaining time and the estimated total time. Line endings may be either LF or CRLF depending on the current platform. @@ -4540,6 +4612,15 @@ version on the server. Automatically-determined need for installation, the package is new on the server and is (most probably) part of an installed collection. +=item C<i> + +Package will be installed and isn't present in the local installation +(action install). + +=item C<I> + +Package is already present but will be reinstalled (action install). + =back =item I<localrev> @@ -4557,6 +4638,14 @@ present on the server. The size in bytes of the package on the server. The sum of all the package sizes is given in the C<total-bytes> header field mentioned above. +=item I<estrem> + +The estimated remaining time. + +=item I<esttot> + +The estimated total time. + =back If you are developing a program that uses this output, and find that diff --git a/Master/tlpkg/TeXLive/TLUtils.pm b/Master/tlpkg/TeXLive/TLUtils.pm index 08ab4571272..84c99221002 100644 --- a/Master/tlpkg/TeXLive/TLUtils.pm +++ b/Master/tlpkg/TeXLive/TLUtils.pm @@ -69,6 +69,7 @@ C<TeXLive::TLUtils> -- utilities used in the TeX Live infrastructure TeXLive::TLUtils::create_updmap($tlpdb,$dest,$localconf); TeXLive::TLUtils::create_language_dat($tlpdb,$dest,$localconf); TeXLive::TLUtils::create_language_def($tlpdb,$dest,$localconf); + TeXLive::TLUtils::time_estimate($totalsize, $donesize, $starttime) TeXLive::TLUtils::install_packages($from_tlpdb,$media,$to_tlpdb,$what,$opt_src, $opt_doc)>); TeXLive::TLUtils::install_package($what, $filelistref, $target, $platform); TeXLive::TLUtils::do_postaction($how, $tlpobj, $do_fileassocs, $do_shortcuts, $do_script); @@ -146,6 +147,7 @@ BEGIN { &w32_add_to_path &w32_remove_from_path &tlcmp + &time_estimate ); @EXPORT = qw(setup_programs download_file process_logging_options tldie tlwarn info log debug ddebug dddebug debug_hash @@ -1039,6 +1041,47 @@ sub removed_dirs return keys %removed_dirs; } +=item C<time_estimate($totalsize, $donesize, $starttime)> + +Returns the estimated remaining and estimated total time +based on the total size, the already done size, and the start time. + +=cut + +sub time_estimate { + my ($totalsize, $donesize, $starttime) = @_; + if ($donesize <= 0) { + return ("??:??", "??:??"); + } + my $curtime = time(); + my $passedtime = $curtime - $starttime; + my $esttotalsecs = int ( ( $passedtime * $totalsize ) / $donesize ); + my $remsecs = $esttotalsecs - $passedtime; + my $min = int($remsecs/60); + my $hour; + if ($min >= 60) { + $hour = int($min/60); + $min %= 60; + } + my $sec = $remsecs % 60; + $remtime = sprintf("%02d:%02d", $min, $sec); + if ($hour) { + $remtime = sprintf("%02d:$remtime", $hour); + } + my $tmin = int($esttotalsecs/60); + my $thour; + if ($tmin >= 60) { + $thour = int($tmin/60); + $tmin %= 60; + } + my $tsec = $esttotalsecs % 60; + $tottime = sprintf("%02d:%02d", $tmin, $tsec); + if ($thour) { + $tottime = sprintf("%02d:$tottime", $thour); + } + return($remtime, $tottime); +} + =item C<install_packages($from_tlpdb, $media, $to_tlpdb, $what, $opt_src, $opt_doc)> @@ -1095,39 +1138,9 @@ sub install_packages { my $tlpobj = $tlpobjs{$package}; my $reloc = $tlpobj->relocated; $n++; - my $remtime = "??:??"; - my $tottime = "??:??"; - if ($donesize > 0) { - # try to compute the remaining time - my $curtime = time(); - my $passedtime = $curtime - $starttime; - my $esttotalsecs = int ( ( $passedtime * $totalsize ) / $donesize ); - my $remsecs = $esttotalsecs - $passedtime; - my $min = int($remsecs/60); - my $hour; - if ($min >= 60) { - $hour = int($min/60); - $min %= 60; - } - my $sec = $remsecs % 60; - $remtime = sprintf("%02d:%02d", $min, $sec); - if ($hour) { - $remtime = sprintf("%02d:$remtime", $hour); - } - my $tmin = int($esttotalsecs/60); - my $thour; - if ($tmin >= 60) { - $thour = int($tmin/60); - $tmin %= 60; - } - my $tsec = $esttotalsecs % 60; - $tottime = sprintf("%02d:%02d", $tmin, $tsec); - if ($thour) { - $tottime = sprintf("%02d:$tottime", $thour); - } - } + my ($estrem, $esttot) = time_estimate($totalsize, $donesize, $starttime); my $infostr = sprintf("Installing [%0${td}d/$totalnr, " - . "time/total: $remtime/$tottime]: $package [%dk]", + . "time/total: $estrem/$esttot]: $package [%dk]", $n, int($tlpsizes{$package}/1024) + 1); info("$infostr\n"); foreach my $h (@::install_packages_hook) { |