diff options
Diffstat (limited to 'Master/tlpkg/archive/download-package-repository')
-rw-r--r-- | Master/tlpkg/archive/download-package-repository | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/Master/tlpkg/archive/download-package-repository b/Master/tlpkg/archive/download-package-repository new file mode 100644 index 00000000000..f2a9b057f35 --- /dev/null +++ b/Master/tlpkg/archive/download-package-repository @@ -0,0 +1,201 @@ +#!/usr/bin/env perl + +# +# Originally written by T.M.Trzeciak in 2010 +# +# Purpose: create/update a local package repository +# How to use: place it tlpkg/installer and run +# + +our $Master; +our $location; + +BEGIN { + $^W = 1; + $Master = __FILE__; + $Master =~ s;\\;/;g if ($^O =~ /^MSWin/i); + $Master =~ s;[^/]*$;../..; unless ($Master =~ s;(/[^/]*){3,3}$;;); + unshift (@INC, "$Master/tlpkg"); + $::installerdir = $Master; + $::localrepo = $Master; + # $::localrepo = '.'; + # $Master = $ENV{"TLINSTALLERDIR"}; + # print "$Master\n"; +} + +use TeXLive::TLPDB; +use TeXLive::TLPOBJ; +use TeXLive::TLConfig; +use TeXLive::TLUtils; +use TeXLive::TLDownload; +use Getopt::Long; +use Pod::Usage; +use File::Path; +use Cwd; + +TeXLive::TLUtils::process_logging_options(); + +my $opt_location; +my $opt_destination; +my $opt_persistent_downloads = 1; +my $opt_help = 0; + +GetOptions( + "location|url|repository|repo=s" => \$opt_location, + # "destination=s" => \$opt_destination, + "persistent-downloads!" => \$opt_persistent_downloads, + "h|help|?" => \$opt_help) or pod2usage(1); +if ($opt_help) { + my @noperldoc = ("-noperldoc", "1") if ($^O =~ /^MSWin/i); + pod2usage(-exitstatus => 0, -verbose => 2, @noperldoc); +} + +exit(&main()); + +sub main { + if ( !setup_programs( "$::installerdir/$InfraLocation/installer", + TeXLive::TLUtils::platform() ) ) { + die "$0: failed to set up necessary programs.\n"; + } + if ($opt_persistent_downloads) { + TeXLive::TLUtils::setup_persistent_downloads() ; + } + $location = defined($opt_location) ? $opt_location : + TeXLive::TLUtils::give_ctan_mirror(); + if (!defined($location)) { + die("$0: failed to obtain repository location.\n"); + } + $::localrepo = $opt_destination if defined($opt_destination); + if ( $location eq $::localrepo ) { + die "destination and remote repository cannot be the same: $location"; + } + + info("Cloning package repository from $location\n"); + $::archivedir = "__ARCHIVE__"; + if (-d "$::localrepo/$Archive") { + rename("$::localrepo/$Archive", "$::localrepo/$::archivedir") || + die "unable to rename $::localrepo/$Archive to $::archivedir: $!"; + } + if (!-d "$::localrepo/$::archivedir") { + mkdir("$::localrepo/$::archivedir") || + die "$0: could not create directory $::localrepo/$::archivedir: $!"; + } + if (!-d "$::localrepo/$InfraLocation" ) { + mkdir("$::localrepo/$InfraLocation") || + die "$0: cannot create directory $::localrepo/$InfraLocation: $!"; + } + my $tlpdbfile = "$InfraLocation/$DatabaseName"; + my $tlpdbpacked = "$tlpdbfile.$DefaultContainerFormat"; + my $md5there; + download_file("$location/$tlpdbfile.md5", "$::localrepo/$tlpdbfile.md5"); + open MD5FILE, "$::localrepo/$tlpdbfile.md5" or + die "cannot open $::localrepo/$tlpdbfile.md5: $!"; + if (read (MD5FILE, $md5there, 32) != 32) { + die "cannot download remote TeX Live database from $location.\n"; + } + close MD5FILE; + my $md5here = (!-r "$::localrepo/$tlpdbfile") ? "" : + TeXLive::TLUtils::tlmd5("$::localrepo/$tlpdbfile"); + # debug("md5 hash mismatch\n") if ($md5there ne $md5here); + if ($md5there ne $md5here) { + download_file("$location/$tlpdbpacked", "$::localrepo/$tlpdbpacked"); + if ( system("$::progs{'xzdec'} <\"$::localrepo/$tlpdbpacked\" >\"$::localrepo/$tlpdbfile\"") ) { + die "cannot decompress $::localrepo/$tlpdbpacked\n"; + } + } + + my $tlpdb = TeXLive::TLPDB->new ("root" => $::localrepo); + if ( !defined($tlpdb) ) { + die "unusable repository database at $location\n"; + } + + my $error_count = 0; + for my $pkgname ($tlpdb->list_packages) { + next if $pkgname =~ /^00texlive/; + my $tlp = $tlpdb->get_package($pkgname); + $error_count += get_container("$pkgname", $tlp->containermd5() ); + $error_count += get_container("$pkgname.doc", $tlp->doccontainermd5() ) + if ($tlp->docfiles()); + $error_count += get_container("$pkgname.source", $tlp->srccontainermd5() ) + if ($tlp->srcfiles()); + } + if ($error_count == 0) { + rename("$::localrepo/$::archivedir", "$::localrepo/$Archive") || + die "unable to rename $::localrepo/$::archivedir to $Archive: $!"; + print("Pacakge repository cloning finished successfully.\n"); + return 0; + } else { + print("Pacakge repository cloning finished with errors.\n"); + print("Rerunning again might fix the problems.\n"); + return 1; + } + + sub get_container { + my ($pkgname, $md5there) = @_; + my $pkgcontainerfile = "$pkgname.$DefaultContainerExtension"; + my $localfile = "$::localrepo/$::archivedir/$pkgcontainerfile"; + my $remotefile = "$location/$Archive/$pkgcontainerfile"; + if (!-r "$localfile" || + TeXLive::TLUtils::tlmd5("$localfile") ne $md5there ) { + print("downloading $pkgname\n"); + download_file("$remotefile", "$localfile"); + # check downloaded file + my $md5here = TeXLive::TLUtils::tlmd5("$localfile"); + if ($md5here ne $md5there) { + warn("md5 sum mismatch for package $pkgname: + database: $md5there + dowloaded: $md5here\n"); + return 1; + } + return 0; + } + # info("package container up to date: $pkgcontainerfile\n"); + print("skipping $pkgname\n"); + return 0; + } + +} + +__END__ +=head1 NAME + +download-package-repository - creates a local package repository + +=head1 SYNOPSIS + +download-package-repository [OPTION]... + +=head1 OPTIONS + +=item B<-repository> I<url|path> +=item B<-persistent-downloads> +=item B<-no-persistent-downloads> + +See the tlmgr documentation (L<http://tug.org/texlive/tlmgr.html>) for +information. + +The standard options B<-help> and B<-q>, B<-v>, and +B<-logfile>=I<file> are accepted too; see the C<process_logging_options> +function in L<TeXLive::TLUtils> for details. + +=head1 DESCRIPTION + +This script is useful particularly on unstable Internet connections to +pre-download all packages before doing an installation. + +In general,it creates or updates a local package repository (within the +TL installer directories). The resulting local repository will be +picked up automatically by the installer as a default one. The new +repository is not enabled untill all packages have been downloaded and +verified. + +If the download is interrupted for any reason, just rerun this script +again to complete it. It will pick upwhere it left off. + +=head1 AUTHORS AND COPYRIGHT + +This script and its documentation were written for the TeX Live +distribution (L<http://tug.org/texlive>) and both are licensed under the +GNU General Public License Version 2 or later. + +=cut |