diff options
author | Norbert Preining <preining@logic.at> | 2008-10-26 22:25:58 +0000 |
---|---|---|
committer | Norbert Preining <preining@logic.at> | 2008-10-26 22:25:58 +0000 |
commit | e529fec5f79d90dd50669f1a5b47a4f061cdaf52 (patch) | |
tree | 3e69933ab8c79c33b8b98a6773c81570cc57c052 /Master/tlpkg | |
parent | 79efd4658611e6110d8d4ab3ee435d7667c3d828 (diff) |
add two patches, see separate email and header of the patches
git-svn-id: svn://tug.org/texlive/trunk@11072 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg')
-rw-r--r-- | Master/tlpkg/etc/auto-backup-feature.patch | 276 | ||||
-rw-r--r-- | Master/tlpkg/etc/use-autopatterns-from-dedicated-tlpsrc-files.patch | 362 |
2 files changed, 638 insertions, 0 deletions
diff --git a/Master/tlpkg/etc/auto-backup-feature.patch b/Master/tlpkg/etc/auto-backup-feature.patch new file mode 100644 index 00000000000..51493fd227b --- /dev/null +++ b/Master/tlpkg/etc/auto-backup-feature.patch @@ -0,0 +1,276 @@ +Implement automatic backups +Current status: + tlmgr option backupdir ..... +sets the defalt backup dir. Now tlmgr update can take another argument + tlmgr update --backup .... +which creates backups in the default backupdir as specified in the TLPDB. + +Furthermore, if the tlpdb opion autobackup is set to a integer >= -1 the +following happens (all of them need the option backupdir set to an +existing directory) + tlmgr option autobackup -1 + always make backups, keep infinitely many + tlmgr option autobackup 0 + disable automatic backups + tlmgr option autobackup N + for N > 0 keep N backups + + +So if you want to set up automatic backups, do: + mkdir /var/cache/texlive-backups + tlmgr option backupdir /var/cache/texlive-backups/ + tlmgr option autobackup 5 + +TODO: +- tlmgr backup clean + necessary? can be done by hand. But since the code is here ... +- testing on windows +- documentation in POD format +- testing with .doc/.src args, and with .ARCH packages, no idea + what is going on there + + +Index: texmf/scripts/texlive/tlmgr.pl +=================================================================== +--- texmf/scripts/texlive/tlmgr.pl (revision 11059) ++++ texmf/scripts/texlive/tlmgr.pl (working copy) +@@ -34,6 +34,16 @@ + # - always do backups, let the user clean them up manually + # Possibly, an operation like 'tlmgr clean' for cleaning old backup could + # be great. ++# format for the options: ++# option backupdir ++# option autobackup/TIME ++# where TIME = natural number N -> keep N backups per package ++# or = 0 -> don't do auto backups ++# or = -1 (= +\infty) keep backup indefinitely ++# or = Nd | Nw | Nm -> keeping backups younger then ++# Nd N days ++# Nw N weeks ++# Nm N months + # - 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 +@@ -112,7 +122,7 @@ + "gui-lang=s" => \$opt_gui_lang, + "package-logfile=s" => \$opt_packagelogfile, + "version" => \$opt_version, +- "pause" => \$opt_pause, ++ "pause" => \$opt_pause, + "h|help|?" => \$opt_help) or pod2usage(2); + + my $action = shift; +@@ -909,6 +919,7 @@ + my $opt_list = 0; + my $opt_noremove = 0; + my $opt_backupdir; ++ my $opt_backup = 0; + Getopt::Long::Configure(@getopt_configure_subopts); + GetOptions("no-depends" => \$opt_nodepends, + "no-depends-at-all" => \$opt_reallynodepends, +@@ -916,6 +927,7 @@ + "list" => \$opt_list, + "no-remove" => \$opt_noremove, + "backupdir=s" => \$opt_backupdir, ++ "backup" => \$opt_backup, + "n|dry-run" => \$opt_dry) or pod2usage(2); + $opt_nodepends = 1 if $opt_reallynodepends; + my $nrupdated = 0; +@@ -925,6 +937,70 @@ + my $mediatlpdb = $tlmediasrc->tlpdb; + info("update: dry run, no changes will be made\n") if $opt_dry; + ++ # do backup dir checking now so that we don't run into troubles ++ # later, and exit if that doesn't work ++ if ($opt_backupdir) { ++ $opt_backupdir = abs_path($opt_backupdir); ++ if (! -d $opt_backupdir) { ++ tlwarn("Argument for --backupdir must be an existing directory. Terminating.\n"); ++ exit 1; ++ } ++ } ++ ++ my $autobackup = 0; ++ # check for the tlpdb option autobackup, and if present and true (!= 0) ++ # assume we are doing backups ++ if (!$opt_backup) { ++ $autobackup = $localtlpdb->option("autobackup"); ++ if ($autobackup) { ++ # check the format, we currently allow only natural numbers, and -1 ++ if ($autobackup eq "-1") { ++ debug ("Automatic backups activated, keeping \\infty backups.\n"); ++ $opt_backup = 1; ++ } elsif ($autobackup eq "0") { ++ debug ("Automatic backups disabled.\n"); ++ } elsif ($autobackup =~ m/^[0-9]+$/) { ++ debug ("Automatic backups activated, keeping $autobackup backups.\n"); ++ $opt_backup = 1; ++ } else { ++ tlwarn ("Option autobackup can only be an integer >= -1.\n"); ++ tlwarn ("Disabling auto backups.\n"); ++ $localtlpdb->option("autobackup", 0); ++ $autobackup = 0; ++ } ++ } ++ } ++ ++ # cmd line --backup, we check for --backupdir, and if that is not given ++ # we try to get the default from the tlpdb. If that doesn't work, exit. ++ if ($opt_backup) { ++ my $diebackupdir = 0; ++ if (!$opt_backupdir) { ++ $opt_backupdir = $localtlpdb->option("backupdir"); ++ if ($opt_backupdir) { ++ # check again: ++ $opt_backupdir = abs_path($opt_backupdir); ++ $diebackupdir = 1 if (! -d $opt_backupdir); ++ } else { ++ # not set in the tlpdb, and not set on cmd line, but asked for ++ # --backup ++ $diebackupdir = 1; ++ } ++ } ++ # no else branch necessary, we already checked that --backupdir if ++ # given is ok, see above ++ if ($diebackupdir) { ++ tlwarn("You have asked for backups, but the backup directory as specified\n"); ++ tlwarn("in the local TLPDB or the cmd line does not exists, exiting.\n"); ++ exit 1; ++ } ++ } ++ ++ # finally, if we have --backupdir, but no --backup, just enable it ++ $opt_backup = 1 if $opt_backupdir; ++ ++ debug("Doing backups to $opt_backupdir\n") if $opt_backup; ++ + # these two variables are used throughout this function + my $root = $localtlpdb->root; + my $temp = "$root/temp"; +@@ -1103,19 +1179,18 @@ + if ($opt_list) { + info("$pkg: local: $rev, source: $mediarev\n"); + } else { +- # first remove the package, then reinstall it +- # this way we get rid of useless files +- # force the deinstallation since we will reinstall it +- if ($opt_backupdir && !$opt_dry) { +- $opt_backupdir = abs_path($opt_backupdir); +- if (! -d $opt_backupdir) { +- tlwarn("backupdir argument must be an existing directory!\n"); +- } else { +- $tlp->make_container("lzma", $root, +- $opt_backupdir, "${pkg}.r" . $tlp->revision); +- $unwind_package = "$opt_backupdir/${pkg}.r" . $tlp->revision . ".tar.lzma"; ++ if ($opt_backup && !$opt_dry) { ++ $tlp->make_container("lzma", $root, ++ $opt_backupdir, "${pkg}.r" . $tlp->revision); ++ $unwind_package = ++ "$opt_backupdir/${pkg}.r" . $tlp->revision . ".tar.lzma"; ++ ++ if ($autobackup) { ++ # in case we do auto backups we remove older backups ++ clear_old_backups($pkg, $opt_backupdir, $autobackup); + } + } ++ + if (win32() && ($pkg =~ m/$WinSpecialUpdatePackagesRegexp/)) { + add_win32_updater($mediatlp, $opt_dry); + } else { +@@ -1142,6 +1217,10 @@ + $remove_unwind_container = 1; + $unwind_package = "$fullname"; + } ++ # first remove the package, then reinstall it ++ # this way we get rid of useless files ++ # force the deinstallation since we will reinstall it ++ # + # 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)); +@@ -1157,7 +1236,7 @@ + # dirs from the new package before re-installing the old one. + # TODO + logpackage("failed update: $pkg ($rev -> $mediarev)"); +- tlwarn("\n\nInstallation of new version of $pkg did fail, trying to unwind!\n"); ++ tlwarn("\n\nInstallation of new version of $pkg did fail, trying to unwind.\n"); + if (win32()) { + # win32 is notorious for not releasing a file immediately + # we experienced permission denied errors +@@ -1383,7 +1462,15 @@ + print "Install documentation files: ", ($localtlpdb->option_install_docfiles ? "yes": "no"), "\n"; + print "Install source files: ", ($localtlpdb->option_install_srcfiles ? "yes": "no"), "\n"; + } else { +- warn "Setting other options currently not supported, please edit texlive.tlpdb!"; ++ my $val = shift @ARGV; ++ if (defined($val)) { ++ print "Setting option $what to $val.\n"; ++ $localtlpdb->option($what,$val); ++ $localtlpdb->save; ++ } else { ++ print "Option $what = ", $localtlpdb->option($what), "\n";; ++ } ++ #warn "Setting other options currently not supported, please edit texlive.tlpdb!"; + } + return; + } +@@ -1937,6 +2024,32 @@ + } + + ++# clear the backup dir for $pkg and keep only $autobackup packages ++sub clear_old_backups ++{ ++ my ($pkg, $opt_backupdir, $autobackup) = @_; ++ # keep arbitrary many backups ++ return if ($autobackup == -1); ++ ++ opendir (DIR, $opt_backupdir) || die "opendir($opt_backupdir) failed: $!"; ++ my @dirents = readdir (DIR); ++ closedir (DIR) || warn "closedir($opt_backupdir) failed: $!"; ++ my @backups; ++ for my $dirent (@dirents) { ++ next if (-d $dirent); ++ next if ($dirent !~ m/^$pkg\.r([0-9]+)\.tar\.lzma$/); ++ push @backups, $1; ++ } ++ my $i = 1; ++ for my $e (reverse sort {$a <=> $b} @backups) { ++ if ($i > $autobackup) { ++ unlink("$opt_backupdir/$pkg.r$e.tar.lzma"); ++ } ++ $i++; ++ } ++} ++ ++ + # + # return all the directories from which all content will be removed + # +Index: tlpkg/TeXLive/TLPDB.pm +=================================================================== +--- tlpkg/TeXLive/TLPDB.pm (revision 11059) ++++ tlpkg/TeXLive/TLPDB.pm (working copy) +@@ -49,6 +49,7 @@ + $tlpdb->config_container_format; + $tlpdb->config_release; + $tlpdb->config_revision; ++ $tlpdb->option($key, [$value]); + + TeXLive::TLPDB->listdir([$dir]); + $tlpdb->generate_listfiles([$destdir]); +@@ -955,6 +956,14 @@ + return; + } + ++sub option { ++ my $self = shift; ++ my $key = shift; ++ if (@_) { $self->_set_option_value($key, shift); } ++ return $self->_option_value($key); ++} ++# TODO the above function should be used in the functions below as ++# far as possible ... + sub option_available_architectures { + my $self = shift; + if (@_) { $self->_set_option_value("available_architectures","@_"); } diff --git a/Master/tlpkg/etc/use-autopatterns-from-dedicated-tlpsrc-files.patch b/Master/tlpkg/etc/use-autopatterns-from-dedicated-tlpsrc-files.patch new file mode 100644 index 00000000000..f29aa49b158 --- /dev/null +++ b/Master/tlpkg/etc/use-autopatterns-from-dedicated-tlpsrc-files.patch @@ -0,0 +1,362 @@ + +This patch adds the ability to change the auto generated patterns by +adding tlpsrc files named + 00texlive.autopatterns.<CATEGORY>.tlpsrc +and within these files the relevant src/bin/doc/run patterns. + +This patch adds in addition the tlpsrc autopattern files + 00texlive.autopatterns.Package.tlpsrc + 00texlive.autopatterns.Documentation.tlpsrc +to get the exact same behaviour as before. + +Warning: This change will make the description for maintaining separate +repositories a bit outdated, since now also these autopattern files +have to be added, or patterns themselves have to be specified. + + +Index: tlpkg/bin/tlpsrc2tlpdb +=================================================================== +--- tlpkg/bin/tlpsrc2tlpdb (revision 11059) ++++ tlpkg/bin/tlpsrc2tlpdb (working copy) +@@ -63,9 +63,43 @@ + $tlc = TeXLive::TeXCatalogue->new ("location" => $opt_catalogue); + } + ++ # get the default patterns ++ my $tlpsrc_dir = "$opt_master/tlpkg/tlpsrc"; ++ chdir ($tlpsrc_dir) || die "chdir($tlpsrc_dir) failed: $!"; ++ my @autopatternfiles = glob ("00texlive.autopatterns.*.tlpsrc"); ++ my %autopatterns; ++ for my $ap (@autopatternfiles) { ++ (my $cat = $ap) =~ s/^00texlive\.autopatterns\.(.*)\.tlpsrc$/$1/; ++ my $tlsrc = new TeXLive::TLPSRC; ++ $tlsrc->from_file ($ap); ++ push @{$autopatterns{$cat}{"bin"}}, $tlsrc->binpatterns ++ if $tlsrc->binpatterns; ++ push @{$autopatterns{$cat}{"src"}}, $tlsrc->srcpatterns ++ if $tlsrc->srcpatterns; ++ push @{$autopatterns{$cat}{"doc"}}, $tlsrc->docpatterns ++ if $tlsrc->docpatterns; ++ push @{$autopatterns{$cat}{"run"}}, $tlsrc->runpatterns ++ if $tlsrc->runpatterns; ++ } ++ ++ for my $cat (keys %autopatterns) { ++ debug ("Category $cat\n"); ++ for my $d (@{$autopatterns{$cat}{"bin"}}) { ++ debug ("Found auto bin pattern $d\n"); ++ } ++ for my $d (@{$autopatterns{$cat}{"src"}}) { ++ debug ("Found auto src pattern $d\n"); ++ } ++ for my $d (@{$autopatterns{$cat}{"doc"}}) { ++ debug ("Found auto doc pattern $d\n"); ++ } ++ for my $d (@{$autopatterns{$cat}{"run"}}) { ++ debug ("Found auto run pattern $d\n"); ++ } ++ } ++ + # if we're regenerating the whole thing, get all our tlpsrc files. + if ($opt_all) { +- my $tlpsrc_dir = "$opt_master/tlpkg/tlpsrc"; + chdir ($tlpsrc_dir) || die "chdir($tlpsrc_dir) failed: $!"; + @ARGV = glob ("*.tlpsrc"); + } +@@ -82,11 +116,16 @@ + my $tldb = TeXLive::TLPDB->new; + my $src_count = 0; + foreach my $f (@ARGV) { ++ next if ($f =~ m/^00texlive\.autopatterns/); + $src_count++ if $opt_all; + + my $tlsrc = new TeXLive::TLPSRC; + $tlsrc->from_file ($f); +- my $tlp = $tlsrc->make_tlpobj ($tltree); ++ my $patternref; ++ if (defined($autopatterns{$tlsrc->category})) { ++ $patternref = $autopatterns{$tlsrc->category}; ++ } ++ my $tlp = $tlsrc->make_tlpobj ($tltree, $autopatterns{$tlsrc->category}); + + (my $base_f = $f) =~ s/\.tlpsrc$//; + warn "$f: package name " . $tlp->name . " does not match filename\n" +Index: tlpkg/tlpsrc/00texlive.autopatterns.Package.tlpsrc +=================================================================== +--- tlpkg/tlpsrc/00texlive.autopatterns.Package.tlpsrc (revision 0) ++++ tlpkg/tlpsrc/00texlive.autopatterns.Package.tlpsrc (revision 0) +@@ -0,0 +1,17 @@ ++name 00texlive.autopatterns.package ++category Package ++shortdesc Defines the automatically generated patterns for category Package ++runpattern t texmf-dist bibtex %NAME% ++runpattern t texmf-dist context %NAME% ++runpattern t texmf-dist dvips %NAME% ++runpattern t texmf-dist fonts %NAME% ++runpattern t texmf-dist makeindex %NAME% ++runpattern t texmf-dist metafont %NAME% ++runpattern t texmf-dist metapost %NAME% ++runpattern t texmf-dist mft %NAME% ++runpattern t texmf-dist omega %NAME% ++runpattern t texmf-dist scripts %NAME% ++runpattern t texmf-dist tex %NAME% ++runpattern t texmf-dist vtex %NAME% ++srcpattern t texmf-dist source %NAME% ++docpattern t texmf-dist doc %NAME% +Index: tlpkg/tlpsrc/00texlive.autopatterns.Documentation.tlpsrc +=================================================================== +--- tlpkg/tlpsrc/00texlive.autopatterns.Documentation.tlpsrc (revision 0) ++++ tlpkg/tlpsrc/00texlive.autopatterns.Documentation.tlpsrc (revision 0) +@@ -0,0 +1,5 @@ ++name 00texlive.autopatterns.documentation ++category Documentation ++shortdesc Defines the automatically generated patterns for category Documentation ++srcpattern t texmf-doc source %NAME% ++docpattern t texmf-doc doc %NAME% +Index: tlpkg/TeXLive/TLPSRC.pm +=================================================================== +--- tlpkg/TeXLive/TLPSRC.pm (revision 11059) ++++ tlpkg/TeXLive/TLPSRC.pm (working copy) +@@ -201,7 +201,11 @@ + # + sub make_tlpobj + { +- my ($self,$tltree) = @_; ++ my ($self,$tltree,$defaultpatterns) = @_; ++ my %patterns; ++ if (defined($defaultpatterns)) { ++ %patterns = %{$defaultpatterns}; ++ } + my $tlp = TeXLive::TLPOBJ->new; + $tlp->name($self->name); + $tlp->category($self->category); +@@ -212,124 +216,67 @@ + $tlp->depends(@{$self->{'depends'}}) if (defined($self->{'depends'})); + $tlp->revision(0); + my $filemax; +- my $usedefault = 1; ++ my $usedefault; + my @allpospats; + my @allnegpats; ++ my $pkgname = $self->name; + # +- # runpatterns ++ # src/run/doc patterns + # +- foreach my $p (@{$self->{'runpatterns'}}) { +- if ($p =~ m/^\+!(.*)$/) { +- push @allnegpats, $1; +- } elsif ($p =~ m/^\+(.*)$/) { +- push @allpospats, $1; +- } elsif ($p =~ m/^!(.*)$/) { +- push @allnegpats, $1; +- $usedefault = 0; +- } else { +- push @allpospats, $p; +- $usedefault = 0; ++ # WARNING WARNING WARNING ++ # the "bin" must be last since we drop through for further dealing ++ # with specialities of the bin patterns!!!! ++ for my $pattype (qw/src run doc bin/) { ++ @allpospats = (); ++ @allnegpats = (); ++ $usedefault = 1; ++ foreach my $p (@{$self->{${pattype} . 'patterns'}}) { ++ if ($p =~ m/^\+!(.*)$/) { ++ push @allnegpats, $1; ++ } elsif ($p =~ m/^\+(.*)$/) { ++ push @allpospats, $1; ++ } elsif ($p =~ m/^!(.*)$/) { ++ push @allnegpats, $1; ++ $usedefault = 0; ++ } else { ++ push @allpospats, $p; ++ $usedefault = 0; ++ } + } +- } +- if ($usedefault) { +- if ($self->category eq "Package") { +- foreach my $md (qw/bibtex context dvips fonts makeindex metafont +- metapost mft omega scripts tex vtex/) { +- # mark the default pattern with a leading * so that +- # we do not warn a missing hit on a default pattern +- push @allpospats, "*t texmf-dist $md $self->{'name'}"; ++ if ($usedefault && defined($patterns{$pattype})) { ++ for my $p (@{$patterns{$pattype}}) { ++ # replace the string %NAME% with the actual package name ++ # we have to make a copy of $p otherwise we change it in the ++ # hash once and for all ++ (my $pp = $p) =~ s/%NAME%/$pkgname/g; ++ # sort through the patterns, and make sure that * are added to ++ # tag the default patterns ++ if ($pp =~ m/^!(.*)$/) { ++ push @allnegpats, "*$1"; ++ } else { ++ push @allpospats, "*$pp"; ++ } + } + } +- } +- foreach my $p (@allpospats) { +- $self->_do_normal_pattern($p,$tlp,$tltree,'run'); +- } +- foreach my $p (@allnegpats) { +- $self->_do_normal_pattern($p,$tlp,$tltree,'run',1); +- } +- # +- # srcpatterns +- # +- @allpospats = (); +- @allnegpats = (); +- $usedefault = 1; +- foreach my $p (@{$self->{'srcpatterns'}}) { +- if ($p =~ m/^\+!(.*)$/) { +- push @allnegpats, $1; +- } elsif ($p =~ m/^\+(.*)$/) { +- push @allpospats, $1; +- } elsif ($p =~ m/^!(.*)$/) { +- push @allnegpats, $1; +- $usedefault = 0; +- } else { +- push @allpospats, $p; +- $usedefault = 0; ++ # at this point we do NOT do the actual pattern matching for ++ # bin patterns, since we have some specialities to do ++ last if ($pattype eq "bin"); ++ # for all other patterns we create the list and add the files ++ foreach my $p (@allpospats) { ++ ddebug("pos pattern $p\n"); ++ $self->_do_normal_pattern($p,$tlp,$tltree,$pattype); + } +- } +- if ($usedefault) { +- # default patterns for srcfiles +- if ($self->category eq "Package") { +- push @allpospats, "*t texmf-dist source $self->{'name'}"; +- } elsif ($self->category eq "Documentation") { +- push @allpospats, "*t texmf-doc source $self->{'name'}"; ++ foreach my $p (@allnegpats) { ++ ddebug("neg pattern $p\n"); ++ $self->_do_normal_pattern($p,$tlp,$tltree,$pattype,1); + } + } +- foreach my $p (@allpospats) { +- $self->_do_normal_pattern($p,$tlp,$tltree,'src'); +- } +- foreach my $p (@allnegpats) { +- $self->_do_normal_pattern($p,$tlp,$tltree,'src',1); +- } + # +- # docpatterns +- # +- @allpospats = (); +- @allnegpats = (); +- $usedefault = 1; +- foreach my $p (@{$self->{'docpatterns'}}) { +- if ($p =~ m/^\+!(.*)$/) { +- push @allnegpats, $1; +- } elsif ($p =~ m/^\+(.*)$/) { +- push @allpospats, $1; +- } elsif ($p =~ m/^!(.*)$/) { +- push @allnegpats, $1; +- $usedefault = 0; +- } else { +- push @allpospats, $p; +- $usedefault = 0; +- } +- } +- if ($usedefault) { +- # default patterns for docfiles +- if ($self->category eq "Package") { +- push @allpospats, "*t texmf-dist doc $self->{'name'}"; +- } elsif ($self->category eq "Documentation") { +- push @allpospats, "*t texmf-doc doc $self->{'name'}"; +- } +- } +- foreach my $p (@allpospats) { +- $self->_do_normal_pattern($p,$tlp,$tltree,'doc'); +- } +- foreach my $p (@allnegpats) { +- $self->_do_normal_pattern($p,$tlp,$tltree,'doc',1); +- } +- # + # binpatterns + # +- # no default patterns for binfiles +- @allpospats = (); +- @allnegpats = (); +- foreach my $p (@{$self->{'binpatterns'}}) { +- if ($p =~ m/^\+!(.*)$/) { +- push @allnegpats, $1; +- } elsif ($p =~ m/^\+(.*)$/) { +- push @allpospats, $1; +- } elsif ($p =~ m/^!(.*)$/) { +- push @allnegpats, $1; +- } else { +- push @allpospats, $p; +- } +- } ++ # mind that @allpospats and @allnegpats have already been set up ++ # in the above loop. We only have to deal with the specialities of ++ # the bin patterns + foreach my $p (@allpospats) { + my @todoarchs = $tltree->architectures; + my $finalp = $p; +@@ -472,17 +419,29 @@ + sub srcpatterns { + my $self = shift; + if (@_) { @{ $self->{'srcpatterns'} } = @_ } +- return @{ $self->{'srcpatterns'} }; ++ if (defined($self->{'srcpatterns'})) { ++ return @{ $self->{'srcpatterns'} }; ++ } else { ++ return; ++ } + } + sub docpatterns { + my $self = shift; + if (@_) { @{ $self->{'docpatterns'} } = @_ } +- return @{ $self->{'docpatterns'} }; ++ if (defined($self->{'docpatterns'})) { ++ return @{ $self->{'docpatterns'} }; ++ } else { ++ return; ++ } + } + sub binpatterns { + my $self = shift; + if (@_) { @{ $self->{'binpatterns'} } = @_ } +- return @{ $self->{'binpatterns'} }; ++ if (defined($self->{'binpatterns'})) { ++ return @{ $self->{'binpatterns'} }; ++ } else { ++ return; ++ } + } + sub depends { + my $self = shift; +@@ -492,7 +451,11 @@ + sub runpatterns { + my $self = shift; + if (@_) { @{ $self->{'runpatterns'} } = @_ } +- return @{ $self->{'runpatterns'} }; ++ if (defined($self->{'runpatterns'})) { ++ return @{ $self->{'runpatterns'} }; ++ } else { ++ return; ++ } + } + sub executes { + my $self = shift; +@@ -746,7 +709,9 @@ + + If a given pattern section is empty or B<all> the provided patterns have + the prefix C<+> (e.g., C<+f ...>), then the following patterns, listed +-by type are I<automatically> added at expansion time: ++by type are I<automatically> added at expansion time. Note that this list ++is not definitive, but is taken from the patterns of tlpsrc files ++named C<00texlive.autopatterns.>I<Category>C<.tlpsrc>. + + =over 4 + |