commit db7dcc065397a1b346a3492aa9b57df866592f24 Author: Danielle McLean Date: Mon Oct 3 23:05:44 2016 +1100 Initial build - GNU stow suitable for linking into your home dir using GNU stow diff --git a/.local/bin/chkstow b/.local/bin/chkstow new file mode 100755 index 0000000..b3a55b0 --- /dev/null +++ b/.local/bin/chkstow @@ -0,0 +1,113 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +require 5.006_001; + +use File::Find; +use Getopt::Long; + +my $DEFAULT_TARGET = '/usr/local/'; + +our $Wanted = \&bad_links; +our %Package = (); +our $Stow_dir = ''; +our $Target = $DEFAULT_TARGET; + +# put the main loop into a block so that tests can load this as a module +if ( not caller() ) { + if (@ARGV == 0) { + usage(); + } + process_options(); + #check_stow($Target, $Wanted); + check_stow(); +} + +sub process_options { + GetOptions( + 'b|badlinks' => sub { $Wanted = \&bad_links }, + 'a|aliens' => sub { $Wanted = \&aliens }, + 'l|list' => sub { $Wanted = \&list }, + 't|target=s' => \$Target, + ) or usage(); + return; +} + +sub usage { + print <<"EOT"; +USAGE: chkstow [options] + +Options: + -t DIR, --target=DIR Set the target directory to DIR + (default is $DEFAULT_TARGET) + -b, --badlinks Report symlinks that point to non-existent files + -a, --aliens Report non-symlinks in the target directory + -l, --list List packages in the target directory + +--badlinks is the default mode. +EOT + exit(0); +} + +sub check_stow { + #my ($Target, $Wanted) = @_; + + my (%options) = ( + wanted => $Wanted, + preprocess => \&skip_dirs, + ); + + find(\%options, $Target); + + if ($Wanted == \&list) { + delete $Package{''}; + delete $Package{'..'}; + + if (keys %Package) { + print map "$_\n", sort(keys %Package); + } + } + return; +} + +sub skip_dirs { + # skip stow source and unstowed targets + if (-e ".stow" || -e ".notstowed" ) { + warn "skipping $File::Find::dir\n"; + return (); + } + else { + return @_; + } +} + +# checking for files that do not link to anything +sub bad_links { + -l && !-e && print "Bogus link: $File::Find::name\n"; +} + +# checking for files that are not owned by stow +sub aliens { + !-l && !-d && print "Unstowed file: $File::Find::name\n"; +} + +# just list the packages in the the target directory +# FIXME: what if the stow dir is not called 'stow'? +sub list { + if (-l) { + $_ = readlink; + s{\A(?:\.\./)+stow/}{}g; + s{/.*}{}g; + $Package{$_} = 1; + } +} + +1; # Hey, it's a module! + +# Local variables: +# mode: perl +# cperl-indent-level: 4 +# End: +# vim: ft=perl diff --git a/.local/bin/stow b/.local/bin/stow new file mode 100755 index 0000000..7acad8b --- /dev/null +++ b/.local/bin/stow @@ -0,0 +1,667 @@ +#!/usr/bin/perl + +# GNU Stow - manage the installation of multiple software packages +# Copyright (C) 1993, 1994, 1995, 1996 by Bob Glickstein +# Copyright (C) 2000, 2001 Guillaume Morin +# Copyright (C) 2007 Kahlil Hodgson +# Copyright (C) 2011 Adam Spiers +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . + +=head1 NAME + +stow - software package installation manager + +=head1 SYNOPSIS + +stow [ options ] package ... + +=head1 DESCRIPTION + +This manual page describes GNU Stow 2.2.2, a program for managing +the installation of software packages. This is not the definitive +documentation for stow; for that, see the info manual. + +Stow is a tool for managing the installation of multiple software +packages in the same run-time directory tree. One historical +difficulty of this task has been the need to administer, upgrade, +install, and remove files in independent packages without confusing +them with other files sharing the same filesystem space. For instance, +it is common to install Perl and Emacs in F. When one +does so, one winds up (as of Perl 4.036 and Emacs 19.22) with the +following files in F: F; F; +F; F; F; F; and F. Now +suppose it's time to uninstall Perl. Which man pages get removed? +Obviously F is one of them, but it should not be the +administrator's responsibility to memorize the ownership of individual +files by separate packages. + +The approach used by Stow is to install each package into its own +tree, then use symbolic links to make it appear as though the files +are installed in the common tree. Administration can be performed in +the package's private tree in isolation from clutter from other +packages. Stow can then be used to update the symbolic links. The +structure of each private tree should reflect the desired structure in +the common tree; i.e. (in the typical case) there should be a F +directory containing executables, a F directory containing +section 1 man pages, and so on. + +Stow was inspired by Carnegie Mellon's Depot program, but is +substantially simpler and safer. Whereas Depot required database files +to keep things in sync, Stow stores no extra state between runs, so +there's no danger (as there was in Depot) of mangling directories when +file hierarchies don't match the database. Also unlike Depot, Stow +will never delete any files, directories, or links that appear in a +Stow directory (e.g., F), so it's always +possible to rebuild the target tree (e.g., F). + +=head1 TERMINOLOGY + +A "package" is a related collection of files and directories that +you wish to administer as a unit -- e.g., Perl or Emacs -- and that +needs to be installed in a particular directory structure -- e.g., +with F, F, and F subdirectories. + +A "target directory" is the root of a tree in which one or more +packages wish to B to be installed. A common, but by no means +the only such location is F. The examples in this manual +page will use F as the target directory. + +A "stow directory" is the root of a tree containing separate +packages in private subtrees. When Stow runs, it uses the current +directory as the default stow directory. The examples in this manual +page will use F as the stow directory, so that +individual packages will be, for example, F and +F. + +An "installation image" is the layout of files and directories +required by a package, relative to the target directory. Thus, the +installation image for Perl includes: a F directory containing +F and F (among others); an F directory containing +Texinfo documentation; a F directory containing Perl +libraries; and a F directory containing man pages. + +A "package directory" is the root of a tree containing the +installation image for a particular package. Each package directory +must reside in a stow directory -- e.g., the package directory +F must reside in the stow directory +F. The "name" of a package is the name of its +directory within the stow directory -- e.g., F. + +Thus, the Perl executable might reside in +F, where F is the target +directory, F is the stow directory, +F is the package directory, and F +within is part of the installation image. + +A "symlink" is a symbolic link. A symlink can be "relative" or +"absolute". An absolute symlink names a full path; that is, one +starting from F. A relative symlink names a relative path; that +is, one not starting from F. The target of a relative symlink is +computed starting from the symlink's own directory. Stow only creates +relative symlinks. + +=head1 OPTIONS + +The stow directory is assumed to be the value of the C +environment variable or if unset the current directory, and the target +directory is assumed to be the parent of the current directory (so it +is typical to execute F from the directory F). +Each F given on the command line is the name of a package in +the stow directory (e.g., F). By default, they are installed +into the target directory (but they can be deleted instead using +C<-D>). + +=over 4 + +=item -n + +=item --no + +Do not perform any operations that modify the filesystem; merely show +what would happen. + +=item -d DIR + +=item --dir=DIR + +Set the stow directory to C instead of the current directory. +This also has the effect of making the default target directory be the +parent of C. + +=item -t DIR + +=item --target=DIR + +Set the target directory to C instead of the parent of the stow +directory. + +=item -v + +=item --verbose[=N] + +Send verbose output to standard error describing what Stow is +doing. Verbosity levels are 0, 1, 2, 3, and 4; 0 is the default. +Using C<-v> or C<--verbose> increases the verbosity by one; using +`--verbose=N' sets it to N. + +=item -S + +=item --stow + +Stow the packages that follow this option into the target directory. +This is the default action and so can be omitted if you are only +stowing packages rather than performing a mixture of +stow/delete/restow actions. + +=item -D + +=item --delete + +Unstow the packages that follow this option from the target directory rather +than installing them. + +=item -R + +=item --restow + +Restow packages (first unstow, then stow again). This is useful +for pruning obsolete symlinks from the target tree after updating +the software in a package. + +=item --adopt + +B This behaviour is specifically intended to alter the +contents of your stow directory. If you do not want that, this option +is not for you. + +When stowing, if a target is encountered which already exists but is a +plain file (and hence not owned by any existing stow package), then +normally Stow will register this as a conflict and refuse to proceed. +This option changes that behaviour so that the file is moved to the +same relative place within the package's installation image within the +stow directory, and then stowing proceeds as before. So effectively, +the file becomes adopted by the stow package, without its contents +changing. + +=item --no-folding + +Disable folding of newly stowed directories when stowing, and +refolding of newly foldable directories when unstowing. + +=item --ignore=REGEX + +Ignore files ending in this Perl regex. + +=item --defer=REGEX + +Don't stow files beginning with this Perl regex if the file is already +stowed to another package. + +=item --override=REGEX + +Force stowing files beginning with this Perl regex if the file is +already stowed to another package. + +=item -V + +=item --version + +Show Stow version number, and exit. + +=item -h + +=item --help + +Show Stow command syntax, and exit. + +=back + +=head1 INSTALLING PACKAGES + +The default action of Stow is to install a package. This means +creating symlinks in the target tree that point into the package tree. +Stow attempts to do this with as few symlinks as possible; in other +words, if Stow can create a single symlink that points to an entire +subtree within the package tree, it will choose to do that rather than +create a directory in the target tree and populate it with symlinks. + +For example, suppose that no packages have yet been installed in +F; it's completely empty (except for the F +subdirectory, of course). Now suppose the Perl package is installed. +Recall that it includes the following directories in its installation +image: F; F; F; F. Rather than +creating the directory F and populating it with +symlinks to F<../stow/perl/bin/perl> and F<../stow/perl/bin/a2p> (and +so on), Stow will create a single symlink, F, which +points to F. In this way, it still works to refer to +F and F, and fewer symlinks +have been created. This is called "tree folding", since an entire +subtree is "folded" into a single symlink. + +To complete this example, Stow will also create the symlink +F pointing to F; the symlink +F pointing to F; and the symlink +F pointing to F. + +Now suppose that instead of installing the Perl package into an empty +target tree, the target tree is not empty to begin with. Instead, it +contains several files and directories installed under a different +system-administration philosophy. In particular, F +already exists and is a directory, as are F and +F. In this case, Stow will descend into +F and create symlinks to F<../stow/perl/bin/perl> and +F<../stow/perl/bin/a2p> (etc.), and it will descend into +F and create the tree-folding symlink F pointing +to F<../stow/perl/lib/perl>, and so on. As a rule, Stow only descends +as far as necessary into the target tree when it can create a +tree-folding symlink. + +The time often comes when a tree-folding symlink has to be undone +because another package uses one or more of the folded subdirectories +in its installation image. This operation is called "splitting open" +a folded tree. It involves removing the original symlink from the +target tree, creating a true directory in its place, and then +populating the new directory with symlinks to the newly-installed +package B to the old package that used the old symlink. For +example, suppose that after installing Perl into an empty +F, we wish to install Emacs. Emacs's installation image +includes a F directory containing the F and F +executables, among others. Stow must make these files appear to be +installed in F, but presently F is a +symlink to F. Stow therefore takes the following +steps: the symlink F is deleted; the directory +F is created; links are made from F to +F<../stow/emacs/bin/emacs> and F<../stow/emacs/bin/etags>; and links +are made from F to F<../stow/perl/bin/perl> and +F<../stow/perl/bin/a2p>. + +When splitting open a folded tree, Stow makes sure that the symlink +it is about to remove points inside a valid package in the current stow +directory. + +=head2 Stow will never delete anything that it doesn't own. + +Stow "owns" everything living in the target tree that points into a +package in the stow directory. Anything Stow owns, it can recompute if +lost. Note that by this definition, Stow doesn't "own" anything +B the stow directory or in any of the packages. + +If Stow needs to create a directory or a symlink in the target tree +and it cannot because that name is already in use and is not owned by +Stow, then a conflict has arisen. See the "Conflicts" section in the +info manual. + +=head1 DELETING PACKAGES + +When the C<-D> option is given, the action of Stow is to delete a +package from the target tree. Note that Stow will not delete anything +it doesn't "own". Deleting a package does B mean removing it from +the stow directory or discarding the package tree. + +To delete a package, Stow recursively scans the target tree, skipping +over the stow directory (since that is usually a subdirectory of the +target tree) and any other stow directories it encounters (see +"Multiple stow directories" in the info manual). Any symlink it +finds that points into the package being deleted is removed. Any +directory that contained only symlinks to the package being deleted is +removed. Any directory that, after removing symlinks and empty +subdirectories, contains only symlinks to a single other package, is +considered to be a previously "folded" tree that was "split open." +Stow will re-fold the tree by removing the symlinks to the surviving +package, removing the directory, then linking the directory back to +the surviving package. + +=head1 SEE ALSO + +The full documentation for F is maintained as a Texinfo manual. +If the F and F programs are properly installed at your site, the command + + info stow + +should give you access to the complete manual. + +=head1 BUGS + +Please report bugs in Stow using the Debian bug tracking system. + +Currently known bugs include: + +=over 4 + +=item * The empty-directory problem. + +If package F includes an empty directory -- say, F -- +then if no other package has a F subdirectory, everything's fine. +If another stowed package F, has a F subdirectory, then +when stowing, F will be "split open" and the contents +of F will be individually stowed. So far, so good. But when +unstowing F, F will be removed, even though +F needs it to remain. A workaround for this problem is to +create a file in F as a placeholder. If you name that file +F<.placeholder>, it will be easy to find and remove such files when +this bug is fixed. + +=item * + +When using multiple stow directories (see "Multiple stow directories" +in the info manual), Stow fails to "split open" tree-folding symlinks +(see "Installing packages" in the info manual) that point into a stow +directory which is not the one in use by the current Stow +command. Before failing, it should search the target of the link to +see whether any element of the path contains a F<.stow> file. If it +finds one, it can "learn" about the cooperating stow directory to +short-circuit the F<.stow> search the next time it encounters a +tree-folding symlink. + +=back + +=head1 AUTHOR + +This man page was originally constructed by Charles Briscoe-Smith from +parts of Stow's info manual, and then converted to POD format by Adam +Spiers. The info manual contains the following notice, which, as it +says, applies to this manual page, too. The text of the section +entitled "GNU General Public License" can be found in the file +F on any Debian GNU/Linux system. If +you don't have access to a Debian system, or the GPL is not there, +write to the Free Software Foundation, Inc., 59 Temple Place, Suite +330, Boston, MA, 02111-1307, USA. + +=head1 COPYRIGHT + +Copyright (C) +1993, 1994, 1995, 1996 by Bob Glickstein ; +2000, 2001 by Guillaume Morin; +2007 by Kahlil Hodgson; +2011 by Adam Spiers; +and others. + +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that +the section entitled "GNU General Public License" is included with the +modified manual, and provided that the entire resulting derived work +is distributed under the terms of a permission notice identical to +this one. + +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be stated in a +translation approved by the Free Software Foundation. + +=cut + +use strict; +use warnings; + +require 5.006_001; + +use POSIX qw(getcwd); +use Getopt::Long; + +use Cwd qw(abs_path); +use File::Basename qw(dirname); +use lib dirname(dirname(abs_path($0))) . '/share/perl'; +use Stow; +use Stow::Util qw(parent error); + +my $ProgramName = $0; +$ProgramName =~ s{.*/}{}; + +main() unless caller(); + +sub main { + my ($options, $pkgs_to_unstow, $pkgs_to_stow) = process_options(); + + my $stow = new Stow(%$options); + # current dir is now the target directory + + $stow->plan_unstow(@$pkgs_to_unstow); + $stow->plan_stow (@$pkgs_to_stow); + + my %conflicts = $stow->get_conflicts; + + if (%conflicts) { + foreach my $action ('unstow', 'stow') { + next unless $conflicts{$action}; + foreach my $package (sort keys %{ $conflicts{$action} }) { + warn "WARNING! ${action}ing $package would cause conflicts:\n"; + #if $stow->get_action_count > 1; + foreach my $message (sort @{ $conflicts{$action}{$package} }) { + warn " * $message\n"; + } + } + } + warn "All operations aborted.\n"; + exit 1; + } + else { + if ($options->{simulate}) { + warn "WARNING: in simulation mode so not modifying filesystem.\n"; + return; + } + + $stow->process_tasks(); + } +} + + +#===== SUBROUTINE =========================================================== +# Name : process_options() +# Purpose : parse command line options +# Parameters: none +# Returns : (\%options, \@pkgs_to_unstow, \@pkgs_to_stow) +# Throws : a fatal error if a bad command line option is given +# Comments : checks @ARGV for valid package names +#============================================================================ +sub process_options { + my %options = (); + my @pkgs_to_unstow = (); + my @pkgs_to_stow = (); + my $action = 'stow'; + + unshift @ARGV, get_config_file_options(); + #$,="\n"; print @ARGV,"\n"; # for debugging rc file + + Getopt::Long::config('no_ignore_case', 'bundling', 'permute'); + GetOptions( + \%options, + 'verbose|v:+', 'help|h', 'simulate|n|no', + 'version|V', 'compat|p', 'dir|d=s', 'target|t=s', + 'adopt', 'no-folding', + + # clean and pre-compile any regex's at parse time + 'ignore=s' => + sub { + my $regex = $_[1]; + push @{$options{ignore}}, qr($regex\z); + }, + + 'override=s' => + sub { + my $regex = $_[1]; + push @{$options{override}}, qr(\A$regex); + }, + + 'defer=s' => + sub { + my $regex = $_[1]; + push @{$options{defer}}, qr(\A$regex); + }, + + # a little craziness so we can do different actions on the same line: + # a -D, -S, or -R changes the action that will be performed on the + # package arguments that follow it. + 'D|delete' => sub { $action = 'unstow' }, + 'S|stow' => sub { $action = 'stow' }, + 'R|restow' => sub { $action = 'restow' }, + + # Handler for non-option arguments + '<>' => + sub { + if ($action eq 'restow') { + push @pkgs_to_unstow, $_[0]; + push @pkgs_to_stow, $_[0]; + } + elsif ($action eq 'unstow') { + push @pkgs_to_unstow, $_[0]; + } + else { + push @pkgs_to_stow, $_[0]; + } + }, + ) or usage(); + + usage() if $options{help}; + version() if $options{version}; + + sanitize_path_options(\%options); + check_packages(\@pkgs_to_unstow, \@pkgs_to_stow); + + return (\%options, \@pkgs_to_unstow, \@pkgs_to_stow); +} + +sub sanitize_path_options { + my ($options) = @_; + + if (exists $options->{dir}) { + $options->{dir} =~ s/\A +//; + $options->{dir} =~ s/ +\z//; + } + else { + $options->{dir} = exists $ENV{STOW_DIR} ? $ENV{STOW_DIR} : getcwd(); + } + + if (exists $options->{target}) { + $options->{target} =~ s/\A +//; + $options->{target} =~ s/ +\z//; + } + else { + $options->{target} = parent($options->{dir}) || '.'; + } +} + +sub check_packages { + my ($pkgs_to_stow, $pkgs_to_unstow) = @_; + + if (not @$pkgs_to_stow and not @$pkgs_to_unstow) { + usage("No packages to stow or unstow"); + } + + # check package arguments + for my $package (@$pkgs_to_stow, @$pkgs_to_unstow) { + $package =~ s{/+$}{}; # delete trailing slashes + if ($package =~ m{/}) { + error("Slashes are not permitted in package names"); + } + } +} + + +#===== SUBROUTINE ============================================================ +# Name : get_config_file_options() +# Purpose : search for default settings in any .stowrc files +# Parameters: none +# Returns : a list of default options +# Throws : no exceptions +# Comments : prepends the contents of '~/.stowrc' and '.stowrc' to the command +# : line so they get parsed just like normal arguments. (This was +# : hacked in so that Emil and I could set different preferences). +#============================================================================= +sub get_config_file_options { + my @defaults = (); + for my $file ("$ENV{HOME}/.stowrc", '.stowrc') { + if (-r $file) { + warn "Loading defaults from $file\n"; + open my $FILE, '<', $file + or die "Could not open $file for reading\n"; + while (my $line = <$FILE>){ + chomp $line; + push @defaults, split " ", $line; + } + close $FILE or die "Could not close open file: $file\n"; + } + } + return @defaults; +} + +#===== SUBROUTINE =========================================================== +# Name : usage() +# Purpose : print program usage message and exit +# Parameters: $msg => string to prepend to the usage message +# Returns : n/a +# Throws : n/a +# Comments : if 'msg' is given, then exit with non-zero status +#============================================================================ +sub usage { + my ($msg) = @_; + + if ($msg) { + print "$ProgramName: $msg\n\n"; + } + + print <<"EOT"; +$ProgramName (GNU Stow) version $Stow::VERSION + +SYNOPSIS: + + $ProgramName [OPTION ...] [-D|-S|-R] PACKAGE ... [-D|-S|-R] PACKAGE ... + +OPTIONS: + + -d DIR, --dir=DIR Set stow dir to DIR (default is current dir) + -t DIR, --target=DIR Set target to DIR (default is parent of stow dir) + + -S, --stow Stow the package names that follow this option + -D, --delete Unstow the package names that follow this option + -R, --restow Restow (like stow -D followed by stow -S) + + --ignore=REGEX Ignore files ending in this Perl regex + --defer=REGEX Don't stow files beginning with this Perl regex + if the file is already stowed to another package + --override=REGEX Force stowing files beginning with this Perl regex + if the file is already stowed to another package + --adopt (Use with care!) Import existing files into stow package + from target. Please read docs before using. + -p, --compat Use legacy algorithm for unstowing + + -n, --no, --simulate Do not actually make any filesystem changes + -v, --verbose[=N] Increase verbosity (levels are 0,1,2,3; + -v or --verbose adds 1; --verbose=N sets level) + -V, --version Show stow version number + -h, --help Show this help + +Report bugs to: bug-stow\@gnu.org +Stow home page: +General help using GNU software: +EOT + exit defined $msg ? 1 : 0; +} + +sub version { + print "$ProgramName (GNU Stow) version $Stow::VERSION\n"; + exit 0; +} + +1; # This file is required by t/stow.t + +# Local variables: +# mode: perl +# cperl-indent-level: 4 +# end: +# vim: ft=perl diff --git a/.local/share/doc/stow/ChangeLog b/.local/share/doc/stow/ChangeLog new file mode 100644 index 0000000..ec7f8e1 --- /dev/null +++ b/.local/share/doc/stow/ChangeLog @@ -0,0 +1,1980 @@ +Mon Nov 9 12:37:09 2015 +0000 Adam Spiers + + * More fixes to "make distcheck" As with dc6a141d, the dependency of + distributed files on non-distributed files was causing this error: + + ERROR: files left in build directory after distclean: + + The automake FAQ explains why this happens: + + + https://www.gnu.org/software/automake/manual/html_node/Errors-with-distclean.html + + so change the dependency to Makefile.am which is distributed. + + + M Makefile.am + +Mon Nov 9 11:48:55 2015 +0000 Adam Spiers + + * NEWS: Explain why 2.2.1 was not released + + M NEWS + +Mon Nov 9 11:46:50 2015 +0000 Adam Spiers + + * Bump version to 2.2.2 + + M META.json + M META.yml + M configure.ac + +Mon Nov 9 11:36:11 2015 +0000 Adam Spiers + + * add Stow/Util.pm.in with @VERSION@ substitution This is now necessary + in order to prevent pause.perl.org from complaining: + + Status: Decreasing version number + ================================= + + module : Stow::Util + version: undef + in file: lib/Stow/Util.pm + status : Not indexed because lib/Stow/Util.pm in + A/AS/ASPIERS/Stow-v2.2.0.tar.gz has a higher + version number + (0) + + + M .gitignore + M MANIFEST + M META.json + M META.yml + M Makefile.am + M NEWS + D lib/Stow/Util.pm + A lib/Stow/Util.pm.in + +Mon Nov 9 11:05:00 2015 +0000 Adam Spiers + + * HOWTO-RELEASE: remove body indent + + M doc/HOWTO-RELEASE + +Mon Nov 9 11:04:21 2015 +0000 Adam Spiers + + * HOWTO-RELEASE: add link to official GNU maintainers guide + + M doc/HOWTO-RELEASE + +Mon Nov 9 10:13:34 2015 +0000 Adam Spiers + + * HOWTO-RELEASE: encourage use of SemVer + + M doc/HOWTO-RELEASE + +Mon Nov 9 10:11:59 2015 +0000 Adam Spiers + + * HOWTO-RELEASE: encourage GPG-signing of release tags + + M doc/HOWTO-RELEASE + +Mon Nov 9 10:10:36 2015 +0000 Adam Spiers + + * HOWTO-RELEASE: use gnulib for gendocs instead of texinfo These days it + seems that gendocs can be done entirely from the templates in + gnulib, rather than requiring the texinfo repository. + + + M doc/HOWTO-RELEASE + +Mon Nov 9 10:08:31 2015 +0000 Adam Spiers + + * fix make distcheck The dependency of the distributed file stow.8 on + the non-distributed file Makefile was causing this error: + + ERROR: files left in build directory after distclean: + ./doc/stow.8 + + The automake FAQ explains why this happens: + + + https://www.gnu.org/software/automake/manual/html_node/Errors-with-distclean.html + + so change stow.8 to depend on Makefile.am which is distributed. + + + M Makefile.am + +Mon Nov 9 09:28:11 2015 +0000 Adam Spiers + + * HOWTO-RELEASE: include automake --add-missing This is necessary since + automake files were removed from the repository recently. + + + M doc/HOWTO-RELEASE + +Mon Nov 9 09:27:49 2015 +0000 Adam Spiers + + * Update META.{yml,json} Rebuilt with newer Module::Build. + + + M META.json + M META.yml + +Mon Nov 9 09:17:34 2015 +0000 Adam Spiers + + * Bump version to 2.2.1 + + M configure.ac + +Mon Nov 9 09:16:32 2015 +0000 Adam Spiers + + * Prepare NEWS file for 2.2.1 release + + M NEWS + +Mon Nov 9 09:15:51 2015 +0000 Adam Spiers + + * Remove trailing whitespace from NEWS file + + M NEWS + +Mon Sep 17 16:55:17 2012 +0100 Adam Spiers + + * Add more index entries to the manual. + + M doc/stow.texi + +Mon Sep 17 16:55:03 2012 +0100 Adam Spiers + + * Fix a typo in the docs. + + M doc/stow.texi + +Sat Feb 7 19:29:43 2015 +0000 Adam Spiers + + * substitute @VERSION@ in stow.8 man page Thanks to Yue Du for spotting + this issue and providing the fix. + + + M Makefile.am + +Sat Feb 7 19:24:22 2015 +0000 Adam Spiers + + * remove automake files These should be generated at development / + install-time, rather than distributing versions via git which will + inevitably age over time. + + + A automake/.gitignore + D automake/install-sh + D automake/mdate-sh + D automake/missing + +Thu Jan 1 19:02:46 2015 +0000 Adam Spiers + + * fix stowing of relative links when --no-folding is used With a tree + like this: + + . + |-- stow + | `-- pkg + | `-- lib + | |-- itk-current -> itk4.0.0 + | `-- itk4.0.0 + | `-- libitk4.0.0.so + `-- target + `-- lib + |-- itk4.0.0 -> ../../stow/pkg/lib/itk4.0.0 + `-- libfoo-1.2.3.so + + stowing pkg with the --no-folding option resulted in itk-current + being "unpacked": + + . + `-- target + `-- lib + |-- itk-current + | `-- libitk4.0.0.so -> + ../../../stow/pkg/lib/itk-current/libitk4.0.0.so + |-- itk4.0.0 + | `-- libitk4.0.0.so -> + ../../../stow/pkg/lib/itk4.0.0/libitk4.0.0.so + `-- libfoo-1.2.3.so + + This commit fixes it so that it gets stowed as a symlink: + + . + `-- target + `-- lib + ... + |-- itk-current -> ../../stow/pkg/lib/itk-current + ... + + Thanks to Gabriele Balducci for reporting this problem: + + http://thread.gmane.org/gmane.comp.gnu.stow.general/6676 + + + M lib/Stow.pm.in + M t/stow.t + +Thu Jan 1 19:02:26 2015 +0000 Adam Spiers + + * improve debug + + M lib/Stow.pm.in + +Mon Sep 22 00:36:25 2014 +0100 Adam Spiers + + * make it more obvious when target (sub)directory is skipped This should + avoid the sort of confusion seen in: + + https://github.com/aspiers/shell-env/issues/1 + + + M lib/Stow.pm.in + M t/stow.t + M t/testutil.pm + M t/unstow.t + M t/unstow_orig.t + +Mon Sep 22 00:40:25 2014 +0100 Adam Spiers + + * trim trailing whitespace + + M t/stow.t + +Mon Sep 22 00:14:56 2014 +0100 Adam Spiers + + * update aclocal + + M aclocal.m4 + +Mon Jun 16 10:22:55 2014 +0100 Adam Spiers + + * avoid precedence warning With Perl 5.20, installing a package with + stow gives a warning like this: + + Possible precedence issue with control flow operator at + /gar/packages/stow-2.2.0/lib/perl5/site_perl/5.20.0/Stow.pm line + 1736. + + http://lists.gnu.org/archive/html/bug-stow/2014-06/msg00000.html + + Suggested-by: Adam Sampson + + + M lib/Stow.pm.in + +Wed Apr 24 08:44:32 2013 +0100 Adam Spiers + + * add TODO for install-hooks + + M TODO + +Fri Apr 12 17:47:29 2013 +0100 Adam Spiers + + * correctly handle the stow/target directories as non-canonical paths + Fix the case discovered by Hiroyuki Iwatsuki where stowing fails + if the stow / target directories are non-canonical paths. For + example, on FreeBSD /home is a symlink pointing to 'usr/home', so + running with the stow directory as /home/user/local/stow and the + target directory as /home/user/local previously resulted in the + stow directory path being calculated as + ../../../usr/home/user/local/stow relative to the target. + + http://article.gmane.org/gmane.comp.gnu.stow.bugs/8820 + + + M lib/Stow.pm.in + +Thu Jan 17 12:25:43 2013 +0000 Adam Spiers + + * default-ignore-list: ignore top-level README.*, LICENSE.*, and COPYING + These files are by definition specific to a given package, so if + they exist in the top-level directory, they should not be stowed. + + + M default-ignore-list + +Mon Jul 9 01:06:13 2012 +0100 Adam Spiers + + * Only include $! in error messages for failed syscalls. + + M lib/Stow.pm.in + M lib/Stow/Util.pm + +Mon Jul 9 01:05:27 2012 +0100 Adam Spiers + + * Fix RT ticket #75349 https://rt.cpan.org/Ticket/Display.html?id=75349 + + + M bin/stow.in + +Wed May 16 11:00:38 2012 +0100 Adam Spiers + + * Bug #36478 - fix Perl warnings from 'require 5.6.1;' + https://savannah.gnu.org/bugs/?36478 + + + M bin/chkstow.in + M bin/stow.in + +Thu Mar 1 11:40:34 2012 +0000 Adam Spiers + + * Revamp README. + + M README + +Sun Feb 19 19:15:48 2012 +0000 Adam Spiers + + * Remove accidentally duplicated code. + + M t/examples.t + +Sun Feb 19 11:54:53 2012 +0000 Adam Spiers + + * Improve docs for path_owned_by_package() + + M lib/Stow.pm.in + +Sun Feb 19 01:42:10 2012 +0000 Adam Spiers + + * Fix typo in manual. + + M doc/stow.texi + +Sun Feb 19 01:42:04 2012 +0000 Adam Spiers + + * Add a few more items to index. + + M doc/stow.texi + +Sat Feb 18 20:43:20 2012 +0000 Adam Spiers + + * Add boilerplate commit message for web docs update. + + M doc/HOWTO-RELEASE + +Sat Feb 18 17:08:19 2012 +0000 Adam Spiers + + * Bump version to 2.2.0 + + M META.json + M META.yml + M NEWS + M configure.ac + +Sat Feb 18 20:13:32 2012 +0000 Adam Spiers + + * Add --no-folding option. + + M NEWS + M bin/stow.in + M doc/stow.texi + M lib/Stow.pm.in + M t/stow.t + M t/testutil.pm + M t/unstow.t + +Sat Feb 18 14:20:07 2012 +0000 Adam Spiers + + * Remove -a option for safety reasons (but keep --adopt). + + M NEWS + M bin/stow.in + M doc/stow.texi + +Sat Feb 18 20:12:14 2012 +0000 Adam Spiers + + * Improve error message when package is not found. + + M NEWS + M lib/Stow.pm.in + +Sat Feb 18 20:19:05 2012 +0000 Adam Spiers + + * Use make_invalid_link() to reliably setup symlink fixtures. + + M NEWS + M t/chkstow.t + M t/cleanup_invalid_links.t + M t/stow.t + M t/testutil.pm + M t/unstow.t + M t/unstow_orig.t + +Sat Feb 18 15:47:36 2012 +0000 Adam Spiers + + * Add documentation improvements to NEWS. + + M NEWS + +Sat Feb 18 17:07:15 2012 +0000 Adam Spiers + + * Update TODO + + M TODO + +Sat Feb 18 20:32:40 2012 +0000 Adam Spiers + + * Last known bug was fixed a long time ago :-) + + M doc/stow.texi + +Sat Feb 18 15:47:19 2012 +0000 Adam Spiers + + * Update structure of manual to match recommended texinfo structure. TOC + now appears after title page. Copying information is no longer + duplicated. + + + M doc/stow.texi + +Sat Feb 18 15:46:14 2012 +0000 Adam Spiers + + * Fix various formatting issues in the manual. + + M doc/stow.texi + +Sat Feb 18 15:45:49 2012 +0000 Adam Spiers + + * Add some more index entries to the manual. + + M doc/stow.texi + +Sat Feb 18 15:45:16 2012 +0000 Adam Spiers + + * Add some @sections to the manual to break larger nodes up. + + M doc/stow.texi + +Sat Feb 18 15:17:21 2012 +0000 Adam Spiers + + * Use @command / @samp / @env / @var in the manual where appropriate, + rather than @code. + + M doc/stow.texi + +Sat Feb 18 15:03:52 2012 +0000 Adam Spiers + + * Fix formatting of regexp values in the manual. + + M doc/stow.texi + +Sat Feb 18 14:15:14 2012 +0000 Adam Spiers + + * Add --adopt to usage text. + + M bin/stow.in + +Sat Feb 18 14:11:33 2012 +0000 Adam Spiers + + * Improve ordering of options in usage text. + + M bin/stow.in + +Sat Feb 18 14:08:17 2012 +0000 Adam Spiers + + * Add missing options to pod, and reference to front-end documentation. + + M lib/Stow.pm.in + +Sat Feb 18 14:07:45 2012 +0000 Adam Spiers + + * Ignore tmp-testing-trees anywhere. + + M .gitignore + M MANIFEST.SKIP + +Sat Feb 18 12:28:00 2012 +0000 Adam Spiers + + * Make shared library tests match real-world scenarios. Typically, + libfoo.so.X.Y.Z is the file, and libfoo.so is the symlink which + points to it. + + + M t/stow.t + +Sat Feb 18 11:53:46 2012 +0000 Adam Spiers + + * Include --simulate in usage text. + + M bin/stow.in + +Fri Jan 13 11:34:55 2012 +0000 Adam Spiers + + * Avoid "Use of uninitialized value" warnings from test suite. Happened + on some versions of Perl when TEST_VERBOSE not yet. Thanks Adam + Sampson! + + + M lib/Stow.pm.in + +Thu Jan 12 17:54:32 2012 +0000 Adam Spiers + + * Remove reference to old FSF address (thank you rpmlint for catching + this!) + + M bin/stow.in + +Wed Jan 11 14:01:40 2012 +0000 Adam Spiers + + * Remove "There are no outstanding operations to perform" warning. This + is more in keeping with the UNIX convention of no output on + success, and is also the way Stow v1.x behaved. Thanks to Adam + Sampson for the suggestion. + + + M NEWS + M THANKS + M lib/Stow.pm.in + M t/stow.t + M t/unstow.t + M t/unstow_orig.t + +Tue Jan 10 12:17:58 2012 +0000 Adam Spiers + + * Fix wrong version number in NEWS. + + M NEWS + +Mon Jan 9 21:39:35 2012 +0000 Adam Spiers + + * Bump version to 2.1.3 + + M META.json + M META.yml + M NEWS + M configure.ac + +Mon Jan 9 21:32:31 2012 +0000 Adam Spiers + + * Rename test files to reflect their purpose. + + M MANIFEST + A t/stow.t + D t/stow_contents.t + A t/unstow.t + D t/unstow_contents.t + D t/unstow_contents_orig.t + A t/unstow_orig.t + +Mon Jan 9 21:31:46 2012 +0000 Adam Spiers + + * Rename stow.t to be more consistent with its purpose. + + M MANIFEST + A t/cli_options.t + D t/stow.t + +Mon Jan 9 22:10:19 2012 +0000 Adam Spiers + + * perl Build.PL needs a prefix during testing + + M doc/HOWTO-RELEASE + +Mon Jan 9 21:25:35 2012 +0000 Adam Spiers + + * Add --adopt / -a option. + + M NEWS + M bin/stow.in + M doc/stow.texi + M lib/Stow.pm.in + M lib/Stow/Util.pm + M t/stow_contents.t + M t/testutil.pm + +Mon Jan 9 21:11:58 2012 +0000 Adam Spiers + + * Add stacktrace to internal error report to aid debugging. + + M lib/Stow.pm.in + +Mon Jan 9 18:32:06 2012 +0000 Adam Spiers + + * Use get_conflict_count() in tests since get_conflicts() no longer + returns a flat structure. + + M t/cleanup_invalid_links.t + M t/examples.t + M t/stow_contents.t + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Mon Jan 9 17:52:11 2012 +0000 Adam Spiers + + * Link to website to encourage users to report bugs. + + M lib/Stow.pm.in + +Mon Jan 9 16:42:40 2012 +0000 Adam Spiers + + * Improve readability of NEWS file when viewed raw. + + M NEWS + +Mon Jan 9 16:25:27 2012 +0000 Adam Spiers + + * Improve existing comments. + + M lib/Stow.pm.in + +Wed Dec 21 11:45:59 2011 +0000 Adam Spiers + + * Improve the footnote which defines 'subpath'. + + M doc/stow.texi + +Wed Dec 21 11:45:43 2011 +0000 Adam Spiers + + * Add another ignore example to the manual and test suite. + + M doc/stow.texi + M t/ignore.t + +Thu Dec 15 21:14:07 2011 +0000 Adam Spiers + + * Fix some incorrect CPAN meta-data about the project. + + M Build.PL + M META.json + M META.yml + +Tue Dec 13 16:12:29 2011 +0000 Adam Spiers + + * Make configure check for Perl modules required by test suite. + + M NEWS + M configure.ac + +Sun Dec 11 13:23:37 2011 +0000 Adam Spiers + + * Make stow script return true for t/stow.t According to + http://matrix.cpantesters.org/?dist=Stow this only seems to be an + issue with Perl <= 5.8.7. + + + M bin/stow.in + +Sun Dec 11 13:12:32 2011 +0000 Adam Spiers + + * Automate check for 'use lib' line in bin/stow. + + M Build.PL + M doc/HOWTO-RELEASE + +Tue Dec 6 18:30:28 2011 +0000 Adam Spiers + + * Bump version to 2.1.2. + + M META.json + M META.yml + M configure.ac + +Wed Dec 7 20:28:28 2011 +0000 Adam Spiers + + * Significantly improve the handling of --with-pmdir. + + M INSTALL + M Makefile.am + M NEWS + M bin/stow.in + M configure.ac + M doc/HOWTO-RELEASE + +Wed Dec 7 01:20:07 2011 +0000 Adam Spiers + + * Make capitalisation consistent in usage text. + + M bin/stow.in + +Wed Dec 7 20:31:18 2011 +0000 Adam Spiers + + * Abort ./configure if we can't find Perl. + + M NEWS + M configure.ac + +Wed Dec 7 01:23:41 2011 +0000 Adam Spiers + + * Ensure the ChangeLog is up-to-date when making a new distribution. + Thanks to Stefano Lattarini for this suggestion. + + + M Makefile.am + M NEWS + M doc/HOWTO-RELEASE + +Wed Dec 7 00:38:16 2011 +0000 Adam Spiers + + * Use maintainer-clean-local rule, not maintainer-clean. + + M Makefile.am + +Tue Dec 6 18:20:03 2011 +0000 Adam Spiers + + * `make clean' shouldn't remove files which the user may not be able to + rebuild. + + M Makefile.am + +Tue Dec 6 10:35:31 2011 +0000 Adam Spiers + + * Bump version to 2.1.1 + + M META.json + M META.yml + M NEWS + M configure.ac + +Tue Dec 6 17:33:41 2011 +0000 Adam Spiers + + * Ignore .mrdownload files from my `download' plugin to Joey Hess' mr + utility. + + M MANIFEST.SKIP + +Tue Dec 6 17:30:58 2011 +0000 Adam Spiers + + * Add a workaround for not being able to ensure that git commit triggers + ChangeLog update. + + M doc/HOWTO-RELEASE + +Tue Dec 6 17:24:44 2011 +0000 Adam Spiers + + * Show when ChangeLog is rebuilt. + + M Makefile.am + +Tue Dec 6 17:22:21 2011 +0000 Adam Spiers + + * Fix release instructions regarding CPAN distribution. + + M doc/HOWTO-RELEASE + +Tue Dec 6 17:08:21 2011 +0000 Adam Spiers + + * Refill paragraph in README. + + M README + +Tue Dec 6 17:08:13 2011 +0000 Adam Spiers + + * Don't duplicate information from INSTALL. + + M README + +Tue Dec 6 17:07:29 2011 +0000 Adam Spiers + + * Document installation via Module::Build. + + M INSTALL + +Tue Dec 6 17:06:59 2011 +0000 Adam Spiers + + * Document prerequisites for installation. + + M INSTALL + +Tue Dec 6 17:04:50 2011 +0000 Adam Spiers + + * chkstow was missing from Module::Build install. + + M Build.PL + +Tue Dec 6 17:04:37 2011 +0000 Adam Spiers + + * File::Slurp is no longer used. + + M Build.PL + M META.json + M META.yml + +Tue Dec 6 16:20:52 2011 +0000 Adam Spiers + + * Fix automake issues (thanks to Stefano Lattarini for spotting these!) + + M Build.PL + M Makefile.am + M NEWS + M THANKS + +Tue Dec 6 16:47:32 2011 +0000 Adam Spiers + + * Add $(PDF) and $(HTML) variables. + + M Makefile.am + +Tue Dec 6 16:39:57 2011 +0000 Adam Spiers + + * Add *.orig to MANIFEST.SKIP. + + M MANIFEST.SKIP + +Tue Dec 6 15:57:36 2011 +0000 Adam Spiers + + * Ditch deprecated AM_MAINTAINER_MODE. + + M aclocal.m4 + M configure.ac + +Tue Dec 6 15:56:43 2011 +0000 Adam Spiers + + * Add licensing changes to TODO. + + M TODO + +Tue Dec 6 15:41:33 2011 +0000 Adam Spiers + + * Add bug-reporting email address and a couple of URLs to usage text to + comply with GNU Coding Standards for --help option. + + M bin/stow.in + +Tue Dec 6 15:57:20 2011 +0000 Adam Spiers + + * Calculated the correct default value for pmdir based on the local Perl + installation. + + M NEWS + M configure.ac + +Tue Dec 6 10:33:34 2011 +0000 Adam Spiers + + * Fixed bug where --with-pmdir was ineffectual. + + M Makefile.am + M NEWS + M configure.ac + +Sun Dec 4 14:57:34 2011 +0000 Adam Spiers + + * Change @dircategory to `System administration' as suggested by Karl + Berry. + + M doc/stow.texi + +Sat Dec 3 18:13:09 2011 +0000 Adam Spiers + + * Add git push and update of online documentation to HOWTO-RELEASE. + + M doc/HOWTO-RELEASE + +Sat Dec 3 17:51:48 2011 +0000 Adam Spiers + + * Release announcements should go to stow-devel too. + + M doc/HOWTO-RELEASE + +Sat Dec 3 17:51:44 2011 +0000 Adam Spiers + + * Fix error in gnupload command-line. + + M doc/HOWTO-RELEASE + +Sat Dec 3 17:09:48 2011 +0000 Adam Spiers + + * Add a missing space. + + M AUTHORS + +Sat Dec 3 16:40:20 2011 +0000 Adam Spiers + + * Add a missing hyperlink to the Stow homepage. + + M doc/stow.texi + +Sat Dec 3 14:03:58 2011 +0000 Adam Spiers + + * Give up on automake's built-in rules for generating PDF and HTML and + use our own. Also include split version of the manual. + + M .gitignore + M MANIFEST + M MANIFEST.SKIP + M Makefile.am + M NEWS + +Sat Dec 3 02:07:19 2011 +0000 Adam Spiers + + * Update reference to maintainer. + + M AUTHORS + M README + M doc/stow.texi + +Sat Dec 3 01:30:08 2011 +0000 Adam Spiers + + * Temporarily remove PDF from dist_doc_DATA due to automake issue. + http://article.gmane.org/gmane.comp.sysutils.automake.general/13192 + + This means that it is still included in the distribution and + installed, but is only automatically (re)built when making a new + distribution - if stow.texi changes during development, it has to + be rebuilt manually via 'make pdf'. + + + M MANIFEST + M MANIFEST.SKIP + M Makefile.am + +Sat Dec 3 00:54:05 2011 +0000 Adam Spiers + + * Module::Build generates archive files with 'v' for version + + M MANIFEST.SKIP + +Fri Dec 2 14:55:44 2011 +0000 Adam Spiers + + * Add TODOs for .rpm and .deb support. + + M TODO + +Thu Dec 1 18:03:16 2011 +0000 Adam Spiers + + * Add doc/version.texi to distribution. + + M Makefile.am + +Thu Dec 1 17:25:24 2011 +0000 Adam Spiers + + * Switch to renaming to manual via install hook as suggested by Stefano + Lattarini + http://article.gmane.org/gmane.comp.sysutils.automake.general/13191 + + + M MANIFEST + M MANIFEST.SKIP + M Makefile.am + +Thu Dec 1 16:23:04 2011 +0000 Adam Spiers + + * Fix corner case where only -d is specified as a single directory. + + M bin/stow.in + +Mon Nov 28 23:20:14 2011 +0000 Adam Spiers + + * Add result of ./Build dist to .gitignore + + M .gitignore + +Mon Nov 28 23:18:58 2011 +0000 Adam Spiers + + * Synchronise CPAN MANIFEST files with automake distribution list. + + M MANIFEST + M MANIFEST.SKIP + +Mon Nov 28 23:18:36 2011 +0000 Adam Spiers + + * Ignore split page version of HTML manual. + + M .gitignore + +Mon Nov 28 23:17:50 2011 +0000 Adam Spiers + + * Don't duplicate stow.texi to manual.texi. + + M MANIFEST + M MANIFEST.SKIP + M Makefile.am + +Sat Nov 26 18:55:10 2011 +0000 Adam Spiers + + * Improve debug levels. + + M lib/Stow.pm.in + M lib/Stow/Util.pm + +Sat Nov 26 18:24:35 2011 +0000 Adam Spiers + + * Add a TODO concerning .nonstow. + + M TODO + +Sat Nov 26 18:15:26 2011 +0000 Adam Spiers + + * Add HOWTO-RELEASE + + A doc/HOWTO-RELEASE + +Thu Nov 24 01:27:41 2011 +0000 Adam Spiers + + * Add NEWS entry for 2.1.0 + + M NEWS + +Thu Nov 24 00:26:50 2011 +0000 Adam Spiers + + * Bump version to 2.1.0 + + M META.json + M META.yml + M configure.ac + +Fri Nov 25 15:23:08 2011 +0000 Adam Spiers + + * Fix documentation regarding splitting of symlinks across multiple stow + directories. + + M doc/stow.texi + M lib/Stow.pm.in + +Fri Nov 25 15:14:07 2011 +0000 Adam Spiers + + * Tidy up chkstow code and documentation. + + M bin/chkstow.in + M doc/stow.texi + +Fri Nov 25 15:03:46 2011 +0000 Adam Spiers + + * Add chkstow to NEWS + + M NEWS + +Fri Nov 25 14:45:28 2011 +0000 Adam Spiers + + * Add comment to manual about test_examples_in_manual() in t/ignore.t. + + M doc/stow.texi + +Sat Nov 26 16:32:25 2011 +0000 Adam Spiers + + * Remove quote stripping code. I'm guessing it was added due to a + misunderstanding of how shell quoting works. When you invoke + + stow --ignore=".#.*" ... + + the shell strips out the quotes before the Perl process ever sees + them. I can't imagine any sensible scenario in which you would + need to invoke + + stow --ignore='"foo"' + + but if the user has a filename containing quotes at the beginning + and end, they can now choose to ignore it (prior to this patch, + they couldn't). + + + M bin/stow.in + M t/stow.t + +Thu Nov 24 22:49:22 2011 +0000 Adam Spiers + + * Improve conflict reporting + + M bin/stow.in + M lib/Stow.pm.in + M t/stow_contents.t + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Thu Nov 24 18:05:57 2011 +0000 Adam Spiers + + * Sync up .gitignore and MANIFEST* with recent changes. + + M .gitignore + M MANIFEST + M MANIFEST.SKIP + +Thu Nov 24 20:47:39 2011 +0000 Adam Spiers + + * Ditch obsolete --conflicts option and update misleading documentation. + + M bin/stow.in + M doc/stow.texi + M lib/Stow.pm.in + +Thu Nov 24 17:00:33 2011 +0000 Adam Spiers + + * Auto-generate ChangeLog from git + + M .gitignore + D ChangeLog + M Makefile.am + A doc/ChangeLog.OLD + +Thu Nov 24 16:59:45 2011 +0000 Adam Spiers + + * Sort .gitignore alphabetically + + M .gitignore + +Thu Nov 24 16:59:26 2011 +0000 Adam Spiers + + * Add some missing stuff to .gitignore + + M .gitignore + +Thu Nov 24 16:22:11 2011 +0000 Adam Spiers + + * Distribute .tar.gz and .tar.bz2 but not .shar.gz + + M Makefile.am + M configure.ac + +Thu Nov 24 16:32:01 2011 +0000 Adam Spiers + + * Numerous fixes so that `make distcheck' succeeds. Moves temporary test + trees into a separate directory. + + M .gitignore + M Makefile.am + M configure.ac + M t/chkstow.t + M t/cleanup_invalid_links.t + M t/defer.t + M t/examples.t + M t/find_stowed_path.t + M t/foldable.t + M t/ignore.t + M t/stow.t + M t/stow_contents.t + M t/testutil.pm + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Thu Nov 24 00:45:29 2011 +0000 Adam Spiers + + * Strip superfluous quotes from $hash{'lookups'} + + M bin/stow.in + M lib/Stow.pm.in + M t/chkstow.t + M t/stow.t + +Thu Nov 24 17:15:02 2011 +0000 Adam Spiers + + * Tidy up the copyright attributions in the manual. + + M doc/stow.texi + +Thu Nov 24 17:14:51 2011 +0000 Adam Spiers + + * Fix some minor issues in the manual. + + M doc/stow.texi + +Thu Nov 24 17:33:36 2011 +0000 Adam Spiers + + * Add HTML and PDF versions of manual to distribution. + + M .gitignore + M Makefile.am + +Wed Nov 23 23:45:48 2011 +0000 Adam Spiers + + * Add support for ignore lists. + + M AUTHORS + M Makefile.am + M TODO + A default-ignore-list + M doc/stow.texi + M lib/Stow.pm.in + M lib/Stow/Util.pm + M t/chkstow.t + M t/cleanup_invalid_links.t + M t/examples.t + M t/find_stowed_path.t + M t/foldable.t + A t/ignore.t + M t/stow.t + M t/stow_contents.t + M t/testutil.pm + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Tue Nov 22 15:59:07 2011 +0000 Adam Spiers + + * Rename $old_* to $existing_* + + M lib/Stow.pm.in + +Tue Nov 22 15:50:12 2011 +0000 Adam Spiers + + * Rename protected_dir() to marked_stow_dir(). + + M lib/Stow.pm.in + +Tue Nov 22 15:48:08 2011 +0000 Adam Spiers + + * Rename should_skip_stow_dir_target() to + should_skip_target_which_is_stow_dir() + + M lib/Stow.pm.in + +Tue Nov 22 15:46:05 2011 +0000 Adam Spiers + + * Be clearer when we're not actually (un)stowing, just planning. + + M lib/Stow.pm.in + +Tue Nov 22 14:29:52 2011 +0000 Adam Spiers + + * Add another test to join_paths.t + + M t/join_paths.t + +Tue Nov 22 14:29:42 2011 +0000 Adam Spiers + + * Clean up coding style in tests + + M t/chkstow.t + M t/cleanup_invalid_links.t + M t/find_stowed_path.t + M t/join_paths.t + M t/parent.t + +Tue Nov 22 14:28:37 2011 +0000 Adam Spiers + + * Avoid use of map in void context + + M bin/stow.in + +Mon Nov 21 23:24:02 2011 +0000 Adam Spiers + + * Add a comment about a relative weakness of compat mode. + + M lib/Stow.pm.in + +Mon Nov 21 23:23:43 2011 +0000 Adam Spiers + + * Test stow/unstow with stow dir / target dir as absolute paths. + + M t/stow_contents.t + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Mon Nov 21 23:21:48 2011 +0000 Adam Spiers + + * Fix more inconsistencies in coding style. + + M lib/Stow.pm.in + +Mon Nov 21 23:15:47 2011 +0000 Adam Spiers + + * Fix typos + + M lib/Stow.pm.in + +Mon Nov 21 22:08:52 2011 +0000 Adam Spiers + + * Fix/remove some outdated TODOs + + M TODO + +Mon Nov 21 18:04:58 2011 +0000 Adam Spiers + + * Add build-time dependencies on Test::More and Test::Output. + + M Build.PL + M META.json + M META.yml + M TODO + +Mon Nov 21 14:48:58 2011 +0000 Adam Spiers + + * Add MYMETA.* to .gitignore + + M .gitignore + +Mon Nov 21 14:46:27 2011 +0000 Adam Spiers + + * Add .dirstamp and stamp-vti to .gitignore + + M .gitignore + +Thu Nov 24 16:52:50 2011 +0000 Adam Spiers + + * Convert man page to POD format which is easier to maintain within + stow.in. + + M .gitignore + M Makefile.am + M bin/stow.in + D doc/stow.8 + +Mon Nov 21 13:59:36 2011 +0000 Adam Spiers + + * Reorganise more files into subdirectories and add CPAN support via + Module::Build + + A Build.PL + A MANIFEST + A MANIFEST.SKIP + A META.json + A META.yml + M Makefile.am + A automake/install-sh + A automake/mdate-sh + A automake/missing + A bin/chkstow.in + A bin/stow.in + D chkstow.in + M configure.ac + A doc/stow.8 + A doc/stow.texi + A doc/texinfo.tex + D install-sh + D mdate-sh + D missing + D stow.8 + D stow.in + D stow.texi + D texinfo.tex + +Mon Nov 21 14:07:39 2011 +0000 Adam Spiers + + * Add myself (Adam) to AUTHORS and THANKS ;-) + + M AUTHORS + M THANKS + +Thu Nov 24 16:28:09 2011 +0000 Adam Spiers + + * Major refactoring of code into separate Stow and Stow::Util Perl + modules + + M .gitignore + M Makefile.am + M TODO + M configure.ac + A lib/Stow.pm.in + A lib/Stow/Util.pm + M stow.in + M t/chkstow.t + M t/cleanup_invalid_links.t + M t/defer.t + M t/examples.t + M t/find_stowed_path.t + M t/foldable.t + M t/join_paths.t + M t/parent.t + M t/stow.t + M t/stow_contents.t + A t/testutil.pm + M t/unstow_contents.t + M t/unstow_contents_orig.t + D t/util.pm + +Fri Nov 18 15:09:39 2011 +0000 Adam Spiers + + * Fix indentation in Makefile.am + + M Makefile.am + +Fri Nov 18 11:24:36 2011 +0000 Adam Spiers + + * Test unstowing when target contains a real file generates a conflict. + + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Thu Nov 17 20:11:06 2011 +0000 Adam Spiers + + * Test unstowing stuff which doesn't exist in the target tree. + + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Thu Nov 17 20:11:32 2011 +0000 Adam Spiers + + * Add a missing conflict if we tried to unstow a file in compat mode. + + M stow.in + +Fri Nov 18 12:00:05 2011 +0000 Adam Spiers + + * Remove setting of verbosity from tests + + M t/cleanup_invalid_links.t + M t/examples.t + M t/foldable.t + M t/stow_contents.t + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Fri Nov 18 11:14:50 2011 +0000 Adam Spiers + + * Make 'verbose' option default to 0 in testmode. + + M stow.in + +Fri Nov 18 10:48:48 2011 +0000 Adam Spiers + + * Add protection against stowing into stow dirs + + M stow.in + M t/stow_contents.t + +Fri Nov 18 10:34:23 2011 +0000 Adam Spiers + + * Debug stow dir in stow/unstow contents routines + + M stow.in + +Fri Nov 18 10:33:08 2011 +0000 Adam Spiers + + * Trace individual cases separately when skipping stow dirs during + unstow. + + M stow.in + +Fri Nov 18 10:29:15 2011 +0000 Adam Spiers + + * Allow TEST_VERBOSE to control level of verbosity. Defaults to 3. + 'verbose' option now has precedence if set. + + M stow.in + +Thu Nov 17 20:32:48 2011 +0000 Adam Spiers + + * Debug when skipping over stow directories + + M stow.in + +Thu Nov 17 20:10:42 2011 +0000 Adam Spiers + + * Add debug when target to be unstowed doesn't exist + + M stow.in + +Thu Nov 17 20:09:42 2011 +0000 Adam Spiers + + * Add comments justifying is_a_node($target) check in unstow_contents(). + + M stow.in + +Thu Nov 17 19:33:09 2011 +0000 Adam Spiers + + * Test unstowing an already unstowed package + + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Thu Nov 17 19:10:02 2011 +0000 Adam Spiers + + * Fix incorrect comments. + + M stow.in + +Thu Nov 17 19:04:10 2011 +0000 Adam Spiers + + * Sync t/unstow_contents{,_orig}.t + + M t/unstow_contents_orig.t + +Thu Nov 17 18:46:32 2011 +0000 Adam Spiers + + * Debug with maximum verbosity to STDOUT when running tests. + + M stow.in + M t/util.pm + +Thu Nov 17 18:46:13 2011 +0000 Adam Spiers + + * Refactored reset_state() into t/util.pm + + M t/cleanup_invalid_links.t + M t/examples.t + M t/stow_contents.t + M t/unstow_contents.t + M t/unstow_contents_orig.t + M t/util.pm + +Thu Nov 17 18:24:53 2011 +0000 Adam Spiers + + * Refactored is_a_{link,dir,node}() code. + + M stow.in + +Thu Nov 17 17:23:04 2011 +0000 Adam Spiers + + * Improve tree splitting comments. + + M stow.in + +Thu Nov 17 16:39:02 2011 +0000 Adam Spiers + + * Don't tolerate '' as value for $target parameter to (un)stow_contents + + M stow.in + M t/stow_contents.t + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Thu Nov 17 16:37:37 2011 +0000 Adam Spiers + + * Add debug tracing to helper routines + + M stow.in + +Thu Nov 17 16:35:57 2011 +0000 Adam Spiers + + * Fix Parameters comments. + + M stow.in + +Thu Nov 17 19:47:20 2011 +0000 Adam Spiers + + * Improve debug output + + M stow.in + +Thu Nov 17 15:32:51 2011 +0000 Adam Spiers + + * Clarify meaning of `--defer' in the manual. + + M stow.texi + +Thu Nov 17 15:22:58 2011 +0000 Adam Spiers + + * Finish "Deferred Operation" section in manual. + + M TODO + M stow.texi + +Thu Nov 17 14:17:24 2011 +0000 Adam Spiers + + * Fix inconsistencies in coding style. + + M stow.in + M t/util.pm + +Thu Nov 17 14:12:14 2011 +0000 Adam Spiers + + * Set cperl-indent-level to 4 + + M stow.in + +Thu Nov 17 14:12:12 2011 +0000 Adam Spiers + + * Simplify GetOptions() code + + M stow.in + +Thu Nov 17 13:26:04 2011 +0000 Adam Spiers + + * Refactor verbosity-controlled output to STDERR into debug() + subroutine. + + M stow.in + +Thu Nov 17 12:45:36 2011 +0000 Adam Spiers + + * Fix broken 'make install' due to man page being duplicated in + install-man8 target + + M Makefile.am + +Wed Nov 16 16:52:03 2011 +0000 Adam Spiers + + * Stow directory now defaults to STOW_DIR environment variable if set. + + M ChangeLog + M stow.8 + M stow.in + M stow.texi + +Wed Nov 16 15:57:17 2011 +0000 Adam Spiers + + * Use File::Spec->abs2rel() instead of home-grown relative_path which + actually gets some inputs wrong (e.g. "/" relative to "/") + + M Makefile.am + M stow.in + D t/relative_path.t + +Wed Nov 16 15:51:54 2011 +0000 Adam Spiers + + * Add a bunch of stuff to the TODO + + M TODO + +Wed Nov 16 15:42:42 2011 +0000 Adam Spiers + + * Add FIXME for Deferred Operation section in manual. + + M TODO + M stow.texi + +Wed Nov 16 15:40:46 2011 +0000 Adam Spiers + + * Fix indentation issues in NEWS + + M NEWS + +Wed Nov 16 15:38:47 2011 +0000 Adam Spiers + + * Switch NEWS and TODO to org-mode. org-mode has been included in emacs + by default for a long time and is much more friendly than + outline-mode. No impact to non-emacs users. + + + M NEWS + M TODO + +Wed Nov 16 15:22:12 2011 +0000 Adam Spiers + + * Stow now requires Perl 5.6.1 or newer, due to use of 'our'. + + M README + M chkstow.in + M stow.in + +Wed Nov 16 15:20:21 2011 +0000 Adam Spiers + + * Troy is the maintainer now. + + M AUTHORS + M README + M TODO + M stow.texi + +Wed Nov 16 14:59:58 2011 +0000 Adam Spiers + + * Fix typos + + M AUTHORS + M TODO + M stow.in + M stow.texi + M t/relative_path.t + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Wed Nov 16 15:16:53 2011 +0000 Adam Spiers + + * Catch warnings in tests when no outstanding operations to perform. + Tests now all pass completely cleanly. + + M t/stow_contents.t + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Wed Nov 16 15:07:26 2011 +0000 Adam Spiers + + * Fix %Options typo in several tests + + M t/cleanup_invalid_links.t + M t/examples.t + M t/stow_contents.t + M t/unstow_contents.t + M t/unstow_contents_orig.t + +Wed Nov 16 15:04:21 2011 +0000 Adam Spiers + + * Fix t/stow.t + + M t/stow.t + +Wed Nov 16 14:51:38 2011 +0000 Adam Spiers + + * Fix chkstow.t + + M chkstow.in + M t/chkstow.t + +Wed Nov 16 14:46:31 2011 +0000 Adam Spiers + + * Add #! header to t/util.pm for benefit of editor mode selection + + M t/util.pm + +Wed Nov 16 14:45:56 2011 +0000 Adam Spiers + + * Fix chkstow.in for emacs users + + M chkstow.in + +Wed Nov 16 14:34:02 2011 +0000 Adam Spiers + + * Support ./configure --disable-maintainer-mode to optionally avoid + auto-reconfiguring on make. + + M aclocal.m4 + M configure.ac + +Wed Nov 16 14:31:32 2011 +0000 Adam Spiers + + * Run autoreconf with more recent GNU autotools. + + M aclocal.m4 + +Wed Nov 16 14:30:55 2011 +0000 Adam Spiers + + * Add test target to Makefile + + M Makefile.am + +Thu Nov 24 16:55:43 2011 +0000 Adam Spiers + + * Remove auto-generated files from git. + + M .gitignore + D Makefile.in + D configure + D stamp-vti + D stow.info + D version.texi + +Wed Nov 16 14:30:39 2011 +0000 Adam Spiers + + * Add .gitignore + + A .gitignore + +Sun Apr 12 23:04:33 2009 -0700 Troy Will + + * made numeric argument to --verbose optional + + M stow.in + +Sun Apr 12 21:59:24 2009 -0700 Troy Will + + * Remove stow, config.status, config.log, Makefile + + D Makefile + D config.log + D config.status + D stow +Thu Jan 31 2008 Kahlil Hodgson + + * stow.texi: Austin Wood and Chris Hoobin clean this up for version 2. + + * texi2man: new script by Austin and Chris to generate a man page from the + texinfo file. + + +Sun Nov 25 19:31:32 2007 Kahlil Hodgson + * all: Version 2.0.1 + + * AUTHORS: added Kahlil Hodgson as a new author and current maintainer. + + * stow.in: major rewrite to produce version 2.0.1 see NEWS for details + + * t/: added test suite and support code + + * configure.in: renamed to configure.ac as per autotools recommendation. + + * configure.ac: + Use AC_INT rather than obsolete AM_INTI_MAKEFILE usage. + Remove redundant VERSION and PACKAGE setttings + Remove redundant AC_ARG_PROGRAM + Use AM_INIT_AUTOMAKE([-Wall -Werror]) because we are pedantic. + Add AC_PREREQ([2.6.1]) + + * Makefile.am, configure.ac: + Use explicit rewrite in Makefile.am, rather than AC_CONFIG_FILES(stow.in), + as per autotools recommendation. + + * Makefile.am: + Add TESTS and TEST_ENVIRONMENT for files in t/ + Use dist_man_MANS instead of EXTRA_DIST for man page + + * INSTALL: update to reflect autotools modernization. + + * NEWS: update to describe cahnges in Version 2.0.1. + + * README: update to point to the right websites and email addresses. + + * THANKS: + Add Emil Mikulc who's ideas largely inspired Version 2 and + and Geoffrey Giesemann who did some initial testing and found some + important bugs. + + * TODO: remove tasks that where implemented in Version 2 + + * stow.texi: update documentation to reflect Version 2 changes. + + * stow.8: update to reflect Version 2 changes. + +Sat Jan 26 16:15:21 2002 Guillaume Morin + + * stow.in: if $ENV{'STOW_DIR'} is set, this becomes the default + Stow directory. + +Sun Jan 06 12:18:50 2002 Guillaume Morin + + * Makefile.am: use EXTRA_DIST to include manpage in distribution + +Wed Jan 02 21:33:41 2002 Guillaume Morin + + * stow.in: Stow now only warns the user if a subdirectory + is unreadable during unstowing. + +Wed Jan 02 20:58:05 2002 Guillaume Morin + + * stow.in: fixed JoinPaths so that subdirs called "0" are + correctly pushed. Thanks a lot to Gergely Nagy + who patiently helped me to chase + this bug. + +Sun Dec 30 21:58:25 2001 Guillaume Morin + + * stow.in: fixed a bug introduced by previous changes when + Target argument was relative. (thanks to Luca Filipozzi + for pointing this out) + +Sun Dec 30 18:23:25 2001 Guillaume Morin + + * stow.in: now requires Perl 5. Use POSIX getcwd instead of broken + fastcwd. Fixed bug when CommonParent is /. Stow does not remove + initially empty directories anymore. + +Sun Dec 30 18:07:51 2001 Guillaume Morin + + * configure.in: automake fixes (fp_ -> AC, +AC_INIT_AUTOMAKE) + +Fri Oct 11 22:09:45 1996 Bob Glickstein + + * stow.html, configure.in: Version 1.3.2. + + * README, stow.texi: Correct the URL again. + +Fri Oct 11 18:20:42 1996 Bob Glickstein + + * configure.in: Version 1.3.1. + + * stow.html: Update Stow manual URL. Mention version 1.3.1. + + * README: Update Stow URL. + + * Makefile.am: stow-manual.html -> manual.html. + + * stow.texi: + Add a reference to the Stow home page on the GNU web server. Change + several occurrences of "which" to "that" for grammatical superiority. + +Wed Oct 9 00:34:07 1996 Bob Glickstein + + * Makefile.am: + Add maintainer-only rules for stow-manual.html and stow-manual.texi. + +Wed Oct 9 00:32:31 1996 Bob Glickstein + + * README: Refer to the new location for the Stow home page. + + * stow.html: Make it right for the GNU web server. + +Tue Oct 8 21:54:09 1996 Bob Glickstein + + * stow.texi: Document --restow + + * stow.in: Add --restow (-R) option + + * configure.in: Add "perl4" to search for Perl binary. + Bump version number to 1.3. + +Mon Jun 24 23:23:03 1996 Bob Glickstein + + * stow.texi: Delete trailing whitespace. + +Fri Jun 21 19:44:26 1996 Bob Glickstein + + * Makefile.am: + Don't explicitly mention version.texi. Automake now does it + automagically, by noticing the `@include version.texi' in + stow.texi. Awesome. + + * stow.texi: + Use @include instead of @input. This is more Texinfoid, plus + allows Automake to automatically deduce the need for + version.texi. + + * stow.in: + Elide trailing slashes from package names, then complain if + package names have slashes in them. + +Tue Jun 18 23:19:04 1996 Bob Glickstein + + * README: Call it "Gnu Stow". + +Tue Jun 18 22:15:45 1996 Bob Glickstein + + * configure.in: + Bump version number to 1.2. + + Look for Perl under the names `perl' and `perl5'. If not found, + print a warning. + + * stow.texi: + Add a section about bootstrapping. Add text about hacking Gnu + Make output. + + * INSTALL: + Describe what happens when Perl isn't found during `configure'. + +Mon Jun 17 19:43:25 1996 Bob Glickstein + + * THANKS: Thank Fritz. + +Fri Jun 14 19:18:50 1996 Bob Glickstein + + * AUTHORS: Credit John Bazik and Gord Matzigkeit. + + * stow.texi: Remove a "known bug" -- the pwd dependency is gone. + + * stow.in: + Use fastcwd, from fastcwd.pl (which is GPL'd), to remove + dependency on an external pwd binary. Suggested by Gord + Matzigkeit. + + * stow.in: Add a missing comma. + +Thu Jun 13 21:52:10 1996 Bob Glickstein + + * stow.in: + Change three occurrences of `my' to `local' for Perl 4 + compatibility. + +Thu Jun 13 18:07:37 1996 Bob Glickstein + + * configure.in: Bump version number to 1.1. + + * Makefile.am: + Add `stow' to the list of clean targets. Don't redirect output + directly into a make target. + + * AUTHORS, README: + Use as the contact address. + + * TODO: New file. + + * stow.in: + Refer to "Gnu Stow" in a few places. Use + as the contact address. Handle long and short options. Handle + `version' and `help' options. Refer to "packages," not + "collections," for consistency with the manual. + + * stow.texi: + Refer to "Gnu Stow" in a few places. Use + as the contact address. Add sections on Reporting bugs and Known + bugs. Create a master menu. Minor rewording. Remove the period + from a node name. + + * TODO, THANKS: New files. + +Mon Jun 10 14:44:13 1996 Bob Glickstein + + * NEWS: Create NEWS file for release. 1.0 now ready. + + * stow.texi: Big revisions in preparation for release. + +Sun Jun 9 15:47:19 1996 Bob Glickstein + + * stow.in: Enhance argument parsing, losing Perl 4 support in the + process. + (later) Perl 4 support restored. + +Fri Jun 7 12:13:33 1996 Bob Glickstein + + * Created stow, formerly "depot." diff --git a/.local/share/doc/stow/ChangeLog.OLD b/.local/share/doc/stow/ChangeLog.OLD new file mode 100644 index 0000000..ba07eb7 --- /dev/null +++ b/.local/share/doc/stow/ChangeLog.OLD @@ -0,0 +1,232 @@ +Thu Jan 31 2008 Kahlil Hodgson + + * stow.texi: Austin Wood and Chris Hoobin clean this up for version 2. + + * texi2man: new script by Austin and Chris to generate a man page from the + texinfo file. + + +Sun Nov 25 19:31:32 2007 Kahlil Hodgson + * all: Version 2.0.1 + + * AUTHORS: added Kahlil Hodgson as a new author and current maintainer. + + * stow.in: major rewrite to produce version 2.0.1 see NEWS for details + + * t/: added test suite and support code + + * configure.in: renamed to configure.ac as per autotools recommendation. + + * configure.ac: + Use AC_INT rather than obsolete AM_INTI_MAKEFILE usage. + Remove redundant VERSION and PACKAGE setttings + Remove redundant AC_ARG_PROGRAM + Use AM_INIT_AUTOMAKE([-Wall -Werror]) because we are pedantic. + Add AC_PREREQ([2.6.1]) + + * Makefile.am, configure.ac: + Use explicit rewrite in Makefile.am, rather than AC_CONFIG_FILES(stow.in), + as per autotools recommendation. + + * Makefile.am: + Add TESTS and TEST_ENVIRONMENT for files in t/ + Use dist_man_MANS instead of EXTRA_DIST for man page + + * INSTALL: update to reflect autotools modernization. + + * NEWS: update to describe cahnges in Version 2.0.1. + + * README: update to point to the right websites and email addresses. + + * THANKS: + Add Emil Mikulc who's ideas largely inspired Version 2 and + and Geoffrey Giesemann who did some initial testing and found some + important bugs. + + * TODO: remove tasks that where implemented in Version 2 + + * stow.texi: update documentation to reflect Version 2 changes. + + * stow.8: update to reflect Version 2 changes. + +Sat Jan 26 16:15:21 2002 Guillaume Morin + + * stow.in: if $ENV{'STOW_DIR'} is set, this becomes the default + Stow directory. + +Sun Jan 06 12:18:50 2002 Guillaume Morin + + * Makefile.am: use EXTRA_DIST to include manpage in distribution + +Wed Jan 02 21:33:41 2002 Guillaume Morin + + * stow.in: Stow now only warns the user if a subdirectory + is unreadable during unstowing. + +Wed Jan 02 20:58:05 2002 Guillaume Morin + + * stow.in: fixed JoinPaths so that subdirs called "0" are + correctly pushed. Thanks a lot to Gergely Nagy + who patiently helped me to chase + this bug. + +Sun Dec 30 21:58:25 2001 Guillaume Morin + + * stow.in: fixed a bug introduced by previous changes when + Target argument was relative. (thanks to Luca Filipozzi + for pointing this out) + +Sun Dec 30 18:23:25 2001 Guillaume Morin + + * stow.in: now requires Perl 5. Use POSIX getcwd instead of broken + fastcwd. Fixed bug when CommonParent is /. Stow does not remove + initially empty directories anymore. + +Sun Dec 30 18:07:51 2001 Guillaume Morin + + * configure.in: automake fixes (fp_ -> AC, +AC_INIT_AUTOMAKE) + +Fri Oct 11 22:09:45 1996 Bob Glickstein + + * stow.html, configure.in: Version 1.3.2. + + * README, stow.texi: Correct the URL again. + +Fri Oct 11 18:20:42 1996 Bob Glickstein + + * configure.in: Version 1.3.1. + + * stow.html: Update Stow manual URL. Mention version 1.3.1. + + * README: Update Stow URL. + + * Makefile.am: stow-manual.html -> manual.html. + + * stow.texi: + Add a reference to the Stow home page on the GNU web server. Change + several occurrences of "which" to "that" for grammatical superiority. + +Wed Oct 9 00:34:07 1996 Bob Glickstein + + * Makefile.am: + Add maintainer-only rules for stow-manual.html and stow-manual.texi. + +Wed Oct 9 00:32:31 1996 Bob Glickstein + + * README: Refer to the new location for the Stow home page. + + * stow.html: Make it right for the GNU web server. + +Tue Oct 8 21:54:09 1996 Bob Glickstein + + * stow.texi: Document --restow + + * stow.in: Add --restow (-R) option + + * configure.in: Add "perl4" to search for Perl binary. + Bump version number to 1.3. + +Mon Jun 24 23:23:03 1996 Bob Glickstein + + * stow.texi: Delete trailing whitespace. + +Fri Jun 21 19:44:26 1996 Bob Glickstein + + * Makefile.am: + Don't explicitly mention version.texi. Automake now does it + automagically, by noticing the `@include version.texi' in + stow.texi. Awesome. + + * stow.texi: + Use @include instead of @input. This is more Texinfoid, plus + allows Automake to automatically deduce the need for + version.texi. + + * stow.in: + Elide trailing slashes from package names, then complain if + package names have slashes in them. + +Tue Jun 18 23:19:04 1996 Bob Glickstein + + * README: Call it "Gnu Stow". + +Tue Jun 18 22:15:45 1996 Bob Glickstein + + * configure.in: + Bump version number to 1.2. + + Look for Perl under the names `perl' and `perl5'. If not found, + print a warning. + + * stow.texi: + Add a section about bootstrapping. Add text about hacking Gnu + Make output. + + * INSTALL: + Describe what happens when Perl isn't found during `configure'. + +Mon Jun 17 19:43:25 1996 Bob Glickstein + + * THANKS: Thank Fritz. + +Fri Jun 14 19:18:50 1996 Bob Glickstein + + * AUTHORS: Credit John Bazik and Gord Matzigkeit. + + * stow.texi: Remove a "known bug" -- the pwd dependency is gone. + + * stow.in: + Use fastcwd, from fastcwd.pl (which is GPL'd), to remove + dependency on an external pwd binary. Suggested by Gord + Matzigkeit. + + * stow.in: Add a missing comma. + +Thu Jun 13 21:52:10 1996 Bob Glickstein + + * stow.in: + Change three occurrences of `my' to `local' for Perl 4 + compatibility. + +Thu Jun 13 18:07:37 1996 Bob Glickstein + + * configure.in: Bump version number to 1.1. + + * Makefile.am: + Add `stow' to the list of clean targets. Don't redirect output + directly into a make target. + + * AUTHORS, README: + Use as the contact address. + + * TODO: New file. + + * stow.in: + Refer to "Gnu Stow" in a few places. Use + as the contact address. Handle long and short options. Handle + `version' and `help' options. Refer to "packages," not + "collections," for consistency with the manual. + + * stow.texi: + Refer to "Gnu Stow" in a few places. Use + as the contact address. Add sections on Reporting bugs and Known + bugs. Create a master menu. Minor rewording. Remove the period + from a node name. + + * TODO, THANKS: New files. + +Mon Jun 10 14:44:13 1996 Bob Glickstein + + * NEWS: Create NEWS file for release. 1.0 now ready. + + * stow.texi: Big revisions in preparation for release. + +Sun Jun 9 15:47:19 1996 Bob Glickstein + + * stow.in: Enhance argument parsing, losing Perl 4 support in the + process. + (later) Perl 4 support restored. + +Fri Jun 7 12:13:33 1996 Bob Glickstein + + * Created stow, formerly "depot." diff --git a/.local/share/doc/stow/README b/.local/share/doc/stow/README new file mode 100644 index 0000000..d8df705 --- /dev/null +++ b/.local/share/doc/stow/README @@ -0,0 +1,53 @@ +README for GNU Stow +=================== + +This is GNU Stow, a symlink farm manager program which takes distinct +packages of software and/or data located in separate directories on +the filesystem, and makes them appear to be installed in the same +place. For example, /usr/local/bin could contain symlinks to files +within /usr/local/stow/emacs/bin, /usr/local/stow/perl/bin etc., and +likewise recursively for any other subdirectories such as .../share, +.../man, and so on. + +This is particularly useful for keeping track of system-wide and +per-user installations of software built from source, but can also +facilitate a more controlled approach to management of configuration +files in the user's home directory, especially when coupled with +version control systems. + +Stow is implemented as a combination of a Perl script providing a CLI +interface, and a backend Perl module which does most of the work. + +You can get the latest information about Stow from the home page: + + http://www.gnu.org/software/stow/ + +License +------- + +Stow is free software, licensed under the GNU General Public License, +which can be found in the file COPYING. + +Installation +------------ + +See INSTALL for installation instructions. + +Feedback +-------- + +Please do send comments, questions, and constructive criticism. The +mailing lists and any other communication channels are detailed on the +above home page. + +Brief history +------------- + +Stow was inspired by Carnegie Mellon's "Depot" program, but is +substantially simpler. Whereas Depot requires database files to keep +things in sync, Stow stores no extra state between runs, so there's no +danger (as there is in Depot) of mangling directories when file +hierarchies don't match the database. Also unlike Depot, Stow will +never delete any files, directories, or links that appear in a Stow +directory (e.g., /usr/local/stow/emacs), so it's always possible to +rebuild the target tree (e.g., /usr/local). diff --git a/.local/share/doc/stow/manual-single.html b/.local/share/doc/stow/manual-single.html new file mode 100644 index 0000000..6f112cc --- /dev/null +++ b/.local/share/doc/stow/manual-single.html @@ -0,0 +1,2534 @@ + + + + + +Stow + + + + + + + + + + + + + + + + + + + + +
[Top][Contents][Index][ ? ]
+ +

Stow

+ +

This manual describes GNU Stow 2.2.2 (9 November 2015), a +program for managing the installation of software packages. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

1. Introduction

+ +

Stow is a tool for managing the installation of multiple software +packages in the same run-time directory tree. One historical difficulty +of this task has been the need to administer, upgrade, install, and +remove files in independent packages without confusing them with other +files sharing the same file system space. For instance, it is common to +install Perl and Emacs in ‘/usr/local’. When one does so, one +winds up with the following files(1) in ‘/usr/local/man/man1’: +

+
 
a2p.1
+ctags.1
+emacs.1
+etags.1
+h2ph.1
+perl.1
+s2p.1
+
+ +

Now suppose it’s time to uninstall Perl. Which man pages +get removed? Obviously ‘perl.1’ is one of them, but it should not +be the administrator’s responsibility to memorize the ownership of +individual files by separate packages. +

+

The approach used by Stow is to install each package into its own +tree, then use symbolic links to make it appear as though the files are +installed in the common tree. Administration can be performed in the +package’s private tree in isolation from clutter from other packages. +Stow can then be used to update the symbolic links. The structure +of each private tree should reflect the desired structure in the common +tree; i.e. (in the typical case) there should be a ‘bin’ directory +containing executables, a ‘man/man1’ directory containing section 1 +man pages, and so on. +

+

Stow was inspired by Carnegie Mellon’s Depot program, but is +substantially simpler and safer. Whereas Depot required database files +to keep things in sync, Stow stores no extra state between runs, so +there’s no danger (as there was in Depot) of mangling directories when +file hierarchies don’t match the database. Also unlike Depot, Stow will +never delete any files, directories, or links that appear in a Stow +directory (e.g., ‘/usr/local/stow/emacs’), so it’s always possible +to rebuild the target tree (e.g., ‘/usr/local’). +

+

For information about the latest version of Stow, you can refer to +http://www.gnu.org/software/stow/. +

+ +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

2. Terminology

+ + +

A package is a related collection of files and directories that +you wish to administer as a unit — e.g., Perl or Emacs — and that needs +to be installed in a particular directory structure — e.g., with +‘bin’, ‘lib’, and ‘man’ subdirectories. +

+ +

A target directory is the root of a tree in which one or more +packages wish to appear to be installed. A common, but by no +means the only such location is ‘/usr/local’. The examples in this +manual will use ‘/usr/local’ as the target directory. +

+ +

A stow directory is the root of a tree containing separate +packages in private subtrees. When Stow runs, it uses the current +directory as the default stow directory. The examples in this manual +will use ‘/usr/local/stow’ as the stow directory, so that +individual packages will be, for example, ‘/usr/local/stow/perl’ +and ‘/usr/local/stow/emacs’. +

+ +

An installation image is the layout of files and directories +required by a package, relative to the target directory. Thus, the +installation image for Perl includes: a ‘bin’ directory containing +‘perl’ and ‘a2p’ (among others); an ‘info’ directory +containing Texinfo documentation; a ‘lib/perl’ directory containing +Perl libraries; and a ‘man/man1’ directory containing man pages. +

+ + +

A package directory is the root of a tree containing the +installation image for a particular package. Each package directory +must reside in a stow directory — e.g., the package directory +‘/usr/local/stow/perl’ must reside in the stow directory +‘/usr/local/stow’. The name of a package is the name of its +directory within the stow directory — e.g., ‘perl’. +

+

Thus, the Perl executable might reside in +‘/usr/local/stow/perl/bin/perl’, where ‘/usr/local’ is the +target directory, ‘/usr/local/stow’ is the stow directory, +‘/usr/local/stow/perl’ is the package directory, and +‘bin/perl’ within is part of the installation image. +

+ + + +

A symlink is a symbolic link. A symlink can be relative or +absolute. An absolute symlink names a full path; that is, one +starting from ‘/’. A relative symlink names a relative path; that +is, one not starting from ‘/’. The target of a relative symlink is +computed starting from the symlink’s own directory. Stow only +creates relative symlinks. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

3. Invoking Stow

+ +

The syntax of the stow command is: +

+
 
stow [options] [action flag] package …
+
+ +

Each package is the name of a package (e.g., ‘perl’) in the stow +directory that we wish to install into (or delete from) the target directory. +The default action is to install the given packages, although alternate actions +may be specified by preceding the package name(s) with an action flag. +

+

The following options are supported: +

+
+
-d dir
+
--dir=dir
+

Set the stow directory to dir. Defaults to the value of the environment +variable STOW_DIR if set, or the current directory otherwise. +

+
+
-t dir
+
--target=dir
+

Set the target directory to dir instead of the parent of the stow +directory. Defaults to the parent of the stow directory, so it is typical to +execute stow from the directory ‘/usr/local/stow’. +

+
+
--ignore=regexp
+

This (repeatable) option lets you suppress acting on files that match the +given perl regular expression. For example, using the options +

+
 
--ignore='*.orig' --ignore='*.dist'
+
+ +

will cause stow to ignore files ending in ‘.orig’ or ‘.dist’. +

+

Note that the regular expression is anchored to the end of the filename, +because this is what you will want to do most of the time. +

+

Also note that by default Stow automatically ignores a “sensible” +built-in list of files and directories such as ‘CVS’, editor +backup files, and so on. See section Ignore Lists, for more details. +

+
+
--defer=regexp
+

This (repeatable) option avoids stowing a file matching the given +regular expression, if that file is already stowed by another package. +This is effectively the opposite of ‘--override’. +

+

(N.B. the name ‘--defer’ was chosen in the sense that the package +currently being stowed is treated with lower precedence than any +already installed package, not in the sense that the operation is +being postponed to be run at a later point in time; do not confuse +this nomenclature with the wording used in Deferred Operation.) +

+

For example, the following options +

+
 
--defer=man --defer=info
+
+ +

will cause stow to skip over pre-existing man and info pages. +

+

Equivalently, you could use ‘--defer='man|info'’ since the +argument is just a Perl regex. +

+

Note that the regular expression is anchored to the beginning of the path +relative to the target directory, because this is what you will want to do most +of the time. +

+
+
--override=regexp
+

This (repeatable) option forces any file matching the regular expression to be +stowed, even if the file is already stowed to another package. For example, +the following options +

+
 
--override=man --override=info
+
+ +

will permit stow to overwrite links that point to pre-existing man and info +pages that are owned by stow and would otherwise cause a conflict. +

+

The regular expression is anchored to the beginning of the path relative to +the target directory, because this is what you will want to do most of the time. +

+
+
--no-folding
+
+

This disables any further tree folding or tree refolding. +If a new subdirectory is encountered whilst stowing a new package, the +subdirectory is created within the target, and its contents are +symlinked, rather than just creating a symlink for the directory. If +removal of symlinks whilst unstowing a package causes a subtree to be +foldable (i.e. only containing symlinks to a single package), that +subtree will not be removed and replaced with a symlink. +

+ +
+
--adopt
+

Warning! This behaviour is specifically intended to alter the +contents of your stow directory. If you do not want that, this option +is not for you. +

+

When stowing, if a target is encountered which already exists but is a +plain file (and hence not owned by any existing stow package), then +normally Stow will register this as a conflict and refuse to proceed. +This option changes that behaviour so that the file is moved to the +same relative place within the package’s installation image within the +stow directory, and then stowing proceeds as before. So effectively, +the file becomes adopted by the stow package, without its contents +changing. +

+

This is particularly useful when the stow package is under the control +of a version control system, because it allows files in the target +tree, with potentially different contents to the equivalent versions +in the stow package’s installation image, to be adopted into the +package, then compared by running something like ‘git diff ...’ +inside the stow package, and finally either kept (e.g. via ‘git +commit ...’) or discarded (‘git checkout HEAD ...’). +

+ + +
+
-n
+
--no
+
--simulate
+

Do not perform any operations that modify the file system; in combination with +‘-v’ can be used to merely show what would happen. +

+ +
+
-v
+
--verbose[=n]
+

Send verbose output to standard error describing what Stow is +doing. Verbosity levels are 0, 1, 2, and 3; 0 is the default. Using +‘-v’ or ‘--verbose’ increases the verbosity by one; using +‘--verbose=n’ sets it to n. +

+
+
-p
+
--compat
+

Scan the whole target tree when unstowing. By default, only +directories specified in the installation image are scanned +during an unstow operation. Scanning the whole tree can be +prohibitive if your target tree is very large. This option restores +the legacy behaviour; however, the ‘--badlinks’ option to the +chkstow utility may be a better way of ensuring that your +installation does not have any dangling symlinks (see section Target Maintenance). +

+
+
-V
+
--version
+

Show Stow version number, and exit. +

+
+
-h
+
--help
+

Show Stow command syntax, and exit. +

+
+ +

The following action flags are supported: +

+
+
-D
+
--delete
+

Delete (unstow) the package name(s) that follow this option from the target +directory. This option may be repeated any number of times. +

+
+
-R
+
--restow
+

Restow (first unstow, then stow again) the package names that follow this +option. This is useful for pruning obsolete symlinks from the target tree +after updating the software in a package. This option may be repeated any +number of times. +

+
+
-S
+
--stow
+

explictly stow the package name(s) that follow this option. May be +omitted if you are not using the ‘-D’ or ‘-R’ options in the +same invocation. See section Mixing Operations, for details of when you +might like to use this feature. This option may be repeated any number +of times. +

+
+ + +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

4. Ignore Lists

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

4.1 Motivation For Ignore Lists

+ +

In many situations, there will exist files under the package +directories which it would be undesirable to stow into the target +directory. For example, files related version control such as +‘.gitignore’, ‘CVS’, ‘*,v’ (RCS files) should typically +not have symlinks from the target tree pointing to them. Also there +may be files or directories relating to the build of the package which +are not needed at run-time. +

+

In these cases, it can be rather cumbersome to specify a +‘--ignore’ parameter for each file or directory to be ignored. +This could be worked around by ensuring the existence of +‘~/.stowrc’ containing multiple ‘--ignore’ lines, or if a +different set of files/directories should be ignored depending on +which stow package is involved, a ‘.stowrc’ file for each stow +package, but this would require the user to ensure that they were in +the correct directory before invoking stow, which would be tedious and +error-prone. Furthermore, since Stow shifts parameters from +‘.stowrc’ onto ARGV at run-time, it could clutter up the process +table with excessively long parameter lists, or even worse, exceed the +operating system’s limit for process arguments. +

+ +

Therefore in addition to ‘--ignore’ parameters, Stow provides a +way to specify lists of files and directories to ignore. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

4.2 Types And Syntax Of Ignore Lists

+ +

If you put Perl regular expressions, one per line, in a +‘.stow-local-ignore’ file within any top level package directory, +in which case any file or directory within that package matching any +of these regular expressions will be ignored. In the absence of this +package-specific ignore list, Stow will instead use the contents of +‘~/.stow-global-ignore’, if it exists. If neither the +package-local or global ignore list exist, Stow will use its own +built-in default ignore list, which serves as a useful example of the +format of these ignore list files: +

+
 
# Comments and blank lines are allowed.
+
+RCS
+.+,v
+
+CVS
+\.\#.+       # CVS conflict files / emacs lock files
+\.cvsignore
+
+\.svn
+_darcs
+\.hg
+
+\.git
+\.gitignore
+
+.+~          # emacs backup files
+\#.*\#       # emacs autosave files
+
+^/README.*
+^/LICENSE.*
+^/COPYING
+
+ +

Stow first iterates through the chosen ignore list (built-in, global, +or package-local) as per above, stripping out comments (if you want to +include the ‘#’ symbol in a regular expression, escape it with a +blackslash) and blank lines, placing each regular expressions into one +of two sets depending on whether it contains the ‘/’ forward +slash symbol. +

+

Then in order to determine whether a file or directory should be +ignored: +

+
    +
  1. +Stow calculates its path relative to the top-level package directory, +prefixing that with ‘/’. If any of the regular expressions +containing a ‘/exactly(2) match +a subpath(3) of this relative path, then the file or +directory will be ignored. + +
  2. +If none of the regular expressions containing a ‘/’ match in the +manner described above, Stow checks whether the +basename(4) of the file or directory matches +exactly against the remaining regular expressions which do not +contain a ‘/’, and if so, ignores the file or directory. + +
  3. +Otherwise, the file or directory is not ignored. +
+ + +

For example, if a file ‘bazqux’ is in the ‘foo/bar’ +subdirectory of the package directory, Stow would use +‘/foo/bar/bazqux’ as the text for matching against regular +expressions which contain ‘/’, and ‘bazqux’ as the text for +matching against regular expressions which don’t contain ‘/’. +Then regular expressions ‘bazqux’, ‘baz.*’, ‘.*qux’, +‘bar/.*x’, and ‘^/foo/.*qux’ would all match (causing the +file to be ignored), whereas ‘bar’, ‘baz’, ‘qux’, and +‘o/bar/b’ would not (although ‘bar’ would cause its parent +directory to be ignored and prevent Stow from recursing into that +anyway, in which case the file ‘bazqux’ would not even be +considered for stowing). +

+

As a special exception to the above algorithm, any +‘.stow-local-ignore’ present in the top-level package directory +is always ignored, regardless of the contents of any ignore +list, because this file serves no purpose outside the stow directory. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

4.3 Justification For Yet Another Set Of Ignore Files

+ +

The reader may note that this format is very similar to existing +ignore list file formats, such as those for cvs, git, +rsync etc., and wonder if another set of ignore lists is +justified. However there are good reasons why Stow does not simply +check for the presence of say, ‘.cvsignore’, and use that if it +exists. Firstly, there is no guarantee that a stow package would +contain any version control meta-data, or permit introducing this if +it didn’t already exist. +

+

Secondly even if it did, version control system ignore lists generally +reflect build-time ignores rather than install-time, and +there may be some intermediate or temporary files on those ignore +lists generated during development or at build-time which it would be +inappropriate to stow, even though many files generated at build-time +(binaries, libraries, documentation etc.) certainly do need to be +stowed. Similarly, if a file is not in the version control +system’s ignore list, there is no way of knowing whether the file is +intended for end use, let alone whether the version control system is +tracking it or not. +

+

Therefore it seems clear that ignore lists provided by version control +systems do not provide sufficient information for Stow to determine +which files and directories to stow, and so it makes sense for Stow to +support independent ignore lists. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

5. Installing Packages

+ + +

The default action of Stow is to install a package. This means creating +symlinks in the target tree that point into the package tree. Stow +attempts to do this with as few symlinks as possible; in other words, if +Stow can create a single symlink that points to an entire subtree within +the package tree, it will choose to do that rather than create a +directory in the target tree and populate it with symlinks. +

+

+


+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+

5.1 Tree folding

+ + + +

For example, suppose that no packages have yet been installed in +‘/usr/local’; it’s completely empty (except for the ‘stow’ +subdirectory, of course). Now suppose the Perl package is installed. +Recall that it includes the following directories in its installation +image: ‘bin’; ‘info’; ‘lib/perl’; ‘man/man1’. +Rather than creating the directory ‘/usr/local/bin’ and populating +it with symlinks to ‘../stow/perl/bin/perl’ and +‘../stow/perl/bin/a2p’ (and so on), Stow will create a +single symlink, ‘/usr/local/bin’, which points to +‘stow/perl/bin’. In this way, it still works to refer to +‘/usr/local/bin/perl’ and ‘/usr/local/bin/a2p’, and fewer +symlinks have been created. This is called tree folding, since an +entire subtree is “folded” into a single symlink. +

+

To complete this example, Stow will also create the symlink +‘/usr/local/info’ pointing to ‘stow/perl/info’; the symlink +‘/usr/local/lib’ pointing to ‘stow/perl/lib’; and the symlink +‘/usr/local/man’ pointing to ‘stow/perl/man’. +

+

Now suppose that instead of installing the Perl package into an empty +target tree, the target tree is not empty to begin with. Instead, it +contains several files and directories installed under a different +system-administration philosophy. In particular, ‘/usr/local/bin’ +already exists and is a directory, as are ‘/usr/local/lib’ and +‘/usr/local/man/man1’. In this case, Stow will descend into +‘/usr/local/bin’ and create symlinks to +‘../stow/perl/bin/perl’ and ‘../stow/perl/bin/a2p’ (etc.), +and it will descend into ‘/usr/local/lib’ and create the +tree-folding symlink ‘perl’ pointing to +‘../stow/perl/lib/perl’, and so on. As a rule, Stow only +descends as far as necessary into the target tree when it can create a +tree-folding symlink. However, this behaviour can be changed via +the ‘--no-folding’ option; see section Invoking Stow. +

+

+


+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+

5.2 Tree unfolding

+ + + + +

The time often comes when a tree-folding symlink has to be undone +because another package uses one or more of the folded subdirectories in +its installation image. This operation is called splitting open or +unfolding a folded tree. It involves removing the original symlink from +the target tree, creating a true directory in its place, and then populating the +new directory with symlinks to the newly-installed package and to +the old package that used the old symlink. For example, suppose that +after installing Perl into an empty ‘/usr/local’, we wish to +install Emacs. Emacs’s installation image includes a ‘bin’ +directory containing the ‘emacs’ and ‘etags’ executables, +among others. Stow must make these files appear to be installed +in ‘/usr/local/bin’, but presently ‘/usr/local/bin’ is a +symlink to ‘stow/perl/bin’. Stow therefore takes the +following steps: the symlink ‘/usr/local/bin’ is deleted; the +directory ‘/usr/local/bin’ is created; links are made from +‘/usr/local/bin’ to ‘../stow/emacs/bin/emacs’ and +‘../stow/emacs/bin/etags’; and links are made from +‘/usr/local/bin’ to ‘../stow/perl/bin/perl’ and +‘../stow/perl/bin/a2p’. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+

5.3 Ownership

+ +

When splitting open a folded tree, Stow makes sure that the +symlink it is about to remove points inside a valid package in the +current stow directory. Stow will never delete anything +that it doesn’t own. Stow “owns” everything living in the +target tree that points into a package in the stow directory. Anything +Stow owns, it can recompute if lost: symlinks that point into a package in +the stow directory, or directories that only contain symlinks that stow +“owns”. Note that by this definition, Stow doesn’t “own” anything +in the stow directory or in any of the packages. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+

5.4 Conflicts during installation

+ + +

If Stow needs to create a directory or a symlink in the target +tree and it cannot because that name is already in use and is not owned +by Stow, then a conflict has arisen. See section Conflicts. +

+ +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

6. Deleting Packages

+ + +

When the ‘-D’ option is given, the action of Stow is to +delete a package from the target tree. Note that Stow will not +delete anything it doesn’t “own”. Deleting a package does not +mean removing it from the stow directory or discarding the package +tree. +

+

To delete a package, Stow recursively scans the target tree, skipping over any +directory that is not included in the installation image.(5) +For example, if the target directory is ‘/usr/local’ and the +installation image for the package being deleted has only a ‘bin’ +directory and a ‘man’ directory at the top level, then we only scan +‘/usr/local/bin’ and ‘/usr/local/bin/man’, and not +‘/usr/local/lib’ or ‘/usr/local/share’, or for that matter +‘/usr/local/stow’. Any symlink it finds that points into the package +being deleted is removed. Any directory that contained only symlinks to the +package being deleted is removed. +

+

+


+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+

6.1 Refolding “foldable” trees.

+ + + +

After removing symlinks and empty subdirectories, any directory that +contains only symlinks to a single other package is considered to be a +previously “folded” tree that was “split open.” Stow will refold +the tree by removing the symlinks to the surviving package, removing +the directory, then linking the directory back to the surviving +package. However, this behaviour can be prevented via the +‘--no-folding’ option; see section Invoking Stow. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

7. Conflicts

+ + +

If, during installation, a file or symlink exists in the target tree and +has the same name as something Stow needs to create, and if the +existing name is not a folded tree that can be split open, then a +conflict has arisen. A conflict also occurs if a directory exists +where Stow needs to place a symlink to a non-directory. On the +other hand, if the existing name is merely a symlink that already points +where Stow needs it to, then no conflict has occurred. (Thus it +is harmless to install a package that has already been installed.) +

+

For complex packages, scanning the stow and target trees in tandem, +and deciding whether to make directories or links, split-open or fold +directories, can actually take a long time (a number of seconds). +Moreover, an accurate analysis of potential conflicts requires us to +take into account all of these operations. +

+

+


+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+

7.1 Deferred Operation

+ + +

Since version 2.0, Stow now adopts a two-phase algorithm, first +scanning for any potential conflicts before any stowing or unstowing +operations are performed. If any conflicts are found, they are +displayed and then Stow terminates without making any modifications to +the filesystem. This means that there is much less risk of a package +being partially stowed or unstowed due to conflicts. +

+

Prior to version 2.0, if a conflict was discovered, the stow or unstow +operation could be aborted mid-flow, leaving the target tree in an +inconsistent state. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

8. Mixing Operations

+ + +

Since version 2.0, multiple distinct actions can be specified in a single +invocation of GNU Stow. For example, to update an installation of Emacs from +version 21.3 to 21.4a you can now do the following: +

+
 
stow -D emacs-21.3 -S emacs-21.4a
+
+ +

which will replace emacs-21.3 with emacs-21.4a using a single invocation. +

+ +

This is much faster and cleaner than performing two separate +invocations of stow, because redundant folding/unfolding operations +can be factored out. In addition, all the operations are calculated +and merged before being executed (see Deferred Operation), so the +amount of of time in which GNU Emacs is unavailable is minimised. +

+

You can mix and match any number of actions, for example, +

+
 
stow -S pkg1 pkg2 -D pkg3 pkg4 -S pkg5 -R pkg6
+
+ +

will unstow pkg3, pkg4 and pkg6, then stow pkg1, pkg2, pkg5 and pkg6. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

9. Multiple Stow Directories

+ +

If there are two or more system administrators who wish to maintain +software separately, or if there is any other reason to want two or more +stow directories, it can be done by creating a file named ‘.stow’ +in each stow directory. The presence of ‘/usr/local/foo/.stow’ +informs Stow that, though ‘foo’ is not the current stow +directory, even if it is a subdirectory of the target directory, +nevertheless it is a stow directory and as such Stow +doesn’t “own” anything in it (see section Installing Packages). This will +protect the contents of ‘foo’ from a ‘stow -D’, for instance. +

+ +

When multiple stow directories share a target tree, if a tree-folding +symlink is encountered and needs to be split open during an +installation, as long as the top-level stow directory into which the +existing symlink points contains ‘.stow’, Stow knows how to split +open the tree in the correct manner. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

10. Target Maintenance

+ + +

From time to time you will need to clean up your target tree. Since +version 2, Stow provides a new utility chkstow to help with +this. It includes three operational modes which performs checks that +would generally be too expensive to be performed during normal stow +execution. +

+

The syntax of the chkstow command is: +

+
 
chkstow [options]
+
+ +

The following options are supported: +

+
+
-t dir
+
--target=dir
+

Set the target directory to dir instead of the parent of the stow +directory. Defaults to the parent of the stow directory, so it is typical to +execute stow from the directory ‘/usr/local/stow’. +

+
+
-b
+
--badlinks
+

Checks target directory for bogus symbolic links. That is, links that point to +non-existent files. +

+
+
-a
+
--aliens
+

Checks for files in the target directory that are not symbolic links. The +target directory should be managed by stow alone, except for directories that +contain a ‘.stow’ file. +

+
+
-l
+
--list
+

Will display the target package for every symbolic link in the stow target +directory. +

+
+
+ +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

11. Resource Files

+ + + +

Default command line options may be set in ‘.stowrc’ (current directory) or +‘~/.stowrc’ (home directory). These are parsed in that order, and effectively +prepended to you command line. This feature can be used for some interesting +effects. +

+

For example, suppose your site uses more than one stow directory, perhaps in +order to share around responsibilities with a number of systems +administrators. One of the administrators might have the following in their +‘~/.stowrc’ file: +

+
 
--dir=/usr/local/stow2
+--target=/usr/local
+--ignore='~'
+--ignore='^CVS'
+
+ +

so that the stow command will default to operating on the +‘/usr/local/stow2’ directory, with ‘/usr/local’ as the +target, and ignoring vi backup files and CVS directories. +

+

If you had a stow directory ‘/usr/local/stow/perl-extras’ that +was only used for Perl modules, then you might place the following in +‘/usr/local/stow/perl-extras/.stowrc’: +

+
 
--dir=/usr/local/stow/perl-extras
+--target=/usr/local
+--override=bin
+--override=man
+--ignore='perllocal\.pod'
+--ignore='\.packlist'
+--ignore='\.bs'
+
+ +

so that when you are in the ‘/usr/local/stow/perl-extras’ +directory, stow will regard any subdirectories as stow +packages, with ‘/usr/local’ as the target (rather than the +immediate parent directory ‘/usr/local/stow’), overriding any +pre-existing links to bin files or man pages, and ignoring some cruft +that gets installed by default. +

+ +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

12. Compile-time vs Install-time

+ +

Software whose installation is managed with Stow needs to be installed +in one place (the package directory, e.g. ‘/usr/local/stow/perl’) +but needs to appear to run in another place (the target tree, e.g., +‘/usr/local’). Why is this important? What’s wrong with Perl, for +instance, looking for its files in ‘/usr/local/stow/perl’ instead +of in ‘/usr/local’? +

+

The answer is that there may be another package, e.g., +‘/usr/local/stow/perl-extras’, stowed under ‘/usr/local’. If +Perl is configured to find its files in ‘/usr/local/stow/perl’, it +will never find the extra files in the ‘perl-extras’ package, even +though they’re intended to be found by Perl. On the other hand, if Perl +looks for its files in ‘/usr/local’, then it will find the +intermingled Perl and ‘perl-extras’ files. +

+

This means that when you compile a package, you must tell it the +location of the run-time, or target tree; but when you install it, you +must place it in the stow tree. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+

12.1 Advice on changing compilation and installation parameters

+

Some software packages allow you to specify, at compile-time, separate +locations for installation and for run-time. Perl is one such package; +see Perl and Perl 5 Modules. Others allow you to compile the +package, then give a different destination in the ‘make install’ +step without causing the binaries or other files to get rebuilt. Most +GNU software falls into this category; Emacs is a notable exception. +See section GNU Emacs, and Other FSF Software. +

+

Still other software packages cannot abide the idea of separate +installation and run-time locations at all. If you try to ‘make +install prefix=/usr/local/stow/foo’, then first the whole package +will be recompiled to hardwire the ‘/usr/local/stow/foo’ +path. With these packages, it is best to compile normally, then run +‘make -n install’, which should report all the steps needed to +install the just-built software. Place this output into a file, edit +the commands in the file to remove recompilation steps and to reflect +the Stow-based installation location, and execute the edited file as a +shell script in place of ‘make install’. Be sure to execute the +script using the same shell that ‘make install’ would have used. +

+

(If you use GNU Make and a shell [such as GNU bash] that understands +pushd and popd, you can do the following: +

+
    +
  1. +Replace all lines matching ‘make[n]: Entering directory +dir’ with ‘pushd dir’. +
  2. +Replace all lines matching ‘make[n]: Leaving directory +dir’ with ‘popd’. +
  3. +Delete all lines matching ‘make[n]: Nothing to be done for +rule’. +
+ +

Then find other lines in the output containing cd or make +commands and rewrite or delete them. In particular, you should be able +to delete sections of the script that resemble this: +

+
 
for i in dir_1 dir_2 ; do \
+  (cd $i; make args ) \
+done
+
+ +

Note, that’s “should be able to,” not “can.” Be sure to modulate +these guidelines with plenty of your own intelligence. +

+

The details of stowing some specific packages are described in the +following sections. +

+ + + + + + + +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

12.2 GNU Emacs

+ +

Although the Free Software Foundation has many enlightened practices +regarding Makefiles and software installation (see see section Other FSF Software), Emacs, its flagship program, doesn’t quite follow the +rules. In particular, most GNU software allows you to write: +

+
 
make
+make install prefix=/usr/local/stow/package
+
+ +

If you try this with Emacs, then the new value for prefix in the +‘make install’ step will cause some files to get recompiled with +the new value of prefix wired into them. In Emacs 19.23 and +later,(6) +the way to work around this problem is: +

+
 
make
+make install-arch-dep install-arch-indep prefix=/usr/local/stow/emacs
+
+ +

In 19.22 and some prior versions of Emacs, the workaround was: +

+
 
make
+make do-install prefix=/usr/local/stow/emacs
+
+ +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

12.3 Other FSF Software

+ +

The Free Software Foundation, the organization behind the GNU project, +has been unifying the build procedure for its tools for some time. +Thanks to its tools ‘autoconf’ and ‘automake’, most packages +now respond well to these simple steps, with no other intervention +necessary: +

+
 
./configure options
+make
+make install prefix=/usr/local/stow/package
+
+ +

Hopefully, these tools can evolve to be aware of Stow-managed packages, +such that providing an option to ‘configure’ can allow ‘make’ +and ‘make install’ steps to work correctly without needing to +“fool” the build process. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

12.4 Cygnus Software

+ +

Cygnus is a commercial supplier and supporter of GNU software. It has +also written several of its own packages, released under the terms of +the GNU General Public License; and it has taken over the maintenance of +other packages. Among the packages released by Cygnus are ‘gdb’, +‘gnats’, and ‘dejagnu’. +

+

Cygnus packages have the peculiarity that each one unpacks into a +directory tree with a generic top-level Makefile, which is set up to +compile all of Cygnus’ packages, any number of which may reside +under the top-level directory. In other words, even if you’re only +building ‘gnats’, the top-level Makefile will look for, and try to +build, ‘gdb’ and ‘dejagnu’ subdirectories, among many others. +

+

The result is that if you try ‘make -n install +prefix=/usr/local/stow/package’ at the top level of a Cygnus +package, you’ll get a bewildering amount of output. It will then be +very difficult to visually scan the output to see whether the install +will proceed correctly. Unfortunately, it’s not always clear how to +invoke an install from the subdirectory of interest. +

+

In cases like this, the best approach is to run your ‘make install +prefix=’, but be ready to interrupt it if you detect that it +is recompiling files. Usually it will work just fine; otherwise, +install manually. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

12.5 Perl and Perl 5 Modules

+ +

Perl 4.036 allows you to specify different locations for installation +and for run-time. It is the only widely-used package in this author’s +experience that allows this, though hopefully more packages will adopt +this model. +

+

Unfortunately, the authors of Perl believed that only AFS sites need +this ability. The configuration instructions for Perl 4 misleadingly +state that some occult means are used under AFS to transport files from +their installation tree to their run-time tree. In fact, that confusion +arises from the fact that Depot, Stow’s predecessor, originated at +Carnegie Mellon University, which was also the birthplace of AFS. CMU’s +need to separate install-time and run-time trees stemmed from its use of +Depot, not from AFS. +

+

The result of this confusion is that Perl 5’s configuration script +doesn’t even offer the option of separating install-time and run-time +trees unless you’re running AFS. Fortunately, after you’ve +entered all the configuration settings, Perl’s setup script gives you +the opportunity to edit those settings in a file called +‘config.sh’. When prompted, you should edit this file and replace +occurrences of +

+
 
inst/usr/local
+
+ +

with +

+
 
inst/usr/local/stow/perl
+
+ +

You can do this with the following Unix command: +

+
 
sed 's,^\(inst.*/usr/local\),\1/stow/perl,' config.sh > config.sh.new
+mv config.sh.new config.sh
+
+ +

Hopefully, the Perl authors will correct this deficiency in Perl 5’s +configuration mechanism. +

+

Perl 5 modules—i.e., extensions to Perl 5—generally conform to a set +of standards for building and installing them. The standard says that +the package comes with a top-level ‘Makefile.PL’, which is a Perl +script. When it runs, it generates a ‘Makefile’. +

+

If you followed the instructions above for editing ‘config.sh’ when +Perl was built, then when you create a ‘Makefile’ from a +‘Makefile.PL’, it will contain separate locations for run-time +(‘/usr/local’) and install-time (‘/usr/local/stow/perl’). +Thus you can do +

+
 
perl Makefile.PL
+make
+make install
+
+ +

and the files will be installed into ‘/usr/local/stow/perl’. +However, you might prefer each Perl module to be stowed separately. In +that case, you must edit the resulting Makefile, replacing +‘/usr/local/stow/perl’ with ‘/usr/local/stow/module’. +The best way to do this is: +

+
 
perl Makefile.PL
+find . -name Makefile -print | \
+  xargs perl -pi~ -e 's,^(INST.*/stow)/perl,$1/module,;'
+make
+make install
+
+ +

(The use of ‘find’ and ‘xargs’ ensures that all Makefiles in +the module’s source tree, even those in subdirectories, get edited.) A +good convention to follow is to name the stow directory for a Perl +modulecpan.module’, where ‘cpan’ stands for +Comprehensive Perl Archive Network, a collection of FTP sites that is +the source of most Perl 5 extensions. This way, it’s easy to tell at a +glance which of the subdirectories of ‘/usr/local/stow’ are Perl 5 +extensions. +

+

When you stow separate Perl 5 modules separately, you are likely to +encounter conflicts (see section Conflicts) with files named ‘.exists’ +and ‘perllocal.pod’. One way to work around this is to remove +those files before stowing the module. If you use the +‘cpan.module’ naming convention, you can simply do this: +

+
 
cd /usr/local/stow
+find cpan.* \( -name .exists -o -name perllocal.pod \) -print | \
+  xargs rm
+
+ + +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

13. Bootstrapping

+ +

Suppose you have a stow directory all set up and ready to go: +‘/usr/local/stow/perl’ contains the Perl installation, +‘/usr/local/stow/stow’ contains Stow itself, and perhaps you have +other packages waiting to be stowed. You’d like to be able to do this: +

+
 
cd /usr/local/stow
+stow -vv *
+
+ +

but stow is not yet in your PATH. Nor can you do this: +

+
 
cd /usr/local/stow
+stow/bin/stow -vv *
+
+ +

because the ‘#!’ line at the beginning of stow tries to +locate Perl (usually in ‘/usr/local/bin/perl’), and that won’t be +found. The solution you must use is: +

+
 
cd /usr/local/stow
+perl/bin/perl stow/bin/stow -vv *
+
+ +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

14. Reporting Bugs

+ +

Please send bug reports to the current maintainers by electronic +mail. The address to use is ‘<bug-stow@gnu.org>’. Please +include: +

+
    +
  • +the version number of Stow (‘stow --version’); + +
  • +the version number of Perl (‘perl -v’); + +
  • +the system information, which can often be obtained with ‘uname +-a’; + +
  • +a description of the bug; + +
  • +the precise command you gave; + +
  • +the output from the command (preferably verbose output, obtained by +adding ‘--verbose=3’ to the Stow command line). +
+ +

If you are really keen, consider developing a minimal test case and +creating a new test. See the ‘t/’ directory in the source for +lots of examples. +

+

Before reporting a bug, please read the manual carefully, especially +Known Bugs, to see whether you’re encountering +something that doesn’t need reporting. +(see section Conflicts). +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

15. Known Bugs

+ +

There are no known bugs in Stow version 2.2.2! +If you think you have found one, please see section Reporting Bugs. +

+ +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

GNU General Public License

+ +

Version 2, June 1991 +

+
 
Copyright © 1989, 1991 Free Software Foundation, Inc.
+675 Mass Ave, Cambridge, MA 02139, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+ +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+

Preamble

+ +

The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software—to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation’s software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. +

+

When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. +

+

To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. +

+

For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. +

+

We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. +

+

Also, for each author’s protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors’ reputations. +

+

Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone’s free use or not licensed at all. +

+

The precise terms and conditions for copying, distribution and +modification follow. +

+

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +

+
    +
  1. +This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The “Program”, below, +refers to any such program or work, and a “work based on the Program” +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term “modification”.) Each licensee is addressed as “you”. + +

    Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. +

    +
  2. +You may copy and distribute verbatim copies of the Program’s +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +

    You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. +

    +
  3. +You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +
      +
    1. +You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change. + +
    2. +You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any +part thereof, to be licensed as a whole at no charge to all third +parties under the terms of this License. + +
    3. +If the modified program normally reads commands interactively +when run, you must cause it, when started running for such +interactive use in the most ordinary way, to print or display an +announcement including an appropriate copyright notice and a +notice that there is no warranty (or else, saying that you provide +a warranty) and that users may redistribute the program under +these conditions, and telling the user how to view a copy of this +License. (Exception: if the Program itself is interactive but +does not normally print such an announcement, your work based on +the Program is not required to print an announcement.) +
    + +

    These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. +

    +

    Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. +

    +

    In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. +

    +
  4. +You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + +
      +
    1. +Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections +1 and 2 above on a medium customarily used for software interchange; or, + +
    2. +Accompany it with a written offer, valid for at least three +years, to give any third party, for a charge no more than your +cost of physically performing source distribution, a complete +machine-readable copy of the corresponding source code, to be +distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, + +
    3. +Accompany it with the information you received as to the offer +to distribute corresponding source code. (This alternative is +allowed only for noncommercial distribution and only if you +received the program in object code or executable form with such +an offer, in accord with Subsection b above.) +
    + +

    The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. +

    +

    If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. +

    +
  5. +You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + +
  6. +You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +
  7. +Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients’ exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +
  8. +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +

    If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. +

    +

    It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. +

    +

    This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. +

    +
  9. +If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +
  10. +The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +

    Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and “any +later version”, you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. +

    +
  11. +If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + +

    NO WARRANTY +

    +
  12. +BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + +
  13. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. +
+ +

END OF TERMS AND CONDITIONS +

+ +
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+

How to Apply These Terms to Your New Programs

+ +

If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. +

+

To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the “copyright” line and a pointer to where the full notice is found. +

+
 
one line to give the program's name and an idea of what it does.
+Copyright (C) 19yy  name of author
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ +

Also add information on how to contact you by electronic and paper mail. +

+

If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: +

+
 
Gnomovision version 69, Copyright (C) 19yy name of author
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+type `show w'.  This is free software, and you are welcome
+to redistribute it under certain conditions; type `show c'
+for details.
+
+ +

The hypothetical commands ‘show w’ and ‘show c’ should show +the appropriate parts of the General Public License. Of course, the +commands you use may be called something other than ‘show w’ and +‘show c’; they could even be mouse-clicks or menu items—whatever +suits your program. +

+

You should also get your employer (if you work as a programmer) or your +school, if any, to sign a “copyright disclaimer” for the program, if +necessary. Here is a sample; alter the names: +

+
 
Yoyodyne, Inc., hereby disclaims all copyright
+interest in the program `Gnomovision'
+(which makes passes at compilers) written
+by James Hacker.
+
+signature of Ty Coon, 1 April 1989
+Ty Coon, President of Vice
+
+ +

This General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications +with the library. If this is what you want to do, use the GNU Library +General Public License instead of this License. +

+
+ + + + + + + + + + + + + + + + +
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
+ +

Index

+ +
Jump to:   A +   +C +   +D +   +F +   +I +   +M +   +O +   +P +   +R +   +S +   +T +   +U +   +V +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry Section

A
absolute symlink2. Terminology
adopting existing files3. Invoking Stow

C
configuration files11. Resource Files
conflicts5.4 Conflicts during installation
conflicts7. Conflicts

D
deferred operation7.1 Deferred Operation
deferred operation8. Mixing Operations
deletion6. Deleting Packages
directory folding5.1 Tree folding
dry run3. Invoking Stow

F
folding trees5.1 Tree folding

I
ignore lists4. Ignore Lists
ignore lists4.1 Motivation For Ignore Lists
ignoring files and directories4. Ignore Lists
installation5. Installing Packages
installation conflicts5.4 Conflicts during installation
installation image2. Terminology

M
maintenance10. Target Maintenance
mixing operations8. Mixing Operations

O
ownership5.3 Ownership

P
package2. Terminology
package directory2. Terminology
package name2. Terminology

R
refolding trees6.1 Refolding “foldable” trees.
relative symlink2. Terminology
resource files11. Resource Files

S
simulated run3. Invoking Stow
splitting open folded trees5.2 Tree unfolding
stow directory2. Terminology
symlink2. Terminology

T
target directory2. Terminology
tree folding5.1 Tree folding
tree refolding6.1 Refolding “foldable” trees.
tree unfolding5.2 Tree unfolding
tree unsplitting5.2 Tree unfolding

U
unfolding trees5.2 Tree unfolding

V
verbosity levels3. Invoking Stow

+
Jump to:   A +   +C +   +D +   +F +   +I +   +M +   +O +   +P +   +R +   +S +   +T +   +U +   +V +   +
+ +
+ + + + + + +
[Top][Contents][Index][ ? ]
+

Footnotes

+

(1)

+

As of Perl 4.036 and Emacs +19.22. +

(2)

+

Exact matching means the +regular expression is anchored at the beginning and end, in contrast +to unanchored regular expressions which will match a substring. +

(3)

+

In this context, “subpath” means a contiguous +subset of path segments; e.g for the relative path +‘one/two/three’, there are six valid subpaths: ‘one’, +‘two’, ‘three’, ‘one/two’, ‘two/three’, +‘one/two/three’. +

(4)

+

The “basename” is the name of the file or +directory itself, excluding any directory path prefix - as returned by +the basename command. +

(5)

+

This +approach was introduced in version 2 of GNU Stow. Previously, the whole +target tree was scanned and stow directories were explicitly omitted. This +became problematic when dealing with very large installations. The only +situation where this is useful is if you accidentally delete a directory in +the package tree, leaving you with a whole bunch of dangling links. Note that +you can enable the old approach with the ‘-p’ option. Alternatively, you can +use the ‘--badlinks’ option get stow to search for dangling links in your target tree and remove the offenders manually. +

(6)

+

As I write this, the current version of Emacs is 19.31. +


+ + + + + + +
[Top][Contents][Index][ ? ]
+

Table of Contents

+ +
+ + + + + + +
[Top][Contents][Index][ ? ]
+

About This Document

+

+ This document was generated by Adam Spiers on November 9, 2015 using texi2html 1.82. +

+

+ The buttons in the navigation panels have the following meaning: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Button Name Go to From 1.2.3 go to
[ < ] BackPrevious section in reading order1.2.2
[ > ] ForwardNext section in reading order1.2.4
[ << ] FastBackBeginning of this chapter or previous chapter1
[ Up ] UpUp section1.2
[ >> ] FastForwardNext chapter2
[Top] TopCover (top) of document  
[Contents] ContentsTable of contents  
[Index] IndexIndex  
[ ? ] AboutAbout (help)  
+ +

+ where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure: +

+ +
    +
  • 1. Section One +
      +
    • 1.1 Subsection One-One +
        +
      • ...
      • +
      +
    • +
    • 1.2 Subsection One-Two +
        +
      • 1.2.1 Subsubsection One-Two-One
      • +
      • 1.2.2 Subsubsection One-Two-Two
      • +
      • 1.2.3 Subsubsection One-Two-Three     + <== Current Position
      • +
      • 1.2.4 Subsubsection One-Two-Four
      • +
      +
    • +
    • 1.3 Subsection One-Three +
        +
      • ...
      • +
      +
    • +
    • 1.4 Subsection One-Four
    • +
    +
  • +
+ +
+

+ + This document was generated by Adam Spiers on November 9, 2015 using texi2html 1.82. + +
+ +

+ + diff --git a/.local/share/doc/stow/manual-split/Bootstrapping.html b/.local/share/doc/stow/manual-split/Bootstrapping.html new file mode 100644 index 0000000..40ee46e --- /dev/null +++ b/.local/share/doc/stow/manual-split/Bootstrapping.html @@ -0,0 +1,89 @@ + + +Bootstrapping - Stow + + + + + + + + + + + + +
+ +

+Next: , +Previous: Compile-time vs Install-time, +Up: Top +


+
+ +

13 Bootstrapping

+ +

Suppose you have a stow directory all set up and ready to go: +/usr/local/stow/perl contains the Perl installation, +/usr/local/stow/stow contains Stow itself, and perhaps you have +other packages waiting to be stowed. You'd like to be able to do this: + +

     cd /usr/local/stow
+     stow -vv *
+
+

but stow is not yet in your PATH. Nor can you do this: + +

     cd /usr/local/stow
+     stow/bin/stow -vv *
+
+

because the ‘#!’ line at the beginning of stow tries to +locate Perl (usually in /usr/local/bin/perl), and that won't be +found. The solution you must use is: + +

     cd /usr/local/stow
+     perl/bin/perl stow/bin/stow -vv *
+
+ + + diff --git a/.local/share/doc/stow/manual-split/Compile_002dtime-vs-Install_002dtime.html b/.local/share/doc/stow/manual-split/Compile_002dtime-vs-Install_002dtime.html new file mode 100644 index 0000000..cb7776e --- /dev/null +++ b/.local/share/doc/stow/manual-split/Compile_002dtime-vs-Install_002dtime.html @@ -0,0 +1,144 @@ + + +Compile-time vs Install-time - Stow + + + + + + + + + + + + +
+ + +

+Next: , +Previous: Resource Files, +Up: Top +


+
+ +

12 Compile-time vs Install-time

+ +

Software whose installation is managed with Stow needs to be installed +in one place (the package directory, e.g. /usr/local/stow/perl) +but needs to appear to run in another place (the target tree, e.g., +/usr/local). Why is this important? What's wrong with Perl, for +instance, looking for its files in /usr/local/stow/perl instead +of in /usr/local? + +

The answer is that there may be another package, e.g., +/usr/local/stow/perl-extras, stowed under /usr/local. If +Perl is configured to find its files in /usr/local/stow/perl, it +will never find the extra files in the ‘perl-extras’ package, even +though they're intended to be found by Perl. On the other hand, if Perl +looks for its files in /usr/local, then it will find the +intermingled Perl and ‘perl-extras’ files. + +

This means that when you compile a package, you must tell it the +location of the run-time, or target tree; but when you install it, you +must place it in the stow tree. + +

12.1 Advice on changing compilation and installation parameters

+ +

Some software packages allow you to specify, at compile-time, separate +locations for installation and for run-time. Perl is one such package; +see Perl and Perl 5 Modules. Others allow you to compile the +package, then give a different destination in the ‘make install’ +step without causing the binaries or other files to get rebuilt. Most +GNU software falls into this category; Emacs is a notable exception. +See GNU Emacs, and Other FSF Software. + +

Still other software packages cannot abide the idea of separate +installation and run-time locations at all. If you try to ‘make +install prefix=/usr/local/stow/foo’, then first the whole package +will be recompiled to hardwire the /usr/local/stow/foo +path. With these packages, it is best to compile normally, then run +‘make -n install’, which should report all the steps needed to +install the just-built software. Place this output into a file, edit +the commands in the file to remove recompilation steps and to reflect +the Stow-based installation location, and execute the edited file as a +shell script in place of ‘make install’. Be sure to execute the +script using the same shell that ‘make install’ would have used. + +

(If you use GNU Make and a shell [such as GNU bash] that understands +pushd and popd, you can do the following: + +

    +
  1. Replace all lines matching ‘make[n]: Entering directory +dir’ with ‘pushd dir’. +
  2. Replace all lines matching ‘make[n]: Leaving directory +dir’ with ‘popd’. +
  3. Delete all lines matching ‘make[n]: Nothing to be done for +rule’. +
+ +

Then find other lines in the output containing cd or make +commands and rewrite or delete them. In particular, you should be able +to delete sections of the script that resemble this: + +

     for i in dir_1 dir_2 ...; do \
+       (cd $i; make args ...) \
+     done
+
+

Note, that's “should be able to,” not “can.” Be sure to modulate +these guidelines with plenty of your own intelligence. + +

The details of stowing some specific packages are described in the +following sections. + +

+ + + + diff --git a/.local/share/doc/stow/manual-split/Conflicts.html b/.local/share/doc/stow/manual-split/Conflicts.html new file mode 100644 index 0000000..6c58620 --- /dev/null +++ b/.local/share/doc/stow/manual-split/Conflicts.html @@ -0,0 +1,100 @@ + + +Conflicts - Stow + + + + + + + + + + + + +
+ +

+Next: , +Previous: Deleting Packages, +Up: Top +


+
+ +

7 Conflicts

+ +

If, during installation, a file or symlink exists in the target tree and +has the same name as something Stow needs to create, and if the +existing name is not a folded tree that can be split open, then a +conflict has arisen. A conflict also occurs if a directory exists +where Stow needs to place a symlink to a non-directory. On the +other hand, if the existing name is merely a symlink that already points +where Stow needs it to, then no conflict has occurred. (Thus it +is harmless to install a package that has already been installed.) + +

For complex packages, scanning the stow and target trees in tandem, +and deciding whether to make directories or links, split-open or fold +directories, can actually take a long time (a number of seconds). +Moreover, an accurate analysis of potential conflicts requires us to +take into account all of these operations. + +

+ +

7.1 Deferred Operation

+ +

+Since version 2.0, Stow now adopts a two-phase algorithm, first +scanning for any potential conflicts before any stowing or unstowing +operations are performed. If any conflicts are found, they are +displayed and then Stow terminates without making any modifications to +the filesystem. This means that there is much less risk of a package +being partially stowed or unstowed due to conflicts. + +

Prior to version 2.0, if a conflict was discovered, the stow or unstow +operation could be aborted mid-flow, leaving the target tree in an +inconsistent state. + + + + diff --git a/.local/share/doc/stow/manual-split/Cygnus-Software.html b/.local/share/doc/stow/manual-split/Cygnus-Software.html new file mode 100644 index 0000000..a98b83d --- /dev/null +++ b/.local/share/doc/stow/manual-split/Cygnus-Software.html @@ -0,0 +1,95 @@ + + +Cygnus Software - Stow + + + + + + + + + + + + + +

+ +

12.4 Cygnus Software

+ +

Cygnus is a commercial supplier and supporter of GNU software. It has +also written several of its own packages, released under the terms of +the GNU General Public License; and it has taken over the maintenance of +other packages. Among the packages released by Cygnus are ‘gdb’, +‘gnats’, and ‘dejagnu’. + +

Cygnus packages have the peculiarity that each one unpacks into a +directory tree with a generic top-level Makefile, which is set up to +compile all of Cygnus' packages, any number of which may reside +under the top-level directory. In other words, even if you're only +building ‘gnats’, the top-level Makefile will look for, and try to +build, gdb and dejagnu subdirectories, among many others. + +

The result is that if you try ‘make -n install +prefix=/usr/local/stow/package’ at the top level of a Cygnus +package, you'll get a bewildering amount of output. It will then be +very difficult to visually scan the output to see whether the install +will proceed correctly. Unfortunately, it's not always clear how to +invoke an install from the subdirectory of interest. + +

In cases like this, the best approach is to run your ‘make install +prefix=...’, but be ready to interrupt it if you detect that it +is recompiling files. Usually it will work just fine; otherwise, +install manually. + + + + diff --git a/.local/share/doc/stow/manual-split/Deferred-Operation.html b/.local/share/doc/stow/manual-split/Deferred-Operation.html new file mode 100644 index 0000000..ff438aa --- /dev/null +++ b/.local/share/doc/stow/manual-split/Deferred-Operation.html @@ -0,0 +1 @@ + diff --git a/.local/share/doc/stow/manual-split/Deleting-Packages.html b/.local/share/doc/stow/manual-split/Deleting-Packages.html new file mode 100644 index 0000000..0257f0e --- /dev/null +++ b/.local/share/doc/stow/manual-split/Deleting-Packages.html @@ -0,0 +1,112 @@ + + +Deleting Packages - Stow + + + + + + + + + + + + +

+ +

+Next: , +Previous: Installing Packages, +Up: Top +


+
+ +

6 Deleting Packages

+ +

When the -D option is given, the action of Stow is to +delete a package from the target tree. Note that Stow will not +delete anything it doesn't “own”. Deleting a package does not +mean removing it from the stow directory or discarding the package +tree. + +

To delete a package, Stow recursively scans the target tree, skipping over any +directory that is not included in the installation image.1 +For example, if the target directory is /usr/local and the +installation image for the package being deleted has only a bin +directory and a man directory at the top level, then we only scan +/usr/local/bin and /usr/local/bin/man, and not +/usr/local/lib or /usr/local/share, or for that matter +/usr/local/stow. Any symlink it finds that points into the package +being deleted is removed. Any directory that contained only symlinks to the +package being deleted is removed. + +

+ +

6.1 Refolding “foldable” trees.

+ +

+After removing symlinks and empty subdirectories, any directory that +contains only symlinks to a single other package is considered to be a +previously “folded” tree that was “split open.” Stow will refold +the tree by removing the symlinks to the surviving package, removing +the directory, then linking the directory back to the surviving +package. However, this behaviour can be prevented via the +--no-folding option; see Invoking Stow. + + +

+
+

Footnotes

[1] This +approach was introduced in version 2 of GNU Stow. Previously, the whole +target tree was scanned and stow directories were explicitly omitted. This +became problematic when dealing with very large installations. The only +situation where this is useful is if you accidentally delete a directory in +the package tree, leaving you with a whole bunch of dangling links. Note that +you can enable the old approach with the -p option. Alternatively, you can +use the --badlinks option get stow to search for dangling links in your target tree and remove the offenders manually.

+ +
+ + + diff --git a/.local/share/doc/stow/manual-split/GNU-Emacs.html b/.local/share/doc/stow/manual-split/GNU-Emacs.html new file mode 100644 index 0000000..3f44cce --- /dev/null +++ b/.local/share/doc/stow/manual-split/GNU-Emacs.html @@ -0,0 +1,97 @@ + + +GNU Emacs - Stow + + + + + + + + + + + + + + + +

12.2 GNU Emacs

+ +

Although the Free Software Foundation has many enlightened practices +regarding Makefiles and software installation (see see Other FSF Software), Emacs, its flagship program, doesn't quite follow the +rules. In particular, most GNU software allows you to write: + +

     make
+     make install prefix=/usr/local/stow/package
+
+

If you try this with Emacs, then the new value for prefix in the +‘make install’ step will cause some files to get recompiled with +the new value of prefix wired into them. In Emacs 19.23 and +later,1 +the way to work around this problem is: + +

     make
+     make install-arch-dep install-arch-indep prefix=/usr/local/stow/emacs
+
+

In 19.22 and some prior versions of Emacs, the workaround was: + +

     make
+     make do-install prefix=/usr/local/stow/emacs
+
+ +
+
+

Footnotes

[1] As I write this, the current version of Emacs is 19.31.

+ +
+ + + diff --git a/.local/share/doc/stow/manual-split/GNU-General-Public-License.html b/.local/share/doc/stow/manual-split/GNU-General-Public-License.html new file mode 100644 index 0000000..32b3c18 --- /dev/null +++ b/.local/share/doc/stow/manual-split/GNU-General-Public-License.html @@ -0,0 +1,411 @@ + + +GNU General Public License - Stow + + + + + + + + + + + + +
+ +

+Next: , +Previous: Known Bugs, +Up: Top +


+
+ +

GNU General Public License

+ +
Version 2, June 1991
+ +
     Copyright © 1989, 1991 Free Software Foundation, Inc.
+     675 Mass Ave, Cambridge, MA 02139, USA
+     
+     Everyone is permitted to copy and distribute verbatim copies
+     of this license document, but changing it is not allowed.
+
+

Preamble

+ +

The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software—to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + +

When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + +

To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +

For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + +

We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +

Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +

Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + +

The precise terms and conditions for copying, distribution and +modification follow. + +

    +
  1. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The “Program”, below, +refers to any such program or work, and a “work based on the Program” +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term “modification”.) Each licensee is addressed as “you”. + +

    Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + +

  2. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +

    You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +

  3. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +
      +
    1. You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change. + +
    2. You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any +part thereof, to be licensed as a whole at no charge to all third +parties under the terms of this License. + +
    3. If the modified program normally reads commands interactively +when run, you must cause it, when started running for such +interactive use in the most ordinary way, to print or display an +announcement including an appropriate copyright notice and a +notice that there is no warranty (or else, saying that you provide +a warranty) and that users may redistribute the program under +these conditions, and telling the user how to view a copy of this +License. (Exception: if the Program itself is interactive but +does not normally print such an announcement, your work based on +the Program is not required to print an announcement.) +
    + +

    These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +

    Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +

    In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +

  4. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + +
      +
    1. Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections +1 and 2 above on a medium customarily used for software interchange; or, + +
    2. Accompany it with a written offer, valid for at least three +years, to give any third party, for a charge no more than your +cost of physically performing source distribution, a complete +machine-readable copy of the corresponding source code, to be +distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, + +
    3. Accompany it with the information you received as to the offer +to distribute corresponding source code. (This alternative is +allowed only for noncommercial distribution and only if you +received the program in object code or executable form with such +an offer, in accord with Subsection b above.) +
    + +

    The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +

    If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + +

  5. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + +
  6. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +
  7. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +
  8. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +

    If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +

    It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +

    This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +

  9. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +
  10. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +

    Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and “any +later version”, you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + +

  11. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + +
  12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + +
  13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. +
+ +

How to Apply These Terms to Your New Programs

+ +

If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + +

To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the “copyright” line and a pointer to where the full notice is found. + +

     one line to give the program's name and an idea of what it does.
+     Copyright (C) 19yy  name of author
+     
+     This program is free software; you can redistribute it and/or
+     modify it under the terms of the GNU General Public License
+     as published by the Free Software Foundation; either version 2
+     of the License, or (at your option) any later version.
+     
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+     
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+

Also add information on how to contact you by electronic and paper mail. + +

If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + +

     Gnomovision version 69, Copyright (C) 19yy name of author
+     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+     type `show w'.  This is free software, and you are welcome
+     to redistribute it under certain conditions; type `show c'
+     for details.
+
+

The hypothetical commands ‘show w’ and ‘show c’ should show +the appropriate parts of the General Public License. Of course, the +commands you use may be called something other than ‘show w’ and +‘show c’; they could even be mouse-clicks or menu items—whatever +suits your program. + +

You should also get your employer (if you work as a programmer) or your +school, if any, to sign a “copyright disclaimer” for the program, if +necessary. Here is a sample; alter the names: + +

     Yoyodyne, Inc., hereby disclaims all copyright
+     interest in the program `Gnomovision'
+     (which makes passes at compilers) written
+     by James Hacker.
+     
+     signature of Ty Coon, 1 April 1989
+     Ty Coon, President of Vice
+
+

This General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications +with the library. If this is what you want to do, use the GNU Library +General Public License instead of this License. + + + diff --git a/.local/share/doc/stow/manual-split/Ignore-Lists.html b/.local/share/doc/stow/manual-split/Ignore-Lists.html new file mode 100644 index 0000000..219962e --- /dev/null +++ b/.local/share/doc/stow/manual-split/Ignore-Lists.html @@ -0,0 +1,77 @@ + + +Ignore Lists - Stow + + + + + + + + + + + + +

+ +

+Next: , +Previous: Invoking Stow, +Up: Top +


+
+ +

4 Ignore Lists

+ +

+ +

+ + + + diff --git a/.local/share/doc/stow/manual-split/Installing-Packages.html b/.local/share/doc/stow/manual-split/Installing-Packages.html new file mode 100644 index 0000000..a0abce2 --- /dev/null +++ b/.local/share/doc/stow/manual-split/Installing-Packages.html @@ -0,0 +1,156 @@ + + +Installing Packages - Stow + + + + + + + + + + + + +
+ +

+Next: , +Previous: Ignore Lists, +Up: Top +


+
+ +

5 Installing Packages

+ +

The default action of Stow is to install a package. This means creating +symlinks in the target tree that point into the package tree. Stow +attempts to do this with as few symlinks as possible; in other words, if +Stow can create a single symlink that points to an entire subtree within +the package tree, it will choose to do that rather than create a +directory in the target tree and populate it with symlinks. + +

+ +

5.1 Tree folding

+ +

For example, suppose that no packages have yet been installed in +/usr/local; it's completely empty (except for the stow +subdirectory, of course). Now suppose the Perl package is installed. +Recall that it includes the following directories in its installation +image: bin; info; lib/perl; man/man1. +Rather than creating the directory /usr/local/bin and populating +it with symlinks to ../stow/perl/bin/perl and +../stow/perl/bin/a2p (and so on), Stow will create a +single symlink, /usr/local/bin, which points to +stow/perl/bin. In this way, it still works to refer to +/usr/local/bin/perl and /usr/local/bin/a2p, and fewer +symlinks have been created. This is called tree folding, since an +entire subtree is “folded” into a single symlink. + +

To complete this example, Stow will also create the symlink +/usr/local/info pointing to stow/perl/info; the symlink +/usr/local/lib pointing to stow/perl/lib; and the symlink +/usr/local/man pointing to stow/perl/man. + +

Now suppose that instead of installing the Perl package into an empty +target tree, the target tree is not empty to begin with. Instead, it +contains several files and directories installed under a different +system-administration philosophy. In particular, /usr/local/bin +already exists and is a directory, as are /usr/local/lib and +/usr/local/man/man1. In this case, Stow will descend into +/usr/local/bin and create symlinks to +../stow/perl/bin/perl and ../stow/perl/bin/a2p (etc.), +and it will descend into /usr/local/lib and create the +tree-folding symlink perl pointing to +../stow/perl/lib/perl, and so on. As a rule, Stow only +descends as far as necessary into the target tree when it can create a +tree-folding symlink. However, this behaviour can be changed via +the --no-folding option; see Invoking Stow. + +

+ +

5.2 Tree unfolding

+ +

The time often comes when a tree-folding symlink has to be undone +because another package uses one or more of the folded subdirectories in +its installation image. This operation is called splitting open or +unfolding a folded tree. It involves removing the original symlink from +the target tree, creating a true directory in its place, and then populating the +new directory with symlinks to the newly-installed package and to +the old package that used the old symlink. For example, suppose that +after installing Perl into an empty /usr/local, we wish to +install Emacs. Emacs's installation image includes a bin +directory containing the emacs and etags executables, +among others. Stow must make these files appear to be installed +in /usr/local/bin, but presently /usr/local/bin is a +symlink to stow/perl/bin. Stow therefore takes the +following steps: the symlink /usr/local/bin is deleted; the +directory /usr/local/bin is created; links are made from +/usr/local/bin to ../stow/emacs/bin/emacs and +../stow/emacs/bin/etags; and links are made from +/usr/local/bin to ../stow/perl/bin/perl and +../stow/perl/bin/a2p. + +

5.3 Ownership

+ +

When splitting open a folded tree, Stow makes sure that the +symlink it is about to remove points inside a valid package in the +current stow directory. Stow will never delete anything +that it doesn't own. Stow “owns” everything living in the +target tree that points into a package in the stow directory. Anything +Stow owns, it can recompute if lost: symlinks that point into a package in +the stow directory, or directories that only contain symlinks that stow +“owns”. Note that by this definition, Stow doesn't “own” anything +in the stow directory or in any of the packages. + +

5.4 Conflicts during installation

+ +

If Stow needs to create a directory or a symlink in the target +tree and it cannot because that name is already in use and is not owned +by Stow, then a conflict has arisen. See Conflicts. + + + + diff --git a/.local/share/doc/stow/manual-split/Introduction.html b/.local/share/doc/stow/manual-split/Introduction.html new file mode 100644 index 0000000..0d971de --- /dev/null +++ b/.local/share/doc/stow/manual-split/Introduction.html @@ -0,0 +1,119 @@ + + +Introduction - Stow + + + + + + + + + + + + +

+ +

+Next: , +Previous: Top, +Up: Top +


+
+ +

1 Introduction

+ +

Stow is a tool for managing the installation of multiple software +packages in the same run-time directory tree. One historical difficulty +of this task has been the need to administer, upgrade, install, and +remove files in independent packages without confusing them with other +files sharing the same file system space. For instance, it is common to +install Perl and Emacs in /usr/local. When one does so, one +winds up with the following files1 in /usr/local/man/man1: + +

     a2p.1
+     ctags.1
+     emacs.1
+     etags.1
+     h2ph.1
+     perl.1
+     s2p.1
+
+

Now suppose it's time to uninstall Perl. Which man pages +get removed? Obviously perl.1 is one of them, but it should not +be the administrator's responsibility to memorize the ownership of +individual files by separate packages. + +

The approach used by Stow is to install each package into its own +tree, then use symbolic links to make it appear as though the files are +installed in the common tree. Administration can be performed in the +package's private tree in isolation from clutter from other packages. +Stow can then be used to update the symbolic links. The structure +of each private tree should reflect the desired structure in the common +tree; i.e. (in the typical case) there should be a bin directory +containing executables, a man/man1 directory containing section 1 +man pages, and so on. + +

Stow was inspired by Carnegie Mellon's Depot program, but is +substantially simpler and safer. Whereas Depot required database files +to keep things in sync, Stow stores no extra state between runs, so +there's no danger (as there was in Depot) of mangling directories when +file hierarchies don't match the database. Also unlike Depot, Stow will +never delete any files, directories, or links that appear in a Stow +directory (e.g., /usr/local/stow/emacs), so it's always possible +to rebuild the target tree (e.g., /usr/local). + +

For information about the latest version of Stow, you can refer to +http://www.gnu.org/software/stow/. + + +

+
+

Footnotes

[1] As of Perl 4.036 and Emacs +19.22.

+ +
+ + + diff --git a/.local/share/doc/stow/manual-split/Invoking-Stow.html b/.local/share/doc/stow/manual-split/Invoking-Stow.html new file mode 100644 index 0000000..ba12b4d --- /dev/null +++ b/.local/share/doc/stow/manual-split/Invoking-Stow.html @@ -0,0 +1,206 @@ + + +Invoking Stow - Stow + + + + + + + + + + + + +
+ +

+Next: , +Previous: Terminology, +Up: Top +


+
+ +

3 Invoking Stow

+ +

The syntax of the stow command is: + +

     stow [options] [action flag] package ...
+
+

Each package is the name of a package (e.g., ‘perl’) in the stow +directory that we wish to install into (or delete from) the target directory. +The default action is to install the given packages, although alternate actions +may be specified by preceding the package name(s) with an action flag. + +

The following options are supported: + +

+
-d dir
--dir=dir
Set the stow directory to dir. Defaults to the value of the environment +variable STOW_DIR if set, or the current directory otherwise. + +
-t dir
--target=dir
Set the target directory to dir instead of the parent of the stow +directory. Defaults to the parent of the stow directory, so it is typical to +execute stow from the directory /usr/local/stow. + +
--ignore=regexp
This (repeatable) option lets you suppress acting on files that match the +given perl regular expression. For example, using the options + +
          --ignore='*.orig' --ignore='*.dist'
+
+

will cause stow to ignore files ending in .orig or .dist. + +

Note that the regular expression is anchored to the end of the filename, +because this is what you will want to do most of the time. + +

Also note that by default Stow automatically ignores a “sensible” +built-in list of files and directories such as CVS, editor +backup files, and so on. See Ignore Lists, for more details. + +

--defer=regexp
This (repeatable) option avoids stowing a file matching the given +regular expression, if that file is already stowed by another package. +This is effectively the opposite of --override. + +

(N.B. the name --defer was chosen in the sense that the package +currently being stowed is treated with lower precedence than any +already installed package, not in the sense that the operation is +being postponed to be run at a later point in time; do not confuse +this nomenclature with the wording used in Deferred Operation.) + +

For example, the following options + +

          --defer=man --defer=info
+
+

will cause stow to skip over pre-existing man and info pages. + +

Equivalently, you could use ‘--defer='man|info'’ since the +argument is just a Perl regex. + +

Note that the regular expression is anchored to the beginning of the path +relative to the target directory, because this is what you will want to do most +of the time. + +

--override=regexp
This (repeatable) option forces any file matching the regular expression to be +stowed, even if the file is already stowed to another package. For example, +the following options + +
          --override=man --override=info
+
+

will permit stow to overwrite links that point to pre-existing man and info +pages that are owned by stow and would otherwise cause a conflict. + +

The regular expression is anchored to the beginning of the path relative to +the target directory, because this is what you will want to do most of the time. + +

--no-folding
+This disables any further tree folding or tree refolding. +If a new subdirectory is encountered whilst stowing a new package, the +subdirectory is created within the target, and its contents are +symlinked, rather than just creating a symlink for the directory. If +removal of symlinks whilst unstowing a package causes a subtree to be +foldable (i.e. only containing symlinks to a single package), that +subtree will not be removed and replaced with a symlink. + +


--adopt
Warning! This behaviour is specifically intended to alter the +contents of your stow directory. If you do not want that, this option +is not for you. + +

When stowing, if a target is encountered which already exists but is a +plain file (and hence not owned by any existing stow package), then +normally Stow will register this as a conflict and refuse to proceed. +This option changes that behaviour so that the file is moved to the +same relative place within the package's installation image within the +stow directory, and then stowing proceeds as before. So effectively, +the file becomes adopted by the stow package, without its contents +changing. + +

This is particularly useful when the stow package is under the control +of a version control system, because it allows files in the target +tree, with potentially different contents to the equivalent versions +in the stow package's installation image, to be adopted into the +package, then compared by running something like ‘git diff ...’ +inside the stow package, and finally either kept (e.g. via ‘git +commit ...’) or discarded (‘git checkout HEAD ...’). + +


-n
--no
--simulate
Do not perform any operations that modify the file system; in combination with +-v can be used to merely show what would happen. + +


-v
--verbose[=n]
Send verbose output to standard error describing what Stow is +doing. Verbosity levels are 0, 1, 2, and 3; 0 is the default. Using +-v or --verbose increases the verbosity by one; using +‘--verbose=n’ sets it to n. + +
-p
--compat
Scan the whole target tree when unstowing. By default, only +directories specified in the installation image are scanned +during an unstow operation. Scanning the whole tree can be +prohibitive if your target tree is very large. This option restores +the legacy behaviour; however, the --badlinks option to the +chkstow utility may be a better way of ensuring that your +installation does not have any dangling symlinks (see Target Maintenance). + +
-V
--version
Show Stow version number, and exit. + +
-h
--help
Show Stow command syntax, and exit. +
+ +

The following action flags are supported: + +

+
-D
--delete
Delete (unstow) the package name(s) that follow this option from the target +directory. This option may be repeated any number of times. + +
-R
--restow
Restow (first unstow, then stow again) the package names that follow this +option. This is useful for pruning obsolete symlinks from the target tree +after updating the software in a package. This option may be repeated any +number of times. + +
-S
--stow
explictly stow the package name(s) that follow this option. May be +omitted if you are not using the -D or -R options in the +same invocation. See Mixing Operations, for details of when you +might like to use this feature. This option may be repeated any number +of times. +
+ + + + diff --git a/.local/share/doc/stow/manual-split/Justification-For-Yet-Another-Set-Of-Ignore-Files.html b/.local/share/doc/stow/manual-split/Justification-For-Yet-Another-Set-Of-Ignore-Files.html new file mode 100644 index 0000000..c6cc9c3 --- /dev/null +++ b/.local/share/doc/stow/manual-split/Justification-For-Yet-Another-Set-Of-Ignore-Files.html @@ -0,0 +1,93 @@ + + +Justification For Yet Another Set Of Ignore Files - Stow + + + + + + + + + + + + + + +

4.3 Justification For Yet Another Set Of Ignore Files

+ +

The reader may note that this format is very similar to existing +ignore list file formats, such as those for cvs, git, +rsync etc., and wonder if another set of ignore lists is +justified. However there are good reasons why Stow does not simply +check for the presence of say, .cvsignore, and use that if it +exists. Firstly, there is no guarantee that a stow package would +contain any version control meta-data, or permit introducing this if +it didn't already exist. + +

Secondly even if it did, version control system ignore lists generally +reflect build-time ignores rather than install-time, and +there may be some intermediate or temporary files on those ignore +lists generated during development or at build-time which it would be +inappropriate to stow, even though many files generated at build-time +(binaries, libraries, documentation etc.) certainly do need to be +stowed. Similarly, if a file is not in the version control +system's ignore list, there is no way of knowing whether the file is +intended for end use, let alone whether the version control system is +tracking it or not. + +

Therefore it seems clear that ignore lists provided by version control +systems do not provide sufficient information for Stow to determine +which files and directories to stow, and so it makes sense for Stow to +support independent ignore lists. + + + + diff --git a/.local/share/doc/stow/manual-split/Known-Bugs.html b/.local/share/doc/stow/manual-split/Known-Bugs.html new file mode 100644 index 0000000..bef4833 --- /dev/null +++ b/.local/share/doc/stow/manual-split/Known-Bugs.html @@ -0,0 +1,76 @@ + + +Known Bugs - Stow + + + + + + + + + + + + +

+ +

+Next: , +Previous: Reporting Bugs, +Up: Top +


+
+ +

15 Known Bugs

+ +

There are no known bugs in Stow version 2.2.2! +If you think you have found one, please see Reporting Bugs. + + + + + + + + diff --git a/.local/share/doc/stow/manual-split/Mixing-Operations.html b/.local/share/doc/stow/manual-split/Mixing-Operations.html new file mode 100644 index 0000000..1267fc1 --- /dev/null +++ b/.local/share/doc/stow/manual-split/Mixing-Operations.html @@ -0,0 +1,90 @@ + + +Mixing Operations - Stow + + + + + + + + + + + + +

+ +

+Next: , +Previous: Conflicts, +Up: Top +


+
+ +

8 Mixing Operations

+ +

+Since version 2.0, multiple distinct actions can be specified in a single +invocation of GNU Stow. For example, to update an installation of Emacs from +version 21.3 to 21.4a you can now do the following: + +

     stow -D emacs-21.3 -S emacs-21.4a
+
+

which will replace emacs-21.3 with emacs-21.4a using a single invocation. + +

This is much faster and cleaner than performing two separate +invocations of stow, because redundant folding/unfolding operations +can be factored out. In addition, all the operations are calculated +and merged before being executed (see Deferred Operation), so the +amount of of time in which GNU Emacs is unavailable is minimised. + +

You can mix and match any number of actions, for example, + +

     stow -S pkg1 pkg2 -D pkg3 pkg4 -S pkg5 -R pkg6
+
+

will unstow pkg3, pkg4 and pkg6, then stow pkg1, pkg2, pkg5 and pkg6. + + + + diff --git a/.local/share/doc/stow/manual-split/Motivation-For-Ignore-Lists.html b/.local/share/doc/stow/manual-split/Motivation-For-Ignore-Lists.html new file mode 100644 index 0000000..37461e4 --- /dev/null +++ b/.local/share/doc/stow/manual-split/Motivation-For-Ignore-Lists.html @@ -0,0 +1,94 @@ + + +Motivation For Ignore Lists - Stow + + + + + + + + + + + + + +

+ +

+Next: , +Previous: Ignore Lists, +Up: Ignore Lists +


+
+ +

4.1 Motivation For Ignore Lists

+ +

In many situations, there will exist files under the package +directories which it would be undesirable to stow into the target +directory. For example, files related version control such as +.gitignore, CVS, *,v (RCS files) should typically +not have symlinks from the target tree pointing to them. Also there +may be files or directories relating to the build of the package which +are not needed at run-time. + +

In these cases, it can be rather cumbersome to specify a +--ignore parameter for each file or directory to be ignored. +This could be worked around by ensuring the existence of +~/.stowrc containing multiple --ignore lines, or if a +different set of files/directories should be ignored depending on +which stow package is involved, a .stowrc file for each stow +package, but this would require the user to ensure that they were in +the correct directory before invoking stow, which would be tedious and +error-prone. Furthermore, since Stow shifts parameters from +.stowrc onto ARGV at run-time, it could clutter up the process +table with excessively long parameter lists, or even worse, exceed the +operating system's limit for process arguments. + +

Therefore in addition to --ignore parameters, Stow provides a +way to specify lists of files and directories to ignore. + + + + diff --git a/.local/share/doc/stow/manual-split/Multiple-Stow-Directories.html b/.local/share/doc/stow/manual-split/Multiple-Stow-Directories.html new file mode 100644 index 0000000..e8573d1 --- /dev/null +++ b/.local/share/doc/stow/manual-split/Multiple-Stow-Directories.html @@ -0,0 +1,86 @@ + + +Multiple Stow Directories - Stow + + + + + + + + + + + + +

+ +

+Next: , +Previous: Mixing Operations, +Up: Top +


+
+ +

9 Multiple Stow Directories

+ +

If there are two or more system administrators who wish to maintain +software separately, or if there is any other reason to want two or more +stow directories, it can be done by creating a file named .stow +in each stow directory. The presence of /usr/local/foo/.stow +informs Stow that, though foo is not the current stow +directory, even if it is a subdirectory of the target directory, +nevertheless it is a stow directory and as such Stow +doesn't “own” anything in it (see Installing Packages). This will +protect the contents of foo from a ‘stow -D’, for instance. + + +

When multiple stow directories share a target tree, if a tree-folding +symlink is encountered and needs to be split open during an +installation, as long as the top-level stow directory into which the +existing symlink points contains .stow, Stow knows how to split +open the tree in the correct manner. + + + + diff --git a/.local/share/doc/stow/manual-split/Other-FSF-Software.html b/.local/share/doc/stow/manual-split/Other-FSF-Software.html new file mode 100644 index 0000000..46a1d20 --- /dev/null +++ b/.local/share/doc/stow/manual-split/Other-FSF-Software.html @@ -0,0 +1,85 @@ + + +Other FSF Software - Stow + + + + + + + + + + + + + +

+ +

+Next: , +Previous: GNU Emacs, +Up: Compile-time vs Install-time +


+
+ +

12.3 Other FSF Software

+ +

The Free Software Foundation, the organization behind the GNU project, +has been unifying the build procedure for its tools for some time. +Thanks to its tools ‘autoconf’ and ‘automake’, most packages +now respond well to these simple steps, with no other intervention +necessary: + +

     ./configure options
+     make
+     make install prefix=/usr/local/stow/package
+
+

Hopefully, these tools can evolve to be aware of Stow-managed packages, +such that providing an option to ‘configure’ can allow ‘make’ +and ‘make install’ steps to work correctly without needing to +“fool” the build process. + + + + diff --git a/.local/share/doc/stow/manual-split/Perl-and-Perl-5-Modules.html b/.local/share/doc/stow/manual-split/Perl-and-Perl-5-Modules.html new file mode 100644 index 0000000..6c082bb --- /dev/null +++ b/.local/share/doc/stow/manual-split/Perl-and-Perl-5-Modules.html @@ -0,0 +1,150 @@ + + +Perl and Perl 5 Modules - Stow + + + + + + + + + + + + +

+ +

+Previous: Cygnus Software, +Up: Compile-time vs Install-time +


+
+ +

12.5 Perl and Perl 5 Modules

+ +

Perl 4.036 allows you to specify different locations for installation +and for run-time. It is the only widely-used package in this author's +experience that allows this, though hopefully more packages will adopt +this model. + +

Unfortunately, the authors of Perl believed that only AFS sites need +this ability. The configuration instructions for Perl 4 misleadingly +state that some occult means are used under AFS to transport files from +their installation tree to their run-time tree. In fact, that confusion +arises from the fact that Depot, Stow's predecessor, originated at +Carnegie Mellon University, which was also the birthplace of AFS. CMU's +need to separate install-time and run-time trees stemmed from its use of +Depot, not from AFS. + +

The result of this confusion is that Perl 5's configuration script +doesn't even offer the option of separating install-time and run-time +trees unless you're running AFS. Fortunately, after you've +entered all the configuration settings, Perl's setup script gives you +the opportunity to edit those settings in a file called +config.sh. When prompted, you should edit this file and replace +occurrences of + +

     inst.../usr/local...
+
+

with + +

     inst.../usr/local/stow/perl...
+
+

You can do this with the following Unix command: + +

     sed 's,^\(inst.*/usr/local\),\1/stow/perl,' config.sh > config.sh.new
+     mv config.sh.new config.sh
+
+

Hopefully, the Perl authors will correct this deficiency in Perl 5's +configuration mechanism. + +

Perl 5 modules—i.e., extensions to Perl 5—generally conform to a set +of standards for building and installing them. The standard says that +the package comes with a top-level Makefile.PL, which is a Perl +script. When it runs, it generates a Makefile. + +

If you followed the instructions above for editing config.sh when +Perl was built, then when you create a Makefile from a +Makefile.PL, it will contain separate locations for run-time +(/usr/local) and install-time (/usr/local/stow/perl). +Thus you can do + +

     perl Makefile.PL
+     make
+     make install
+
+

and the files will be installed into /usr/local/stow/perl. +However, you might prefer each Perl module to be stowed separately. In +that case, you must edit the resulting Makefile, replacing +/usr/local/stow/perl with /usr/local/stow/module. +The best way to do this is: + +

     perl Makefile.PL
+     find . -name Makefile -print | \
+       xargs perl -pi~ -e 's,^(INST.*/stow)/perl,$1/module,;'
+     make
+     make install
+
+

(The use of ‘find’ and ‘xargs’ ensures that all Makefiles in +the module's source tree, even those in subdirectories, get edited.) A +good convention to follow is to name the stow directory for a Perl +module cpan.module, where ‘cpan’ stands for +Comprehensive Perl Archive Network, a collection of FTP sites that is +the source of most Perl 5 extensions. This way, it's easy to tell at a +glance which of the subdirectories of /usr/local/stow are Perl 5 +extensions. + +

When you stow separate Perl 5 modules separately, you are likely to +encounter conflicts (see Conflicts) with files named .exists +and perllocal.pod. One way to work around this is to remove +those files before stowing the module. If you use the +cpan.module naming convention, you can simply do this: + +

     cd /usr/local/stow
+     find cpan.* \( -name .exists -o -name perllocal.pod \) -print | \
+       xargs rm
+
+ + + diff --git a/.local/share/doc/stow/manual-split/Reporting-Bugs.html b/.local/share/doc/stow/manual-split/Reporting-Bugs.html new file mode 100644 index 0000000..6f3f6c2 --- /dev/null +++ b/.local/share/doc/stow/manual-split/Reporting-Bugs.html @@ -0,0 +1,98 @@ + + +Reporting Bugs - Stow + + + + + + + + + + + + +
+ +

+Next: , +Previous: Bootstrapping, +Up: Top +


+
+ +

14 Reporting Bugs

+ +

Please send bug reports to the current maintainers by electronic +mail. The address to use is ‘<bug-stow@gnu.org>’. Please +include: + +

    +
  • the version number of Stow (‘stow --version’); + +
  • the version number of Perl (‘perl -v’); + +
  • the system information, which can often be obtained with ‘uname +-a’; + +
  • a description of the bug; + +
  • the precise command you gave; + +
  • the output from the command (preferably verbose output, obtained by +adding ‘--verbose=3’ to the Stow command line). +
+ +

If you are really keen, consider developing a minimal test case and +creating a new test. See the t/ directory in the source for +lots of examples. + +

Before reporting a bug, please read the manual carefully, especially +Known Bugs, to see whether you're encountering +something that doesn't need reporting. +(see Conflicts). + + + + diff --git a/.local/share/doc/stow/manual-split/Resource-Files.html b/.local/share/doc/stow/manual-split/Resource-Files.html new file mode 100644 index 0000000..7abb7fc --- /dev/null +++ b/.local/share/doc/stow/manual-split/Resource-Files.html @@ -0,0 +1,108 @@ + + +Resource Files - Stow + + + + + + + + + + + + +

+ +

+Next: , +Previous: Target Maintenance, +Up: Top +


+
+ +

11 Resource Files

+ +

+Default command line options may be set in .stowrc (current directory) or +~/.stowrc (home directory). These are parsed in that order, and effectively +prepended to you command line. This feature can be used for some interesting +effects. + +

For example, suppose your site uses more than one stow directory, perhaps in +order to share around responsibilities with a number of systems +administrators. One of the administrators might have the following in their +~/.stowrc file: + +

     --dir=/usr/local/stow2
+     --target=/usr/local
+     --ignore='~'
+     --ignore='^CVS'
+
+

so that the stow command will default to operating on the +/usr/local/stow2 directory, with /usr/local as the +target, and ignoring vi backup files and CVS directories. + +

If you had a stow directory /usr/local/stow/perl-extras that +was only used for Perl modules, then you might place the following in +/usr/local/stow/perl-extras/.stowrc: + +

     --dir=/usr/local/stow/perl-extras
+     --target=/usr/local
+     --override=bin
+     --override=man
+     --ignore='perllocal\.pod'
+     --ignore='\.packlist'
+     --ignore='\.bs'
+
+

so that when you are in the /usr/local/stow/perl-extras +directory, stow will regard any subdirectories as stow +packages, with /usr/local as the target (rather than the +immediate parent directory /usr/local/stow), overriding any +pre-existing links to bin files or man pages, and ignoring some cruft +that gets installed by default. + + + + diff --git a/.local/share/doc/stow/manual-split/Target-Maintenance.html b/.local/share/doc/stow/manual-split/Target-Maintenance.html new file mode 100644 index 0000000..d283e35 --- /dev/null +++ b/.local/share/doc/stow/manual-split/Target-Maintenance.html @@ -0,0 +1,98 @@ + + +Target Maintenance - Stow + + + + + + + + + + + + +

+ +

+Next: , +Previous: Multiple Stow Directories, +Up: Top +


+
+ +

10 Target Maintenance

+ +

From time to time you will need to clean up your target tree. Since +version 2, Stow provides a new utility chkstow to help with +this. It includes three operational modes which performs checks that +would generally be too expensive to be performed during normal stow +execution. + +

The syntax of the chkstow command is: + +

     chkstow [options]
+
+

The following options are supported: + +

+
-t dir
--target=dir
Set the target directory to dir instead of the parent of the stow +directory. Defaults to the parent of the stow directory, so it is typical to +execute stow from the directory /usr/local/stow. + +
-b
--badlinks
Checks target directory for bogus symbolic links. That is, links that point to +non-existent files. + +
-a
--aliens
Checks for files in the target directory that are not symbolic links. The +target directory should be managed by stow alone, except for directories that +contain a .stow file. + +
-l
--list
Will display the target package for every symbolic link in the stow target +directory. + +
+ + + + diff --git a/.local/share/doc/stow/manual-split/Terminology.html b/.local/share/doc/stow/manual-split/Terminology.html new file mode 100644 index 0000000..a7b403e --- /dev/null +++ b/.local/share/doc/stow/manual-split/Terminology.html @@ -0,0 +1,113 @@ + + +Terminology - Stow + + + + + + + + + + + + +
+ +

+Next: , +Previous: Introduction, +Up: Top +


+
+ +

2 Terminology

+ +

A package is a related collection of files and directories that +you wish to administer as a unit — e.g., Perl or Emacs — and that needs +to be installed in a particular directory structure — e.g., with +bin, lib, and man subdirectories. + +

A target directory is the root of a tree in which one or more +packages wish to appear to be installed. A common, but by no +means the only such location is /usr/local. The examples in this +manual will use /usr/local as the target directory. + +

A stow directory is the root of a tree containing separate +packages in private subtrees. When Stow runs, it uses the current +directory as the default stow directory. The examples in this manual +will use /usr/local/stow as the stow directory, so that +individual packages will be, for example, /usr/local/stow/perl +and /usr/local/stow/emacs. + +

An installation image is the layout of files and directories +required by a package, relative to the target directory. Thus, the +installation image for Perl includes: a bin directory containing +perl and a2p (among others); an info directory +containing Texinfo documentation; a lib/perl directory containing +Perl libraries; and a man/man1 directory containing man pages. + +

A package directory is the root of a tree containing the +installation image for a particular package. Each package directory +must reside in a stow directory — e.g., the package directory +/usr/local/stow/perl must reside in the stow directory +/usr/local/stow. The name of a package is the name of its +directory within the stow directory — e.g., perl. + +

Thus, the Perl executable might reside in +/usr/local/stow/perl/bin/perl, where /usr/local is the +target directory, /usr/local/stow is the stow directory, +/usr/local/stow/perl is the package directory, and +bin/perl within is part of the installation image. + +

A symlink is a symbolic link. A symlink can be relative or +absolute. An absolute symlink names a full path; that is, one +starting from /. A relative symlink names a relative path; that +is, one not starting from /. The target of a relative symlink is +computed starting from the symlink's own directory. Stow only +creates relative symlinks. + + + + diff --git a/.local/share/doc/stow/manual-split/Tree-unfolding.html b/.local/share/doc/stow/manual-split/Tree-unfolding.html new file mode 100644 index 0000000..f9d21bf --- /dev/null +++ b/.local/share/doc/stow/manual-split/Tree-unfolding.html @@ -0,0 +1 @@ + diff --git a/.local/share/doc/stow/manual-split/Types-And-Syntax-Of-Ignore-Lists.html b/.local/share/doc/stow/manual-split/Types-And-Syntax-Of-Ignore-Lists.html new file mode 100644 index 0000000..879192c --- /dev/null +++ b/.local/share/doc/stow/manual-split/Types-And-Syntax-Of-Ignore-Lists.html @@ -0,0 +1,167 @@ + + +Types And Syntax Of Ignore Lists - Stow + + + + + + + + + + + + + +

+ +

4.2 Types And Syntax Of Ignore Lists

+ +

If you put Perl regular expressions, one per line, in a +.stow-local-ignore file within any top level package directory, +in which case any file or directory within that package matching any +of these regular expressions will be ignored. In the absence of this +package-specific ignore list, Stow will instead use the contents of +~/.stow-global-ignore, if it exists. If neither the +package-local or global ignore list exist, Stow will use its own +built-in default ignore list, which serves as a useful example of the +format of these ignore list files: + +

     # Comments and blank lines are allowed.
+     
+     RCS
+     .+,v
+     
+     CVS
+     \.\#.+       # CVS conflict files / emacs lock files
+     \.cvsignore
+     
+     \.svn
+     _darcs
+     \.hg
+     
+     \.git
+     \.gitignore
+     
+     .+~          # emacs backup files
+     \#.*\#       # emacs autosave files
+     
+     ^/README.*
+     ^/LICENSE.*
+     ^/COPYING
+
+

Stow first iterates through the chosen ignore list (built-in, global, +or package-local) as per above, stripping out comments (if you want to +include the ‘#’ symbol in a regular expression, escape it with a +blackslash) and blank lines, placing each regular expressions into one +of two sets depending on whether it contains the ‘/’ forward +slash symbol. + +

Then in order to determine whether a file or directory should be +ignored: + +

    +
  1. Stow calculates its path relative to the top-level package directory, +prefixing that with ‘/’. If any of the regular expressions +containing a ‘/exactly1 match +a subpath2 of this relative path, then the file or +directory will be ignored. + +
  2. If none of the regular expressions containing a ‘/’ match in the +manner described above, Stow checks whether the +basename3 of the file or directory matches +exactly against the remaining regular expressions which do not +contain a ‘/’, and if so, ignores the file or directory. + +
  3. Otherwise, the file or directory is not ignored. +
+ + + +

For example, if a file bazqux is in the foo/bar +subdirectory of the package directory, Stow would use +‘/foo/bar/bazqux’ as the text for matching against regular +expressions which contain ‘/’, and ‘bazqux’ as the text for +matching against regular expressions which don't contain ‘/’. +Then regular expressions ‘bazqux’, ‘baz.*’, ‘.*qux’, +‘bar/.*x’, and ‘^/foo/.*qux’ would all match (causing the +file to be ignored), whereas ‘bar’, ‘baz’, ‘qux’, and +‘o/bar/b’ would not (although ‘bar’ would cause its parent +directory to be ignored and prevent Stow from recursing into that +anyway, in which case the file bazqux would not even be +considered for stowing). + +

As a special exception to the above algorithm, any +.stow-local-ignore present in the top-level package directory +is always ignored, regardless of the contents of any ignore +list, because this file serves no purpose outside the stow directory. + + +

+
+

Footnotes

[1] Exact matching means the +regular expression is anchored at the beginning and end, in contrast +to unanchored regular expressions which will match a substring.

+ +

[2] In this context, “subpath” means a contiguous +subset of path segments; e.g for the relative path +one/two/three, there are six valid subpaths: one, +two, three, one/two, two/three, +one/two/three.

+ +

[3] The “basename” is the name of the file or +directory itself, excluding any directory path prefix - as returned by +the basename command.

+ +
+ + + diff --git a/.local/share/doc/stow/manual-split/index.html b/.local/share/doc/stow/manual-split/index.html new file mode 100644 index 0000000..e8dd536 --- /dev/null +++ b/.local/share/doc/stow/manual-split/index.html @@ -0,0 +1,164 @@ + + +Stow + + + + + + + + + + +

Stow

+ + + + + +
+ +

+Next: , +Up: (dir) +


+
+ +

Stow

+ + +

--- The Detailed Node Listing --- + +

Ignore Lists + +

+ +

Advice on changing compilation and installation parameters + +

+ + + + + diff --git a/.local/share/doc/stow/manual-split/tree-folding.html b/.local/share/doc/stow/manual-split/tree-folding.html new file mode 100644 index 0000000..cc06e05 --- /dev/null +++ b/.local/share/doc/stow/manual-split/tree-folding.html @@ -0,0 +1 @@ + diff --git a/.local/share/doc/stow/manual-split/tree-refolding.html b/.local/share/doc/stow/manual-split/tree-refolding.html new file mode 100644 index 0000000..5d17385 --- /dev/null +++ b/.local/share/doc/stow/manual-split/tree-refolding.html @@ -0,0 +1 @@ + diff --git a/.local/share/doc/stow/manual.pdf b/.local/share/doc/stow/manual.pdf new file mode 100644 index 0000000..38eb348 Binary files /dev/null and b/.local/share/doc/stow/manual.pdf differ diff --git a/.local/share/doc/stow/version.texi b/.local/share/doc/stow/version.texi new file mode 100644 index 0000000..a9d4737 --- /dev/null +++ b/.local/share/doc/stow/version.texi @@ -0,0 +1,4 @@ +@set UPDATED 9 November 2015 +@set UPDATED-MONTH November 2015 +@set EDITION 2.2.2 +@set VERSION 2.2.2 diff --git a/.local/share/info/dir b/.local/share/info/dir new file mode 100644 index 0000000..cd5f8a5 --- /dev/null +++ b/.local/share/info/dir @@ -0,0 +1,18 @@ +This is the file .../info/dir, which contains the +topmost node of the Info hierarchy, called (dir)Top. +The first time you invoke Info you start off looking at this node. + +File: dir, Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "?" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs" visits the Emacs manual, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: + +System administration +* Stow: (stow). GNU Stow. diff --git a/.local/share/info/stow.info b/.local/share/info/stow.info new file mode 100644 index 0000000..0ee4e1d --- /dev/null +++ b/.local/share/info/stow.info @@ -0,0 +1,1585 @@ +This is doc/stow.info, produced by makeinfo version 4.13 from +./doc/stow.texi. + +This manual describes GNU Stow version 2.2.2 (9 November 2015), a +program for managing the installation of software packages. + + Software and documentation is copyrighted by the following: + + (C) 1993, 1994, 1995, 1996 Bob Glickstein +(C) 2000, 2001 Guillaume Morin +(C) 2007 Kahlil (Kal) Hodgson +(C) 2011 Adam Spiers + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission + notice are preserved on all copies. + + Permission is granted to copy and distribute modified versions of + this manual under the conditions for verbatim copying, provided + also that the section entitled "GNU General Public License" is + included with the modified manual, and provided that the entire + resulting derived work is distributed under the terms of a + permission notice identical to this one. + + Permission is granted to copy and distribute translations of this + manual into another language, under the above conditions for + modified versions, except that this permission notice may be + stated in a translation approved by the Free Software Foundation. + +INFO-DIR-SECTION System administration +START-INFO-DIR-ENTRY +* Stow: (stow). GNU Stow. +END-INFO-DIR-ENTRY + + +File: stow.info, Node: Top, Next: Introduction, Up: (dir) + +Stow +**** + +This manual describes GNU Stow 2.2.2 (9 November 2015), a program for +managing the installation of software packages. + +* Menu: + +* Introduction:: Description of Stow. +* Terminology:: Terms used by this manual. +* Invoking Stow:: Option summary. +* Ignore Lists:: Controlling what gets stowed. +* Installing Packages:: Using Stow to install. +* Deleting Packages:: Using Stow to uninstall. +* Conflicts:: When Stow can't stow. +* Mixing Operations:: Multiple actions per invocation. +* Multiple Stow Directories:: Further segregating software. +* Target Maintenance:: Cleaning up mistakes. +* Resource Files:: Setting default command line options. +* Compile-time vs Install-time:: Faking out `make install'. +* Bootstrapping:: When stow and perl are not yet stowed. +* Reporting Bugs:: How, what, where, and when to report. +* Known Bugs:: Don't report any of these. +* GNU General Public License:: Copying terms. +* Index:: Index of concepts. + + --- The Detailed Node Listing --- + +Ignore Lists + +* Motivation For Ignore Lists:: +* Types And Syntax Of Ignore Lists:: +* Justification For Yet Another Set Of Ignore Files:: + +Advice on changing compilation and installation parameters + +* GNU Emacs:: +* Other FSF Software:: +* Cygnus Software:: +* Perl and Perl 5 Modules:: + + +File: stow.info, Node: Introduction, Next: Terminology, Prev: Top, Up: Top + +1 Introduction +************** + +Stow is a tool for managing the installation of multiple software +packages in the same run-time directory tree. One historical difficulty +of this task has been the need to administer, upgrade, install, and +remove files in independent packages without confusing them with other +files sharing the same file system space. For instance, it is common to +install Perl and Emacs in `/usr/local'. When one does so, one winds up +with the following files(1) in `/usr/local/man/man1': + + a2p.1 + ctags.1 + emacs.1 + etags.1 + h2ph.1 + perl.1 + s2p.1 + +Now suppose it's time to uninstall Perl. Which man pages get removed? +Obviously `perl.1' is one of them, but it should not be the +administrator's responsibility to memorize the ownership of individual +files by separate packages. + + The approach used by Stow is to install each package into its own +tree, then use symbolic links to make it appear as though the files are +installed in the common tree. Administration can be performed in the +package's private tree in isolation from clutter from other packages. +Stow can then be used to update the symbolic links. The structure of +each private tree should reflect the desired structure in the common +tree; i.e. (in the typical case) there should be a `bin' directory +containing executables, a `man/man1' directory containing section 1 man +pages, and so on. + + Stow was inspired by Carnegie Mellon's Depot program, but is +substantially simpler and safer. Whereas Depot required database files +to keep things in sync, Stow stores no extra state between runs, so +there's no danger (as there was in Depot) of mangling directories when +file hierarchies don't match the database. Also unlike Depot, Stow will +never delete any files, directories, or links that appear in a Stow +directory (e.g., `/usr/local/stow/emacs'), so it's always possible to +rebuild the target tree (e.g., `/usr/local'). + + For information about the latest version of Stow, you can refer to +`http://www.gnu.org/software/stow/'. + + ---------- Footnotes ---------- + + (1) As of Perl 4.036 and Emacs 19.22. + + +File: stow.info, Node: Terminology, Next: Invoking Stow, Prev: Introduction, Up: Top + +2 Terminology +************* + + A "package" is a related collection of files and directories that +you wish to administer as a unit -- e.g., Perl or Emacs -- and that +needs to be installed in a particular directory structure -- e.g., with +`bin', `lib', and `man' subdirectories. + + A "target directory" is the root of a tree in which one or more +packages wish to _appear_ to be installed. A common, but by no means +the only such location is `/usr/local'. The examples in this manual +will use `/usr/local' as the target directory. + + A "stow directory" is the root of a tree containing separate +packages in private subtrees. When Stow runs, it uses the current +directory as the default stow directory. The examples in this manual +will use `/usr/local/stow' as the stow directory, so that individual +packages will be, for example, `/usr/local/stow/perl' and +`/usr/local/stow/emacs'. + + An "installation image" is the layout of files and directories +required by a package, relative to the target directory. Thus, the +installation image for Perl includes: a `bin' directory containing +`perl' and `a2p' (among others); an `info' directory containing Texinfo +documentation; a `lib/perl' directory containing Perl libraries; and a +`man/man1' directory containing man pages. + + A "package directory" is the root of a tree containing the +installation image for a particular package. Each package directory +must reside in a stow directory -- e.g., the package directory +`/usr/local/stow/perl' must reside in the stow directory +`/usr/local/stow'. The "name" of a package is the name of its +directory within the stow directory -- e.g., `perl'. + + Thus, the Perl executable might reside in +`/usr/local/stow/perl/bin/perl', where `/usr/local' is the target +directory, `/usr/local/stow' is the stow directory, +`/usr/local/stow/perl' is the package directory, and `bin/perl' within +is part of the installation image. + + A "symlink" is a symbolic link. A symlink can be "relative" or +"absolute". An absolute symlink names a full path; that is, one +starting from `/'. A relative symlink names a relative path; that is, +one not starting from `/'. The target of a relative symlink is +computed starting from the symlink's own directory. Stow only creates +relative symlinks. + + +File: stow.info, Node: Invoking Stow, Next: Ignore Lists, Prev: Terminology, Up: Top + +3 Invoking Stow +*************** + +The syntax of the `stow' command is: + + stow [OPTIONS] [ACTION FLAG] PACKAGE ... + +Each PACKAGE is the name of a package (e.g., `perl') in the stow +directory that we wish to install into (or delete from) the target +directory. The default action is to install the given packages, +although alternate actions may be specified by preceding the package +name(s) with an ACTION FLAG. + +The following options are supported: + +`-d DIR' +`--dir=DIR' + Set the stow directory to DIR. Defaults to the value of the + environment variable `STOW_DIR' if set, or the current directory + otherwise. + +`-t DIR' +`--target=DIR' + Set the target directory to DIR instead of the parent of the stow + directory. Defaults to the parent of the stow directory, so it is + typical to execute `stow' from the directory `/usr/local/stow'. + +`--ignore=REGEXP' + This (repeatable) option lets you suppress acting on files that + match the given perl regular expression. For example, using the + options + + --ignore='*.orig' --ignore='*.dist' + + will cause stow to ignore files ending in `.orig' or `.dist'. + + Note that the regular expression is anchored to the end of the + filename, because this is what you will want to do most of the + time. + + Also note that by default Stow automatically ignores a "sensible" + built-in list of files and directories such as `CVS', editor + backup files, and so on. *Note Ignore Lists::, for more details. + +`--defer=REGEXP' + This (repeatable) option avoids stowing a file matching the given + regular expression, if that file is already stowed by another + package. This is effectively the opposite of `--override'. + + (N.B. the name `--defer' was chosen in the sense that the package + currently being stowed is treated with lower precedence than any + already installed package, not in the sense that the operation is + being postponed to be run at a later point in time; do not confuse + this nomenclature with the wording used in *note Deferred + Operation::.) + + For example, the following options + + --defer=man --defer=info + + will cause stow to skip over pre-existing man and info pages. + + Equivalently, you could use `--defer='man|info'' since the + argument is just a Perl regex. + + Note that the regular expression is anchored to the beginning of + the path relative to the target directory, because this is what + you will want to do most of the time. + +`--override=REGEXP' + This (repeatable) option forces any file matching the regular + expression to be stowed, even if the file is already stowed to + another package. For example, the following options + + --override=man --override=info + + will permit stow to overwrite links that point to pre-existing man + and info pages that are owned by stow and would otherwise cause a + conflict. + + The regular expression is anchored to the beginning of the path + relative to the target directory, because this is what you will + want to do most of the time. + +`--no-folding' + This disables any further *note tree folding:: or *note tree + refolding::. If a new subdirectory is encountered whilst stowing + a new package, the subdirectory is created within the target, and + its contents are symlinked, rather than just creating a symlink + for the directory. If removal of symlinks whilst unstowing a + package causes a subtree to be foldable (i.e. only containing + symlinks to a single package), that subtree will not be removed + and replaced with a symlink. + +`--adopt' + *Warning!* This behaviour is specifically intended to alter the + contents of your stow directory. If you do not want that, this + option is not for you. + + When stowing, if a target is encountered which already exists but + is a plain file (and hence not owned by any existing stow + package), then normally Stow will register this as a conflict and + refuse to proceed. This option changes that behaviour so that the + file is moved to the same relative place within the package's + installation image within the stow directory, and then stowing + proceeds as before. So effectively, the file becomes adopted by + the stow package, without its contents changing. + + This is particularly useful when the stow package is under the + control of a version control system, because it allows files in + the target tree, with potentially different contents to the + equivalent versions in the stow package's installation image, to + be adopted into the package, then compared by running something + like `git diff ...' inside the stow package, and finally either + kept (e.g. via `git commit ...') or discarded (`git checkout HEAD + ...'). + +`-n' +`--no' +`--simulate' + Do not perform any operations that modify the file system; in + combination with `-v' can be used to merely show what would happen. + +`-v' +`--verbose[=N]' + Send verbose output to standard error describing what Stow is + doing. Verbosity levels are 0, 1, 2, and 3; 0 is the default. + Using `-v' or `--verbose' increases the verbosity by one; using + `--verbose=N' sets it to N. + +`-p' +`--compat' + Scan the whole target tree when unstowing. By default, only + directories specified in the "installation image" are scanned + during an unstow operation. Scanning the whole tree can be + prohibitive if your target tree is very large. This option + restores the legacy behaviour; however, the `--badlinks' option to + the `chkstow' utility may be a better way of ensuring that your + installation does not have any dangling symlinks (*note Target + Maintenance::). + +`-V' +`--version' + Show Stow version number, and exit. + +`-h' +`--help' + Show Stow command syntax, and exit. + + The following ACTION FLAGS are supported: + +`-D' +`--delete' + Delete (unstow) the package name(s) that follow this option from + the "target directory". This option may be repeated any number of + times. + +`-R' +`--restow' + Restow (first unstow, then stow again) the package names that + follow this option. This is useful for pruning obsolete symlinks + from the target tree after updating the software in a package. + This option may be repeated any number of times. + +`-S' + +`--stow' + explictly stow the package name(s) that follow this option. May be + omitted if you are not using the `-D' or `-R' options in the same + invocation. *Note Mixing Operations::, for details of when you + might like to use this feature. This option may be repeated any + number of times. + + +File: stow.info, Node: Ignore Lists, Next: Installing Packages, Prev: Invoking Stow, Up: Top + +4 Ignore Lists +************** + +* Menu: + +* Motivation For Ignore Lists:: +* Types And Syntax Of Ignore Lists:: +* Justification For Yet Another Set Of Ignore Files:: + + +File: stow.info, Node: Motivation For Ignore Lists, Next: Types And Syntax Of Ignore Lists, Prev: Ignore Lists, Up: Ignore Lists + +4.1 Motivation For Ignore Lists +=============================== + +In many situations, there will exist files under the package +directories which it would be undesirable to stow into the target +directory. For example, files related version control such as +`.gitignore', `CVS', `*,v' (RCS files) should typically not have +symlinks from the target tree pointing to them. Also there may be +files or directories relating to the build of the package which are not +needed at run-time. + + In these cases, it can be rather cumbersome to specify a `--ignore' +parameter for each file or directory to be ignored. This could be +worked around by ensuring the existence of `~/.stowrc' containing +multiple `--ignore' lines, or if a different set of files/directories +should be ignored depending on which stow package is involved, a +`.stowrc' file for each stow package, but this would require the user +to ensure that they were in the correct directory before invoking stow, +which would be tedious and error-prone. Furthermore, since Stow shifts +parameters from `.stowrc' onto ARGV at run-time, it could clutter up +the process table with excessively long parameter lists, or even worse, +exceed the operating system's limit for process arguments. + + Therefore in addition to `--ignore' parameters, Stow provides a way +to specify lists of files and directories to ignore. + + +File: stow.info, Node: Types And Syntax Of Ignore Lists, Next: Justification For Yet Another Set Of Ignore Files, Prev: Motivation For Ignore Lists, Up: Ignore Lists + +4.2 Types And Syntax Of Ignore Lists +==================================== + +If you put Perl regular expressions, one per line, in a +`.stow-local-ignore' file within any top level package directory, in +which case any file or directory within that package matching any of +these regular expressions will be ignored. In the absence of this +package-specific ignore list, Stow will instead use the contents of +`~/.stow-global-ignore', if it exists. If neither the package-local or +global ignore list exist, Stow will use its own built-in default ignore +list, which serves as a useful example of the format of these ignore +list files: + + # Comments and blank lines are allowed. + + RCS + .+,v + + CVS + \.\#.+ # CVS conflict files / emacs lock files + \.cvsignore + + \.svn + _darcs + \.hg + + \.git + \.gitignore + + .+~ # emacs backup files + \#.*\# # emacs autosave files + + ^/README.* + ^/LICENSE.* + ^/COPYING + + Stow first iterates through the chosen ignore list (built-in, global, +or package-local) as per above, stripping out comments (if you want to +include the `#' symbol in a regular expression, escape it with a +blackslash) and blank lines, placing each regular expressions into one +of two sets depending on whether it contains the `/' forward slash +symbol. + + Then in order to determine whether a file or directory should be +ignored: + + 1. Stow calculates its path relative to the top-level package + directory, prefixing that with `/'. If any of the regular + expressions containing a `/' _exactly_(1) match a subpath(2) of + this relative path, then the file or directory will be ignored. + + 2. If none of the regular expressions containing a `/' match in the + manner described above, Stow checks whether the _basename_(3) of + the file or directory matches _exactly_ against the remaining + regular expressions which do not contain a `/', and if so, ignores + the file or directory. + + 3. Otherwise, the file or directory is not ignored. + + For example, if a file `bazqux' is in the `foo/bar' subdirectory of +the package directory, Stow would use `/foo/bar/bazqux' as the text for +matching against regular expressions which contain `/', and `bazqux' as +the text for matching against regular expressions which don't contain +`/'. Then regular expressions `bazqux', `baz.*', `.*qux', `bar/.*x', +and `^/foo/.*qux' would all match (causing the file to be ignored), +whereas `bar', `baz', `qux', and `o/bar/b' would not (although `bar' +would cause its parent directory to be ignored and prevent Stow from +recursing into that anyway, in which case the file `bazqux' would not +even be considered for stowing). + + As a special exception to the above algorithm, any +`.stow-local-ignore' present in the top-level package directory is +_always_ ignored, regardless of the contents of any ignore list, +because this file serves no purpose outside the stow directory. + + ---------- Footnotes ---------- + + (1) Exact matching means the regular expression is anchored at the +beginning and end, in contrast to unanchored regular expressions which +will match a substring. + + (2) In this context, "subpath" means a contiguous subset of path +segments; e.g for the relative path `one/two/three', there are six +valid subpaths: `one', `two', `three', `one/two', `two/three', +`one/two/three'. + + (3) The "basename" is the name of the file or directory itself, +excluding any directory path prefix - as returned by the `basename' +command. + + +File: stow.info, Node: Justification For Yet Another Set Of Ignore Files, Prev: Types And Syntax Of Ignore Lists, Up: Ignore Lists + +4.3 Justification For Yet Another Set Of Ignore Files +===================================================== + +The reader may note that this format is very similar to existing ignore +list file formats, such as those for `cvs', `git', `rsync' etc., and +wonder if another set of ignore lists is justified. However there are +good reasons why Stow does not simply check for the presence of say, +`.cvsignore', and use that if it exists. Firstly, there is no +guarantee that a stow package would contain any version control +meta-data, or permit introducing this if it didn't already exist. + + Secondly even if it did, version control system ignore lists +generally reflect _build-time_ ignores rather than _install-time_, and +there may be some intermediate or temporary files on those ignore lists +generated during development or at build-time which it would be +inappropriate to stow, even though many files generated at build-time +(binaries, libraries, documentation etc.) certainly do need to be +stowed. Similarly, if a file is _not_ in the version control system's +ignore list, there is no way of knowing whether the file is intended +for end use, let alone whether the version control system is tracking +it or not. + + Therefore it seems clear that ignore lists provided by version +control systems do not provide sufficient information for Stow to +determine which files and directories to stow, and so it makes sense +for Stow to support independent ignore lists. + + +File: stow.info, Node: Installing Packages, Next: Deleting Packages, Prev: Ignore Lists, Up: Top + +5 Installing Packages +********************* + +The default action of Stow is to install a package. This means creating +symlinks in the target tree that point into the package tree. Stow +attempts to do this with as few symlinks as possible; in other words, if +Stow can create a single symlink that points to an entire subtree within +the package tree, it will choose to do that rather than create a +directory in the target tree and populate it with symlinks. + +5.1 Tree folding +================ + +For example, suppose that no packages have yet been installed in +`/usr/local'; it's completely empty (except for the `stow' +subdirectory, of course). Now suppose the Perl package is installed. +Recall that it includes the following directories in its installation +image: `bin'; `info'; `lib/perl'; `man/man1'. Rather than creating +the directory `/usr/local/bin' and populating it with symlinks to +`../stow/perl/bin/perl' and `../stow/perl/bin/a2p' (and so on), Stow +will create a single symlink, `/usr/local/bin', which points to +`stow/perl/bin'. In this way, it still works to refer to +`/usr/local/bin/perl' and `/usr/local/bin/a2p', and fewer symlinks have +been created. This is called "tree folding", since an entire subtree +is "folded" into a single symlink. + + To complete this example, Stow will also create the symlink +`/usr/local/info' pointing to `stow/perl/info'; the symlink +`/usr/local/lib' pointing to `stow/perl/lib'; and the symlink +`/usr/local/man' pointing to `stow/perl/man'. + + Now suppose that instead of installing the Perl package into an empty +target tree, the target tree is not empty to begin with. Instead, it +contains several files and directories installed under a different +system-administration philosophy. In particular, `/usr/local/bin' +already exists and is a directory, as are `/usr/local/lib' and +`/usr/local/man/man1'. In this case, Stow will descend into +`/usr/local/bin' and create symlinks to `../stow/perl/bin/perl' and +`../stow/perl/bin/a2p' (etc.), and it will descend into +`/usr/local/lib' and create the tree-folding symlink `perl' pointing to +`../stow/perl/lib/perl', and so on. As a rule, Stow only descends as +far as necessary into the target tree when it can create a tree-folding +symlink. However, this behaviour can be changed via the `--no-folding' +option; *note Invoking Stow::. + +5.2 Tree unfolding +================== + +The time often comes when a tree-folding symlink has to be undone +because another package uses one or more of the folded subdirectories in +its installation image. This operation is called "splitting open" or +"unfolding" a folded tree. It involves removing the original symlink +from the target tree, creating a true directory in its place, and then +populating the new directory with symlinks to the newly-installed +package _and_ to the old package that used the old symlink. For +example, suppose that after installing Perl into an empty `/usr/local', +we wish to install Emacs. Emacs's installation image includes a `bin' +directory containing the `emacs' and `etags' executables, among others. +Stow must make these files appear to be installed in `/usr/local/bin', +but presently `/usr/local/bin' is a symlink to `stow/perl/bin'. Stow +therefore takes the following steps: the symlink `/usr/local/bin' is +deleted; the directory `/usr/local/bin' is created; links are made from +`/usr/local/bin' to `../stow/emacs/bin/emacs' and +`../stow/emacs/bin/etags'; and links are made from `/usr/local/bin' to +`../stow/perl/bin/perl' and `../stow/perl/bin/a2p'. + +5.3 Ownership +============= + +When splitting open a folded tree, Stow makes sure that the symlink it +is about to remove points inside a valid package in the current stow +directory. _Stow will never delete anything that it doesn't own_. +Stow "owns" everything living in the target tree that points into a +package in the stow directory. Anything Stow owns, it can recompute if +lost: symlinks that point into a package in the stow directory, or +directories that only contain symlinks that stow "owns". Note that by +this definition, Stow doesn't "own" anything _in_ the stow directory or +in any of the packages. + +5.4 Conflicts during installation +================================= + +If Stow needs to create a directory or a symlink in the target tree and +it cannot because that name is already in use and is not owned by Stow, +then a "conflict" has arisen. *Note Conflicts::. + + +File: stow.info, Node: Deleting Packages, Next: Conflicts, Prev: Installing Packages, Up: Top + +6 Deleting Packages +******************* + +When the `-D' option is given, the action of Stow is to delete a +package from the target tree. Note that Stow will not delete anything +it doesn't "own". Deleting a package does _not_ mean removing it from +the stow directory or discarding the package tree. + + To delete a package, Stow recursively scans the target tree, +skipping over any directory that is not included in the installation +image.(1) For example, if the target directory is `/usr/local' and the +installation image for the package being deleted has only a `bin' +directory and a `man' directory at the top level, then we only scan +`/usr/local/bin' and `/usr/local/bin/man', and not `/usr/local/lib' or +`/usr/local/share', or for that matter `/usr/local/stow'. Any symlink +it finds that points into the package being deleted is removed. Any +directory that contained only symlinks to the package being deleted is +removed. + +6.1 Refolding "foldable" trees. +=============================== + +After removing symlinks and empty subdirectories, any directory that +contains only symlinks to a single other package is considered to be a +previously "folded" tree that was "split open." Stow will refold the +tree by removing the symlinks to the surviving package, removing the +directory, then linking the directory back to the surviving package. +However, this behaviour can be prevented via the `--no-folding' option; +*note Invoking Stow::. + + ---------- Footnotes ---------- + + (1) This approach was introduced in version 2 of GNU Stow. +Previously, the whole target tree was scanned and stow directories were +explicitly omitted. This became problematic when dealing with very +large installations. The only situation where this is useful is if you +accidentally delete a directory in the package tree, leaving you with a +whole bunch of dangling links. Note that you can enable the old +approach with the `-p' option. Alternatively, you can use the +`--badlinks' option get stow to search for dangling links in your +target tree and remove the offenders manually. + + +File: stow.info, Node: Conflicts, Next: Mixing Operations, Prev: Deleting Packages, Up: Top + +7 Conflicts +*********** + +If, during installation, a file or symlink exists in the target tree and +has the same name as something Stow needs to create, and if the +existing name is not a folded tree that can be split open, then a +"conflict" has arisen. A conflict also occurs if a directory exists +where Stow needs to place a symlink to a non-directory. On the other +hand, if the existing name is merely a symlink that already points +where Stow needs it to, then no conflict has occurred. (Thus it is +harmless to install a package that has already been installed.) + + For complex packages, scanning the stow and target trees in tandem, +and deciding whether to make directories or links, split-open or fold +directories, can actually take a long time (a number of seconds). +Moreover, an accurate analysis of potential conflicts requires us to +take into account all of these operations. + +7.1 Deferred Operation +====================== + +Since version 2.0, Stow now adopts a two-phase algorithm, first +scanning for any potential conflicts before any stowing or unstowing +operations are performed. If any conflicts are found, they are +displayed and then Stow terminates without making any modifications to +the filesystem. This means that there is much less risk of a package +being partially stowed or unstowed due to conflicts. + + Prior to version 2.0, if a conflict was discovered, the stow or +unstow operation could be aborted mid-flow, leaving the target tree in +an inconsistent state. + + +File: stow.info, Node: Mixing Operations, Next: Multiple Stow Directories, Prev: Conflicts, Up: Top + +8 Mixing Operations +******************* + +Since version 2.0, multiple distinct actions can be specified in a +single invocation of GNU Stow. For example, to update an installation +of Emacs from version 21.3 to 21.4a you can now do the following: + + stow -D emacs-21.3 -S emacs-21.4a + +which will replace emacs-21.3 with emacs-21.4a using a single +invocation. + + This is much faster and cleaner than performing two separate +invocations of stow, because redundant folding/unfolding operations can +be factored out. In addition, all the operations are calculated and +merged before being executed (*note Deferred Operation::), so the +amount of of time in which GNU Emacs is unavailable is minimised. + + You can mix and match any number of actions, for example, + + stow -S pkg1 pkg2 -D pkg3 pkg4 -S pkg5 -R pkg6 + +will unstow pkg3, pkg4 and pkg6, then stow pkg1, pkg2, pkg5 and pkg6. + + +File: stow.info, Node: Multiple Stow Directories, Next: Target Maintenance, Prev: Mixing Operations, Up: Top + +9 Multiple Stow Directories +*************************** + +If there are two or more system administrators who wish to maintain +software separately, or if there is any other reason to want two or more +stow directories, it can be done by creating a file named `.stow' in +each stow directory. The presence of `/usr/local/foo/.stow' informs +Stow that, though `foo' is not the current stow directory, even if it +is a subdirectory of the target directory, nevertheless it is _a_ stow +directory and as such Stow doesn't "own" anything in it (*note +Installing Packages::). This will protect the contents of `foo' from a +`stow -D', for instance. + + When multiple stow directories share a target tree, if a tree-folding +symlink is encountered and needs to be split open during an +installation, as long as the top-level stow directory into which the +existing symlink points contains `.stow', Stow knows how to split open +the tree in the correct manner. + + +File: stow.info, Node: Target Maintenance, Next: Resource Files, Prev: Multiple Stow Directories, Up: Top + +10 Target Maintenance +********************* + +From time to time you will need to clean up your target tree. Since +version 2, Stow provides a new utility `chkstow' to help with this. It +includes three operational modes which performs checks that would +generally be too expensive to be performed during normal stow execution. + + The syntax of the `chkstow' command is: + + chkstow [OPTIONS] + +The following options are supported: + +`-t DIR' +`--target=DIR' + Set the target directory to DIR instead of the parent of the stow + directory. Defaults to the parent of the stow directory, so it is + typical to execute `stow' from the directory `/usr/local/stow'. + +`-b' +`--badlinks' + Checks target directory for bogus symbolic links. That is, links + that point to non-existent files. + +`-a' +`--aliens' + Checks for files in the target directory that are not symbolic + links. The target directory should be managed by stow alone, + except for directories that contain a `.stow' file. + +`-l' +`--list' + Will display the target package for every symbolic link in the + stow target directory. + + + +File: stow.info, Node: Resource Files, Next: Compile-time vs Install-time, Prev: Target Maintenance, Up: Top + +11 Resource Files +***************** + +Default command line options may be set in `.stowrc' (current +directory) or `~/.stowrc' (home directory). These are parsed in that +order, and effectively prepended to you command line. This feature can +be used for some interesting effects. + + For example, suppose your site uses more than one stow directory, +perhaps in order to share around responsibilities with a number of +systems administrators. One of the administrators might have the +following in their `~/.stowrc' file: + + --dir=/usr/local/stow2 + --target=/usr/local + --ignore='~' + --ignore='^CVS' + + so that the `stow' command will default to operating on the +`/usr/local/stow2' directory, with `/usr/local' as the target, and +ignoring vi backup files and CVS directories. + + If you had a stow directory `/usr/local/stow/perl-extras' that was +only used for Perl modules, then you might place the following in +`/usr/local/stow/perl-extras/.stowrc': + + --dir=/usr/local/stow/perl-extras + --target=/usr/local + --override=bin + --override=man + --ignore='perllocal\.pod' + --ignore='\.packlist' + --ignore='\.bs' + + so that when you are in the `/usr/local/stow/perl-extras' directory, +`stow' will regard any subdirectories as stow packages, with +`/usr/local' as the target (rather than the immediate parent directory +`/usr/local/stow'), overriding any pre-existing links to bin files or +man pages, and ignoring some cruft that gets installed by default. + + +File: stow.info, Node: Compile-time vs Install-time, Next: Bootstrapping, Prev: Resource Files, Up: Top + +12 Compile-time vs Install-time +******************************* + +Software whose installation is managed with Stow needs to be installed +in one place (the package directory, e.g. `/usr/local/stow/perl') but +needs to appear to run in another place (the target tree, e.g., +`/usr/local'). Why is this important? What's wrong with Perl, for +instance, looking for its files in `/usr/local/stow/perl' instead of in +`/usr/local'? + + The answer is that there may be another package, e.g., +`/usr/local/stow/perl-extras', stowed under `/usr/local'. If Perl is +configured to find its files in `/usr/local/stow/perl', it will never +find the extra files in the `perl-extras' package, even though they're +intended to be found by Perl. On the other hand, if Perl looks for its +files in `/usr/local', then it will find the intermingled Perl and +`perl-extras' files. + + This means that when you compile a package, you must tell it the +location of the run-time, or target tree; but when you install it, you +must place it in the stow tree. + +12.1 Advice on changing compilation and installation parameters +=============================================================== + +Some software packages allow you to specify, at compile-time, separate +locations for installation and for run-time. Perl is one such package; +see *note Perl and Perl 5 Modules::. Others allow you to compile the +package, then give a different destination in the `make install' step +without causing the binaries or other files to get rebuilt. Most GNU +software falls into this category; Emacs is a notable exception. *Note +GNU Emacs::, and *note Other FSF Software::. + + Still other software packages cannot abide the idea of separate +installation and run-time locations at all. If you try to `make +install prefix=/usr/local/stow/FOO', then first the whole package will +be recompiled to hardwire the `/usr/local/stow/FOO' path. With these +packages, it is best to compile normally, then run `make -n install', +which should report all the steps needed to install the just-built +software. Place this output into a file, edit the commands in the file +to remove recompilation steps and to reflect the Stow-based +installation location, and execute the edited file as a shell script in +place of `make install'. Be sure to execute the script using the same +shell that `make install' would have used. + + (If you use GNU Make and a shell [such as GNU bash] that understands +`pushd' and `popd', you can do the following: + + 1. Replace all lines matching `make[N]: Entering directory DIR' with + `pushd DIR'. + + 2. Replace all lines matching `make[N]: Leaving directory DIR' with + `popd'. + + 3. Delete all lines matching `make[N]: Nothing to be done for RULE'. + + Then find other lines in the output containing `cd' or `make' +commands and rewrite or delete them. In particular, you should be able +to delete sections of the script that resemble this: + + for i in DIR_1 DIR_2 ...; do \ + (cd $i; make ARGS ...) \ + done + +Note, that's "should be able to," not "can." Be sure to modulate these +guidelines with plenty of your own intelligence. + + The details of stowing some specific packages are described in the +following sections. + +* Menu: + +* GNU Emacs:: +* Other FSF Software:: +* Cygnus Software:: +* Perl and Perl 5 Modules:: + + +File: stow.info, Node: GNU Emacs, Next: Other FSF Software, Prev: Compile-time vs Install-time, Up: Compile-time vs Install-time + +12.2 GNU Emacs +============== + +Although the Free Software Foundation has many enlightened practices +regarding Makefiles and software installation (see *note Other FSF +Software::), Emacs, its flagship program, doesn't quite follow the +rules. In particular, most GNU software allows you to write: + + make + make install prefix=/usr/local/stow/PACKAGE + +If you try this with Emacs, then the new value for PREFIX in the `make +install' step will cause some files to get recompiled with the new +value of PREFIX wired into them. In Emacs 19.23 and later,(1) the way +to work around this problem is: + + make + make install-arch-dep install-arch-indep prefix=/usr/local/stow/emacs + + In 19.22 and some prior versions of Emacs, the workaround was: + + make + make do-install prefix=/usr/local/stow/emacs + + ---------- Footnotes ---------- + + (1) As I write this, the current version of Emacs is 19.31. + + +File: stow.info, Node: Other FSF Software, Next: Cygnus Software, Prev: GNU Emacs, Up: Compile-time vs Install-time + +12.3 Other FSF Software +======================= + +The Free Software Foundation, the organization behind the GNU project, +has been unifying the build procedure for its tools for some time. +Thanks to its tools `autoconf' and `automake', most packages now +respond well to these simple steps, with no other intervention +necessary: + + ./configure OPTIONS + make + make install prefix=/usr/local/stow/PACKAGE + + Hopefully, these tools can evolve to be aware of Stow-managed +packages, such that providing an option to `configure' can allow `make' +and `make install' steps to work correctly without needing to "fool" +the build process. + + +File: stow.info, Node: Cygnus Software, Next: Perl and Perl 5 Modules, Prev: Other FSF Software, Up: Compile-time vs Install-time + +12.4 Cygnus Software +==================== + +Cygnus is a commercial supplier and supporter of GNU software. It has +also written several of its own packages, released under the terms of +the GNU General Public License; and it has taken over the maintenance of +other packages. Among the packages released by Cygnus are `gdb', +`gnats', and `dejagnu'. + + Cygnus packages have the peculiarity that each one unpacks into a +directory tree with a generic top-level Makefile, which is set up to +compile _all_ of Cygnus' packages, any number of which may reside under +the top-level directory. In other words, even if you're only building +`gnats', the top-level Makefile will look for, and try to build, `gdb' +and `dejagnu' subdirectories, among many others. + + The result is that if you try `make -n install +prefix=/usr/local/stow/PACKAGE' at the top level of a Cygnus package, +you'll get a bewildering amount of output. It will then be very +difficult to visually scan the output to see whether the install will +proceed correctly. Unfortunately, it's not always clear how to invoke +an install from the subdirectory of interest. + + In cases like this, the best approach is to run your `make install +prefix=...', but be ready to interrupt it if you detect that it is +recompiling files. Usually it will work just fine; otherwise, install +manually. + + +File: stow.info, Node: Perl and Perl 5 Modules, Prev: Cygnus Software, Up: Compile-time vs Install-time + +12.5 Perl and Perl 5 Modules +============================ + +Perl 4.036 allows you to specify different locations for installation +and for run-time. It is the only widely-used package in this author's +experience that allows this, though hopefully more packages will adopt +this model. + + Unfortunately, the authors of Perl believed that only AFS sites need +this ability. The configuration instructions for Perl 4 misleadingly +state that some occult means are used under AFS to transport files from +their installation tree to their run-time tree. In fact, that confusion +arises from the fact that Depot, Stow's predecessor, originated at +Carnegie Mellon University, which was also the birthplace of AFS. CMU's +need to separate install-time and run-time trees stemmed from its use of +Depot, not from AFS. + + The result of this confusion is that Perl 5's configuration script +doesn't even offer the option of separating install-time and run-time +trees _unless_ you're running AFS. Fortunately, after you've entered +all the configuration settings, Perl's setup script gives you the +opportunity to edit those settings in a file called `config.sh'. When +prompted, you should edit this file and replace occurrences of + + inst.../usr/local... + +with + + inst.../usr/local/stow/perl... + +You can do this with the following Unix command: + + sed 's,^\(inst.*/usr/local\),\1/stow/perl,' config.sh > config.sh.new + mv config.sh.new config.sh + + Hopefully, the Perl authors will correct this deficiency in Perl 5's +configuration mechanism. + + Perl 5 modules--i.e., extensions to Perl 5--generally conform to a +set of standards for building and installing them. The standard says +that the package comes with a top-level `Makefile.PL', which is a Perl +script. When it runs, it generates a `Makefile'. + + If you followed the instructions above for editing `config.sh' when +Perl was built, then when you create a `Makefile' from a `Makefile.PL', +it will contain separate locations for run-time (`/usr/local') and +install-time (`/usr/local/stow/perl'). Thus you can do + + perl Makefile.PL + make + make install + +and the files will be installed into `/usr/local/stow/perl'. However, +you might prefer each Perl module to be stowed separately. In that +case, you must edit the resulting Makefile, replacing +`/usr/local/stow/perl' with `/usr/local/stow/MODULE'. The best way to +do this is: + + perl Makefile.PL + find . -name Makefile -print | \ + xargs perl -pi~ -e 's,^(INST.*/stow)/perl,$1/MODULE,;' + make + make install + +(The use of `find' and `xargs' ensures that all Makefiles in the +module's source tree, even those in subdirectories, get edited.) A +good convention to follow is to name the stow directory for a Perl +MODULE `cpan.MODULE', where `cpan' stands for Comprehensive Perl +Archive Network, a collection of FTP sites that is the source of most +Perl 5 extensions. This way, it's easy to tell at a glance which of +the subdirectories of `/usr/local/stow' are Perl 5 extensions. + + When you stow separate Perl 5 modules separately, you are likely to +encounter conflicts (*note Conflicts::) with files named `.exists' and +`perllocal.pod'. One way to work around this is to remove those files +before stowing the module. If you use the `cpan.MODULE' naming +convention, you can simply do this: + + cd /usr/local/stow + find cpan.* \( -name .exists -o -name perllocal.pod \) -print | \ + xargs rm + + +File: stow.info, Node: Bootstrapping, Next: Reporting Bugs, Prev: Compile-time vs Install-time, Up: Top + +13 Bootstrapping +**************** + +Suppose you have a stow directory all set up and ready to go: +`/usr/local/stow/perl' contains the Perl installation, +`/usr/local/stow/stow' contains Stow itself, and perhaps you have other +packages waiting to be stowed. You'd like to be able to do this: + + cd /usr/local/stow + stow -vv * + +but `stow' is not yet in your `PATH'. Nor can you do this: + + cd /usr/local/stow + stow/bin/stow -vv * + +because the `#!' line at the beginning of `stow' tries to locate Perl +(usually in `/usr/local/bin/perl'), and that won't be found. The +solution you must use is: + + cd /usr/local/stow + perl/bin/perl stow/bin/stow -vv * + + +File: stow.info, Node: Reporting Bugs, Next: Known Bugs, Prev: Bootstrapping, Up: Top + +14 Reporting Bugs +***************** + +Please send bug reports to the current maintainers by electronic mail. +The address to use is `'. Please include: + + * the version number of Stow (`stow --version'); + + * the version number of Perl (`perl -v'); + + * the system information, which can often be obtained with `uname + -a'; + + * a description of the bug; + + * the precise command you gave; + + * the output from the command (preferably verbose output, obtained by + adding `--verbose=3' to the Stow command line). + + If you are really keen, consider developing a minimal test case and +creating a new test. See the `t/' directory in the source for lots of +examples. + + Before reporting a bug, please read the manual carefully, especially +*note Known Bugs::, to see whether you're encountering something that +doesn't need reporting. (*note Conflicts::). + + +File: stow.info, Node: Known Bugs, Next: GNU General Public License, Prev: Reporting Bugs, Up: Top + +15 Known Bugs +************* + +There are no known bugs in Stow version 2.2.2! If you think you have +found one, please *note Reporting Bugs::. + + +File: stow.info, Node: GNU General Public License, Next: Index, Prev: Known Bugs, Up: Top + +GNU General Public License +************************** + + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +Preamble +======== + +The licenses for most software are designed to take away your freedom +to share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it in +new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, +and (2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + 0. This License applies to any program or other work which contains a + notice placed by the copyright holder saying it may be distributed + under the terms of this General Public License. The "Program", + below, refers to any such program or work, and a "work based on + the Program" means either the Program or any derivative work under + copyright law: that is to say, a work containing the Program or a + portion of it, either verbatim or with modifications and/or + translated into another language. (Hereinafter, translation is + included without limitation in the term "modification".) Each + licensee is addressed as "you". + + Activities other than copying, distribution and modification are + not covered by this License; they are outside its scope. The act + of running the Program is not restricted, and the output from the + Program is covered only if its contents constitute a work based on + the Program (independent of having been made by running the + Program). Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's + source code as you receive it, in any medium, provided that you + conspicuously and appropriately publish on each copy an appropriate + copyright notice and disclaimer of warranty; keep intact all the + notices that refer to this License and to the absence of any + warranty; and give any other recipients of the Program a copy of + this License along with the Program. + + You may charge a fee for the physical act of transferring a copy, + and you may at your option offer warranty protection in exchange + for a fee. + + 2. You may modify your copy or copies of the Program or any portion + of it, thus forming a work based on the Program, and copy and + distribute such modifications or work under the terms of Section 1 + above, provided that you also meet all of these conditions: + + a. You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b. You must cause any work that you distribute or publish, that + in whole or in part contains or is derived from the Program + or any part thereof, to be licensed as a whole at no charge + to all third parties under the terms of this License. + + c. If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display + an announcement including an appropriate copyright notice and + a notice that there is no warranty (or else, saying that you + provide a warranty) and that users may redistribute the + program under these conditions, and telling the user how to + view a copy of this License. (Exception: if the Program + itself is interactive but does not normally print such an + announcement, your work based on the Program is not required + to print an announcement.) + + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the + Program, and can be reasonably considered independent and separate + works in themselves, then this License, and its terms, do not + apply to those sections when you distribute them as separate + works. But when you distribute the same sections as part of a + whole which is a work based on the Program, the distribution of + the whole must be on the terms of this License, whose permissions + for other licensees extend to the entire whole, and thus to each + and every part regardless of who wrote it. + + Thus, it is not the intent of this section to claim rights or + contest your rights to work written entirely by you; rather, the + intent is to exercise the right to control the distribution of + derivative or collective works based on the Program. + + In addition, mere aggregation of another work not based on the + Program with the Program (or with a work based on the Program) on + a volume of a storage or distribution medium does not bring the + other work under the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, + under Section 2) in object code or executable form under the terms + of Sections 1 and 2 above provided that you also do one of the + following: + + a. Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Sections 1 and 2 above on a medium customarily used for + software interchange; or, + + b. Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a + medium customarily used for software interchange; or, + + c. Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with + such an offer, in accord with Subsection b above.) + + The source code for a work means the preferred form of the work for + making modifications to it. For an executable work, complete + source code means all the source code for all modules it contains, + plus any associated interface definition files, plus the scripts + used to control compilation and installation of the executable. + However, as a special exception, the source code distributed need + not include anything that is normally distributed (in either + source or binary form) with the major components (compiler, + kernel, and so on) of the operating system on which the executable + runs, unless that component itself accompanies the executable. + + If distribution of executable or object code is made by offering + access to copy from a designated place, then offering equivalent + access to copy the source code from the same place counts as + distribution of the source code, even though third parties are not + compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program + except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense or distribute the Program is + void, and will automatically terminate your rights under this + License. However, parties who have received copies, or rights, + from you under this License will not have their licenses + terminated so long as such parties remain in full compliance. + + 5. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify + or distribute the Program or its derivative works. These actions + are prohibited by law if you do not accept this License. + Therefore, by modifying or distributing the Program (or any work + based on the Program), you indicate your acceptance of this + License to do so, and all its terms and conditions for copying, + distributing or modifying the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the + Program), the recipient automatically receives a license from the + original licensor to copy, distribute or modify the Program + subject to these terms and conditions. You may not impose any + further restrictions on the recipients' exercise of the rights + granted herein. You are not responsible for enforcing compliance + by third parties to this License. + + 7. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent + issues), conditions are imposed on you (whether by court order, + agreement or otherwise) that contradict the conditions of this + License, they do not excuse you from the conditions of this + License. If you cannot distribute so as to satisfy simultaneously + your obligations under this License and any other pertinent + obligations, then as a consequence you may not distribute the + Program at all. For example, if a patent license would not permit + royalty-free redistribution of the Program by all those who + receive copies directly or indirectly through you, then the only + way you could satisfy both it and this License would be to refrain + entirely from distribution of the Program. + + If any portion of this section is held invalid or unenforceable + under any particular circumstance, the balance of the section is + intended to apply and the section as a whole is intended to apply + in other circumstances. + + It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of + any such claims; this section has the sole purpose of protecting + the integrity of the free software distribution system, which is + implemented by public license practices. Many people have made + generous contributions to the wide range of software distributed + through that system in reliance on consistent application of that + system; it is up to the author/donor to decide if he or she is + willing to distribute software through any other system and a + licensee cannot impose that choice. + + This section is intended to make thoroughly clear what is believed + to be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in + certain countries either by patents or by copyrighted interfaces, + the original copyright holder who places the Program under this + License may add an explicit geographical distribution limitation + excluding those countries, so that distribution is permitted only + in or among countries not thus excluded. In such case, this + License incorporates the limitation as if written in the body of + this License. + + 9. The Free Software Foundation may publish revised and/or new + versions of the General Public License from time to time. Such + new versions will be similar in spirit to the present version, but + may differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the + Program specifies a version number of this License which applies + to it and "any later version", you have the option of following + the terms and conditions either of that version or of any later + version published by the Free Software Foundation. If the Program + does not specify a version number of this License, you may choose + any version ever published by the Free Software Foundation. + + 10. If you wish to incorporate parts of the Program into other free + programs whose distribution conditions are different, write to the + author to ask for permission. For software which is copyrighted + by the Free Software Foundation, write to the Free Software + Foundation; we sometimes make exceptions for this. Our decision + will be guided by the two goals of preserving the free status of + all derivatives of our free software and of promoting the sharing + and reuse of software generally. + + NO WARRANTY + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE + LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT + NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE + QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE + PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY + SERVICING, REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY + MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE + LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, + INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR + INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF + DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU + OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY + OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS +How to Apply These Terms to Your New Programs +============================================= + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + ONE LINE TO GIVE THE PROGRAM'S NAME AND AN IDEA OF WHAT IT DOES. + Copyright (C) 19YY NAME OF AUTHOR + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Also add information on how to contact you by electronic and paper +mail. + + If the program is interactive, make it output a short notice like +this when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details + type `show w'. This is free software, and you are welcome + to redistribute it under certain conditions; type `show c' + for details. + + The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and `show +c'; they could even be mouse-clicks or menu items--whatever suits your +program. + + You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the program, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright + interest in the program `Gnomovision' + (which makes passes at compilers) written + by James Hacker. + + SIGNATURE OF TY COON, 1 April 1989 + Ty Coon, President of Vice + + This General Public License does not permit incorporating your +program into proprietary programs. If your program is a subroutine +library, you may consider it more useful to permit linking proprietary +applications with the library. If this is what you want to do, use the +GNU Library General Public License instead of this License. + + +File: stow.info, Node: Index, Prev: GNU General Public License, Up: Top + +Index +***** + +[index] +* Menu: + +* absolute symlink: Terminology. (line 43) +* adopting existing files: Invoking Stow. (line 97) +* configuration files: Resource Files. (line 6) +* conflicts <1>: Conflicts. (line 6) +* conflicts: Installing Packages. (line 85) +* deferred operation <1>: Mixing Operations. (line 15) +* deferred operation: Conflicts. (line 24) +* deletion: Deleting Packages. (line 6) +* directory folding: Installing Packages. (line 16) +* dry run: Invoking Stow. (line 120) +* folding trees: Installing Packages. (line 16) +* ignore lists <1>: Motivation For Ignore Lists. + (line 26) +* ignore lists: Ignore Lists. (line 6) +* ignoring files and directories: Ignore Lists. (line 6) +* installation: Installing Packages. (line 6) +* installation conflicts: Installing Packages. (line 85) +* installation image: Terminology. (line 23) +* maintenance: Target Maintenance. (line 6) +* mixing operations: Mixing Operations. (line 6) +* ownership: Installing Packages. (line 72) +* package: Terminology. (line 6) +* package directory: Terminology. (line 30) +* package name: Terminology. (line 30) +* refolding trees: Deleting Packages. (line 25) +* relative symlink: Terminology. (line 43) +* resource files: Resource Files. (line 6) +* simulated run: Invoking Stow. (line 120) +* splitting open folded trees: Installing Packages. (line 51) +* stow directory: Terminology. (line 16) +* symlink: Terminology. (line 43) +* target directory: Terminology. (line 11) +* tree folding: Installing Packages. (line 16) +* tree refolding: Deleting Packages. (line 25) +* tree unfolding: Installing Packages. (line 51) +* tree unsplitting: Installing Packages. (line 51) +* unfolding trees: Installing Packages. (line 51) +* verbosity levels: Invoking Stow. (line 126) + + + +Tag Table: +Node: Top1445 +Node: Introduction2967 +Ref: Introduction-Footnote-15130 +Node: Terminology5172 +Node: Invoking Stow7535 +Node: Ignore Lists14338 +Node: Motivation For Ignore Lists14602 +Node: Types And Syntax Of Ignore Lists16097 +Ref: Types And Syntax Of Ignore Lists-Footnote-119260 +Ref: Types And Syntax Of Ignore Lists-Footnote-219426 +Ref: Types And Syntax Of Ignore Lists-Footnote-319642 +Node: Justification For Yet Another Set Of Ignore Files19787 +Node: Installing Packages21385 +Ref: tree folding21947 +Ref: Tree unfolding23825 +Node: Deleting Packages25893 +Ref: tree refolding26925 +Ref: Deleting Packages-Footnote-127470 +Node: Conflicts28058 +Ref: Deferred Operation29044 +Node: Mixing Operations29645 +Node: Multiple Stow Directories30637 +Node: Target Maintenance31697 +Node: Resource Files32927 +Node: Compile-time vs Install-time34533 +Node: GNU Emacs37943 +Ref: GNU Emacs-Footnote-138928 +Node: Other FSF Software38992 +Node: Cygnus Software39753 +Node: Perl and Perl 5 Modules41232 +Node: Bootstrapping44787 +Node: Reporting Bugs45568 +Node: Known Bugs46547 +Node: GNU General Public License46795 +Node: Index65935 + +End Tag Table diff --git a/.local/share/man/man8/stow.8 b/.local/share/man/man8/stow.8 new file mode 100644 index 0000000..ff4542f --- /dev/null +++ b/.local/share/man/man8/stow.8 @@ -0,0 +1,508 @@ +.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is turned on, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{ +. if \nF \{ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "IO::FILE=IO(0X81D9F0) 1" +.TH IO::FILE=IO(0X81D9F0) 1 "2015-11-09" "perl v5.20.1" "User Contributed Perl Documentation" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +stow \- software package installation manager +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +stow [ options ] package ... +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +This manual page describes \s-1GNU\s0 Stow 2.2.2, a program for managing +the installation of software packages. This is not the definitive +documentation for stow; for that, see the info manual. +.PP +Stow is a tool for managing the installation of multiple software +packages in the same run-time directory tree. One historical +difficulty of this task has been the need to administer, upgrade, +install, and remove files in independent packages without confusing +them with other files sharing the same filesystem space. For instance, +it is common to install Perl and Emacs in \fI/usr/local\fR. When one +does so, one winds up (as of Perl 4.036 and Emacs 19.22) with the +following files in \fI/usr/local/man/man1\fR: \fIa2p.1\fR; \fIctags.1\fR; +\&\fIemacs.1\fR; \fIetags.1\fR; \fIh2ph.1\fR; \fIperl.1\fR; and \fIs2p.1\fR. Now +suppose it's time to uninstall Perl. Which man pages get removed? +Obviously \fIperl.1\fR is one of them, but it should not be the +administrator's responsibility to memorize the ownership of individual +files by separate packages. +.PP +The approach used by Stow is to install each package into its own +tree, then use symbolic links to make it appear as though the files +are installed in the common tree. Administration can be performed in +the package's private tree in isolation from clutter from other +packages. Stow can then be used to update the symbolic links. The +structure of each private tree should reflect the desired structure in +the common tree; i.e. (in the typical case) there should be a \fIbin\fR +directory containing executables, a \fIman/man1\fR directory containing +section 1 man pages, and so on. +.PP +Stow was inspired by Carnegie Mellon's Depot program, but is +substantially simpler and safer. Whereas Depot required database files +to keep things in sync, Stow stores no extra state between runs, so +there's no danger (as there was in Depot) of mangling directories when +file hierarchies don't match the database. Also unlike Depot, Stow +will never delete any files, directories, or links that appear in a +Stow directory (e.g., \fI/usr/local/stow/emacs\fR), so it's always +possible to rebuild the target tree (e.g., \fI/usr/local\fR). +.SH "TERMINOLOGY" +.IX Header "TERMINOLOGY" +A \*(L"package\*(R" is a related collection of files and directories that +you wish to administer as a unit \*(-- e.g., Perl or Emacs \*(-- and that +needs to be installed in a particular directory structure \*(-- e.g., +with \fIbin\fR, \fIlib\fR, and \fIman\fR subdirectories. +.PP +A \*(L"target directory\*(R" is the root of a tree in which one or more +packages wish to \fBappear\fR to be installed. A common, but by no means +the only such location is \fI/usr/local\fR. The examples in this manual +page will use \fI/usr/local\fR as the target directory. +.PP +A \*(L"stow directory\*(R" is the root of a tree containing separate +packages in private subtrees. When Stow runs, it uses the current +directory as the default stow directory. The examples in this manual +page will use \fI/usr/local/stow\fR as the stow directory, so that +individual packages will be, for example, \fI/usr/local/stow/perl\fR and +\&\fI/usr/local/stow/emacs\fR. +.PP +An \*(L"installation image\*(R" is the layout of files and directories +required by a package, relative to the target directory. Thus, the +installation image for Perl includes: a \fIbin\fR directory containing +\&\fIperl\fR and \fIa2p\fR (among others); an \fIinfo\fR directory containing +Texinfo documentation; a \fIlib/perl\fR directory containing Perl +libraries; and a \fIman/man1\fR directory containing man pages. +.PP +A \*(L"package directory\*(R" is the root of a tree containing the +installation image for a particular package. Each package directory +must reside in a stow directory \*(-- e.g., the package directory +\&\fI/usr/local/stow/perl\fR must reside in the stow directory +\&\fI/usr/local/stow\fR. The \*(L"name\*(R" of a package is the name of its +directory within the stow directory \*(-- e.g., \fIperl\fR. +.PP +Thus, the Perl executable might reside in +\&\fI/usr/local/stow/perl/bin/perl\fR, where \fI/usr/local\fR is the target +directory, \fI/usr/local/stow\fR is the stow directory, +\&\fI/usr/local/stow/perl\fR is the package directory, and \fIbin/perl\fR +within is part of the installation image. +.PP +A \*(L"symlink\*(R" is a symbolic link. A symlink can be \*(L"relative\*(R" or +\&\*(L"absolute\*(R". An absolute symlink names a full path; that is, one +starting from \fI/\fR. A relative symlink names a relative path; that +is, one not starting from \fI/\fR. The target of a relative symlink is +computed starting from the symlink's own directory. Stow only creates +relative symlinks. +.SH "OPTIONS" +.IX Header "OPTIONS" +The stow directory is assumed to be the value of the \f(CW\*(C`STOW_DIR\*(C'\fR +environment variable or if unset the current directory, and the target +directory is assumed to be the parent of the current directory (so it +is typical to execute \fIstow\fR from the directory \fI/usr/local/stow\fR). +Each \fIpackage\fR given on the command line is the name of a package in +the stow directory (e.g., \fIperl\fR). By default, they are installed +into the target directory (but they can be deleted instead using +\&\f(CW\*(C`\-D\*(C'\fR). +.IP "\-n" 4 +.IX Item "-n" +.PD 0 +.IP "\-\-no" 4 +.IX Item "--no" +.PD +Do not perform any operations that modify the filesystem; merely show +what would happen. +.IP "\-d \s-1DIR\s0" 4 +.IX Item "-d DIR" +.PD 0 +.IP "\-\-dir=DIR" 4 +.IX Item "--dir=DIR" +.PD +Set the stow directory to \f(CW\*(C`DIR\*(C'\fR instead of the current directory. +This also has the effect of making the default target directory be the +parent of \f(CW\*(C`DIR\*(C'\fR. +.IP "\-t \s-1DIR\s0" 4 +.IX Item "-t DIR" +.PD 0 +.IP "\-\-target=DIR" 4 +.IX Item "--target=DIR" +.PD +Set the target directory to \f(CW\*(C`DIR\*(C'\fR instead of the parent of the stow +directory. +.IP "\-v" 4 +.IX Item "-v" +.PD 0 +.IP "\-\-verbose[=N]" 4 +.IX Item "--verbose[=N]" +.PD +Send verbose output to standard error describing what Stow is +doing. Verbosity levels are 0, 1, 2, 3, and 4; 0 is the default. +Using \f(CW\*(C`\-v\*(C'\fR or \f(CW\*(C`\-\-verbose\*(C'\fR increases the verbosity by one; using +`\-\-verbose=N' sets it to N. +.IP "\-S" 4 +.IX Item "-S" +.PD 0 +.IP "\-\-stow" 4 +.IX Item "--stow" +.PD +Stow the packages that follow this option into the target directory. +This is the default action and so can be omitted if you are only +stowing packages rather than performing a mixture of +stow/delete/restow actions. +.IP "\-D" 4 +.IX Item "-D" +.PD 0 +.IP "\-\-delete" 4 +.IX Item "--delete" +.PD +Unstow the packages that follow this option from the target directory rather +than installing them. +.IP "\-R" 4 +.IX Item "-R" +.PD 0 +.IP "\-\-restow" 4 +.IX Item "--restow" +.PD +Restow packages (first unstow, then stow again). This is useful +for pruning obsolete symlinks from the target tree after updating +the software in a package. +.IP "\-\-adopt" 4 +.IX Item "--adopt" +\&\fBWarning!\fR This behaviour is specifically intended to alter the +contents of your stow directory. If you do not want that, this option +is not for you. +.Sp +When stowing, if a target is encountered which already exists but is a +plain file (and hence not owned by any existing stow package), then +normally Stow will register this as a conflict and refuse to proceed. +This option changes that behaviour so that the file is moved to the +same relative place within the package's installation image within the +stow directory, and then stowing proceeds as before. So effectively, +the file becomes adopted by the stow package, without its contents +changing. +.IP "\-\-no\-folding" 4 +.IX Item "--no-folding" +Disable folding of newly stowed directories when stowing, and +refolding of newly foldable directories when unstowing. +.IP "\-\-ignore=REGEX" 4 +.IX Item "--ignore=REGEX" +Ignore files ending in this Perl regex. +.IP "\-\-defer=REGEX" 4 +.IX Item "--defer=REGEX" +Don't stow files beginning with this Perl regex if the file is already +stowed to another package. +.IP "\-\-override=REGEX" 4 +.IX Item "--override=REGEX" +Force stowing files beginning with this Perl regex if the file is +already stowed to another package. +.IP "\-V" 4 +.IX Item "-V" +.PD 0 +.IP "\-\-version" 4 +.IX Item "--version" +.PD +Show Stow version number, and exit. +.IP "\-h" 4 +.IX Item "-h" +.PD 0 +.IP "\-\-help" 4 +.IX Item "--help" +.PD +Show Stow command syntax, and exit. +.SH "INSTALLING PACKAGES" +.IX Header "INSTALLING PACKAGES" +The default action of Stow is to install a package. This means +creating symlinks in the target tree that point into the package tree. +Stow attempts to do this with as few symlinks as possible; in other +words, if Stow can create a single symlink that points to an entire +subtree within the package tree, it will choose to do that rather than +create a directory in the target tree and populate it with symlinks. +.PP +For example, suppose that no packages have yet been installed in +\&\fI/usr/local\fR; it's completely empty (except for the \fIstow\fR +subdirectory, of course). Now suppose the Perl package is installed. +Recall that it includes the following directories in its installation +image: \fIbin\fR; \fIinfo\fR; \fIlib/perl\fR; \fIman/man1\fR. Rather than +creating the directory \fI/usr/local/bin\fR and populating it with +symlinks to \fI../stow/perl/bin/perl\fR and \fI../stow/perl/bin/a2p\fR (and +so on), Stow will create a single symlink, \fI/usr/local/bin\fR, which +points to \fIstow/perl/bin\fR. In this way, it still works to refer to +\&\fI/usr/local/bin/perl\fR and \fI/usr/local/bin/a2p\fR, and fewer symlinks +have been created. This is called \*(L"tree folding\*(R", since an entire +subtree is \*(L"folded\*(R" into a single symlink. +.PP +To complete this example, Stow will also create the symlink +\&\fI/usr/local/info\fR pointing to \fIstow/perl/info\fR; the symlink +\&\fI/usr/local/lib\fR pointing to \fIstow/perl/lib\fR; and the symlink +\&\fI/usr/local/man\fR pointing to \fIstow/perl/man\fR. +.PP +Now suppose that instead of installing the Perl package into an empty +target tree, the target tree is not empty to begin with. Instead, it +contains several files and directories installed under a different +system-administration philosophy. In particular, \fI/usr/local/bin\fR +already exists and is a directory, as are \fI/usr/local/lib\fR and +\&\fI/usr/local/man/man1\fR. In this case, Stow will descend into +\&\fI/usr/local/bin\fR and create symlinks to \fI../stow/perl/bin/perl\fR and +\&\fI../stow/perl/bin/a2p\fR (etc.), and it will descend into +\&\fI/usr/local/lib\fR and create the tree-folding symlink \fIperl\fR pointing +to \fI../stow/perl/lib/perl\fR, and so on. As a rule, Stow only descends +as far as necessary into the target tree when it can create a +tree-folding symlink. +.PP +The time often comes when a tree-folding symlink has to be undone +because another package uses one or more of the folded subdirectories +in its installation image. This operation is called \*(L"splitting open\*(R" +a folded tree. It involves removing the original symlink from the +target tree, creating a true directory in its place, and then +populating the new directory with symlinks to the newly-installed +package \fBand\fR to the old package that used the old symlink. For +example, suppose that after installing Perl into an empty +\&\fI/usr/local\fR, we wish to install Emacs. Emacs's installation image +includes a \fIbin\fR directory containing the \fIemacs\fR and \fIetags\fR +executables, among others. Stow must make these files appear to be +installed in \fI/usr/local/bin\fR, but presently \fI/usr/local/bin\fR is a +symlink to \fIstow/perl/bin\fR. Stow therefore takes the following +steps: the symlink \fI/usr/local/bin\fR is deleted; the directory +\&\fI/usr/local/bin\fR is created; links are made from \fI/usr/local/bin\fR to +\&\fI../stow/emacs/bin/emacs\fR and \fI../stow/emacs/bin/etags\fR; and links +are made from \fI/usr/local/bin\fR to \fI../stow/perl/bin/perl\fR and +\&\fI../stow/perl/bin/a2p\fR. +.PP +When splitting open a folded tree, Stow makes sure that the symlink +it is about to remove points inside a valid package in the current stow +directory. +.SS "Stow will never delete anything that it doesn't own." +.IX Subsection "Stow will never delete anything that it doesn't own." +Stow \*(L"owns\*(R" everything living in the target tree that points into a +package in the stow directory. Anything Stow owns, it can recompute if +lost. Note that by this definition, Stow doesn't \*(L"own\*(R" anything +\&\fBin\fR the stow directory or in any of the packages. +.PP +If Stow needs to create a directory or a symlink in the target tree +and it cannot because that name is already in use and is not owned by +Stow, then a conflict has arisen. See the \*(L"Conflicts\*(R" section in the +info manual. +.SH "DELETING PACKAGES" +.IX Header "DELETING PACKAGES" +When the \f(CW\*(C`\-D\*(C'\fR option is given, the action of Stow is to delete a +package from the target tree. Note that Stow will not delete anything +it doesn't \*(L"own\*(R". Deleting a package does \fBnot\fR mean removing it from +the stow directory or discarding the package tree. +.PP +To delete a package, Stow recursively scans the target tree, skipping +over the stow directory (since that is usually a subdirectory of the +target tree) and any other stow directories it encounters (see +\&\*(L"Multiple stow directories\*(R" in the info manual). Any symlink it +finds that points into the package being deleted is removed. Any +directory that contained only symlinks to the package being deleted is +removed. Any directory that, after removing symlinks and empty +subdirectories, contains only symlinks to a single other package, is +considered to be a previously \*(L"folded\*(R" tree that was \*(L"split open.\*(R" +Stow will re-fold the tree by removing the symlinks to the surviving +package, removing the directory, then linking the directory back to +the surviving package. +.SH "SEE ALSO" +.IX Header "SEE ALSO" +The full documentation for \fIstow\fR is maintained as a Texinfo manual. +If the \fIinfo\fR and \fIstow\fR programs are properly installed at your site, the command +.PP +.Vb 1 +\& info stow +.Ve +.PP +should give you access to the complete manual. +.SH "BUGS" +.IX Header "BUGS" +Please report bugs in Stow using the Debian bug tracking system. +.PP +Currently known bugs include: +.IP "\(bu" 4 +The empty-directory problem. +.Sp +If package \fIfoo\fR includes an empty directory \*(-- say, \fIfoo/bar\fR \*(-- +then if no other package has a \fIbar\fR subdirectory, everything's fine. +If another stowed package \fIquux\fR, has a \fIbar\fR subdirectory, then +when stowing, \fItargetdir/bar\fR will be \*(L"split open\*(R" and the contents +of \fIquux/bar\fR will be individually stowed. So far, so good. But when +unstowing \fIquux\fR, \fItargetdir/bar\fR will be removed, even though +\&\fIfoo/bar\fR needs it to remain. A workaround for this problem is to +create a file in \fIfoo/bar\fR as a placeholder. If you name that file +\&\fI.placeholder\fR, it will be easy to find and remove such files when +this bug is fixed. +.IP "\(bu" 4 +When using multiple stow directories (see \*(L"Multiple stow directories\*(R" +in the info manual), Stow fails to \*(L"split open\*(R" tree-folding symlinks +(see \*(L"Installing packages\*(R" in the info manual) that point into a stow +directory which is not the one in use by the current Stow +command. Before failing, it should search the target of the link to +see whether any element of the path contains a \fI.stow\fR file. If it +finds one, it can \*(L"learn\*(R" about the cooperating stow directory to +short-circuit the \fI.stow\fR search the next time it encounters a +tree-folding symlink. +.SH "AUTHOR" +.IX Header "AUTHOR" +This man page was originally constructed by Charles Briscoe-Smith from +parts of Stow's info manual, and then converted to \s-1POD\s0 format by Adam +Spiers. The info manual contains the following notice, which, as it +says, applies to this manual page, too. The text of the section +entitled \*(L"\s-1GNU\s0 General Public License\*(R" can be found in the file +\&\fI/usr/share/common\-licenses/GPL\fR on any Debian GNU/Linux system. If +you don't have access to a Debian system, or the \s-1GPL\s0 is not there, +write to the Free Software Foundation, Inc., 59 Temple Place, Suite +330, Boston, \s-1MA, 02111\-1307, USA.\s0 +.SH "COPYRIGHT" +.IX Header "COPYRIGHT" +Copyright (C) +1993, 1994, 1995, 1996 by Bob Glickstein ; +2000, 2001 by Guillaume Morin; +2007 by Kahlil Hodgson; +2011 by Adam Spiers; +and others. +.PP +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. +.PP +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that +the section entitled \*(L"\s-1GNU\s0 General Public License\*(R" is included with the +modified manual, and provided that the entire resulting derived work +is distributed under the terms of a permission notice identical to +this one. +.PP +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be stated in a +translation approved by the Free Software Foundation. diff --git a/.local/share/perl/Stow.pm b/.local/share/perl/Stow.pm new file mode 100644 index 0000000..bda7d3a --- /dev/null +++ b/.local/share/perl/Stow.pm @@ -0,0 +1,2110 @@ +#!/usr/bin/perl + +package Stow; + +=head1 NAME + +Stow - manage the installation of multiple software packages + +=head1 SYNOPSIS + + my $stow = new Stow(%$options); + + $stow->plan_unstow(@pkgs_to_unstow); + $stow->plan_stow (@pkgs_to_stow); + + my %conflicts = $stow->get_conflicts; + $stow->process_tasks() unless %conflicts; + +=head1 DESCRIPTION + +This is the backend Perl module for GNU Stow, a program for managing +the installation of software packages, keeping them separate +(C vs. C, for example) +while making them appear to be installed in the same place +(C). + +Stow doesn't store an extra state between runs, so there's no danger +of mangling directories when file hierarchies don't match the +database. Also, stow will never delete any files, directories, or +links that appear in a stow directory, so it is always possible to +rebuild the target tree. + +=cut + +use strict; +use warnings; + +use Carp qw(carp cluck croak confess longmess); +use File::Copy qw(move); +use File::Spec; +use POSIX qw(getcwd); + +use Stow::Util qw(set_debug_level debug error set_test_mode + join_paths restore_cwd canon_path parent); + +our $ProgramName = 'stow'; +our $VERSION = '2.2.2'; + +our $LOCAL_IGNORE_FILE = '.stow-local-ignore'; +our $GLOBAL_IGNORE_FILE = '.stow-global-ignore'; + +our @default_global_ignore_regexps = + __PACKAGE__->get_default_global_ignore_regexps(); + +# These are the default options for each Stow instance. +our %DEFAULT_OPTIONS = ( + conflicts => 0, + simulate => 0, + verbose => 0, + paranoid => 0, + compat => 0, + test_mode => 0, + adopt => 0, + 'no-folding' => 0, + ignore => [], + override => [], + defer => [], +); + +=head1 CONSTRUCTORS + +=head2 new(%options) + +=head3 Required options + +=over 4 + +=item * dir - the stow directory + +=item * target - the target directory + +=back + +=head3 Non-mandatory options + +See the documentation for the F CLI front-end for information on these. + +=over 4 + +=item * conflicts + +=item * simulate + +=item * verbose + +=item * paranoid + +=item * compat + +=item * test_mode + +=item * adopt + +=item * no-folding + +=item * ignore + +=item * override + +=item * defer + +=back + +N.B. This sets the current working directory to the target directory. + +=cut + +sub new { + my $self = shift; + my $class = ref($self) || $self; + my %opts = @_; + + my $new = bless { }, $class; + + $new->{action_count} = 0; + + for my $required_arg (qw(dir target)) { + croak "$class->new() called without '$required_arg' parameter\n" + unless exists $opts{$required_arg}; + $new->{$required_arg} = delete $opts{$required_arg}; + } + + for my $opt (keys %DEFAULT_OPTIONS) { + $new->{$opt} = exists $opts{$opt} ? delete $opts{$opt} + : $DEFAULT_OPTIONS{$opt}; + } + + if (%opts) { + croak "$class->new() called with unrecognised parameter(s): ", + join(", ", keys %opts), "\n"; + } + + set_debug_level($new->get_verbosity()); + set_test_mode($new->{test_mode}); + $new->set_stow_dir(); + $new->init_state(); + + return $new; +} + +sub get_verbosity { + my $self = shift; + + return $self->{verbose} unless $self->{test_mode}; + + return 0 unless exists $ENV{TEST_VERBOSE}; + return 0 unless length $ENV{TEST_VERBOSE}; + + # Convert TEST_VERBOSE=y into numeric value + $ENV{TEST_VERBOSE} = 3 if $ENV{TEST_VERBOSE} !~ /^\d+$/; + + return $ENV{TEST_VERBOSE}; +} + +=head2 set_stow_dir([$dir]) + +Sets a new stow directory. This allows the use of multiple stow +directories within one Stow instance, e.g. + + $stow->plan_stow('foo'); + $stow->set_stow_dir('/different/stow/dir'); + $stow->plan_stow('bar'); + $stow->process_tasks; + +If C<$dir> is omitted, uses the value of the C parameter passed +to the L constructor. + +=cut + +sub set_stow_dir { + my $self = shift; + my ($dir) = @_; + if (defined $dir) { + $self->{dir} = $dir; + } + + my $stow_dir = canon_path($self->{dir}); + my $target = canon_path($self->{target}); + $self->{stow_path} = File::Spec->abs2rel($stow_dir, $target); + + debug(2, "stow dir is $stow_dir"); + debug(2, "stow dir path relative to target $target is $self->{stow_path}"); +} + +sub init_state { + my $self = shift; + + # Store conflicts during pre-processing + $self->{conflicts} = {}; + $self->{conflict_count} = 0; + + # Store command line packages to stow (-S and -R) + $self->{pkgs_to_stow} = []; + + # Store command line packages to unstow (-D and -R) + $self->{pkgs_to_delete} = []; + + # The following structures are used by the abstractions that allow us to + # defer operating on the filesystem until after all potential conflicts have + # been assessed. + + # $self->{tasks}: list of operations to be performed (in order) + # each element is a hash ref of the form + # { + # action => ... ('create' or 'remove' or 'move') + # type => ... ('link' or 'dir' or 'file') + # path => ... (unique) + # source => ... (only for links) + # dest => ... (only for moving files) + # } + $self->{tasks} = []; + + # $self->{dir_task_for}: map a path to the corresponding directory task reference + # This structure allows us to quickly determine if a path has an existing + # directory task associated with it. + $self->{dir_task_for} = {}; + + # $self->{link_task_for}: map a path to the corresponding directory task reference + # This structure allows us to quickly determine if a path has an existing + # directory task associated with it. + $self->{link_task_for} = {}; + + # N.B.: directory tasks and link tasks are NOT mutually exclusive due + # to tree splitting (which involves a remove link task followed by + # a create directory task). +} + +=head1 METHODS + +=head2 plan_unstow(@packages) + +Plan which symlink/directory creation/removal tasks need to be executed +in order to unstow the given packages. Any potential conflicts are then +accessible via L. + +=cut + +sub plan_unstow { + my $self = shift; + my @packages = @_; + + $self->within_target_do(sub { + for my $package (@packages) { + my $path = join_paths($self->{stow_path}, $package); + if (not -d $path) { + error("The stow directory $self->{stow_path} does not contain package $package"); + } + debug(2, "Planning unstow of package $package..."); + if ($self->{compat}) { + $self->unstow_contents_orig( + $self->{stow_path}, + $package, + '.', + ); + } + else { + $self->unstow_contents( + $self->{stow_path}, + $package, + '.', + ); + } + debug(2, "Planning unstow of package $package... done"); + $self->{action_count}++; + } + }); +} + +=head2 plan_stow(@packages) + +Plan which symlink/directory creation/removal tasks need to be executed +in order to stow the given packages. Any potential conflicts are then +accessible via L. + +=cut + +sub plan_stow { + my $self = shift; + my @packages = @_; + + $self->within_target_do(sub { + for my $package (@packages) { + my $path = join_paths($self->{stow_path}, $package); + if (not -d $path) { + error("The stow directory $self->{stow_path} does not contain package $package"); + } + debug(2, "Planning stow of package $package..."); + $self->stow_contents( + $self->{stow_path}, + $package, + '.', + $path, # source from target + ); + debug(2, "Planning stow of package $package... done"); + $self->{action_count}++; + } + }); +} + +#===== METHOD =============================================================== +# Name : within_target_do() +# Purpose : execute code within target directory, preserving cwd +# Parameters: $code => anonymous subroutine to execute within target dir +# Returns : n/a +# Throws : n/a +# Comments : This is done to ensure that the consumer of the Stow interface +# : doesn't have to worry about (a) what their cwd is, and +# : (b) that their cwd might change. +#============================================================================ +sub within_target_do { + my $self = shift; + my ($code) = @_; + + my $cwd = getcwd(); + chdir($self->{target}) + or error("Cannot chdir to target tree: $self->{target} ($!)"); + debug(3, "cwd now $self->{target}"); + + $self->$code(); + + restore_cwd($cwd); + debug(3, "cwd restored to $cwd"); +} + +#===== METHOD =============================================================== +# Name : stow_contents() +# Purpose : stow the contents of the given directory +# Parameters: $stow_path => relative path from current (i.e. target) directory +# : to the stow dir containing the package to be stowed +# : $package => the package whose contents are being stowed +# : $target => subpath relative to package and target directories +# : $source => relative path from the (sub)dir of target +# : to symlink source +# Returns : n/a +# Throws : a fatal error if directory cannot be read +# Comments : stow_node() and stow_contents() are mutually recursive. +# : $source and $target are used for creating the symlink +# : $path is used for folding/unfolding trees as necessary +#============================================================================ +sub stow_contents { + my $self = shift; + my ($stow_path, $package, $target, $source) = @_; + + my $path = join_paths($stow_path, $package, $target); + + return if $self->should_skip_target_which_is_stow_dir($target); + + my $cwd = getcwd(); + my $msg = "Stowing contents of $path (cwd=$cwd)"; + $msg =~ s!$ENV{HOME}(/|$)!~$1!g; + debug(3, $msg); + debug(4, " => $source"); + + error("stow_contents() called with non-directory path: $path") + unless -d $path; + error("stow_contents() called with non-directory target: $target") + unless $self->is_a_node($target); + + opendir my $DIR, $path + or error("cannot read directory: $path ($!)"); + my @listing = readdir $DIR; + closedir $DIR; + + NODE: + for my $node (@listing) { + next NODE if $node eq '.'; + next NODE if $node eq '..'; + my $node_target = join_paths($target, $node); + next NODE if $self->ignore($stow_path, $package, $node_target); + $self->stow_node( + $stow_path, + $package, + $node_target, # target + join_paths($source, $node), # source + ); + } +} + +#===== METHOD =============================================================== +# Name : stow_node() +# Purpose : stow the given node +# Parameters: $stow_path => relative path from current (i.e. target) directory +# : to the stow dir containing the node to be stowed +# : $package => the package containing the node being stowed +# : $target => subpath relative to package and target directories +# : $source => relative path to symlink source from the dir of target +# Returns : n/a +# Throws : fatal exception if a conflict arises +# Comments : stow_node() and stow_contents() are mutually recursive +# : $source and $target are used for creating the symlink +# : $path is used for folding/unfolding trees as necessary +#============================================================================ +sub stow_node { + my $self = shift; + my ($stow_path, $package, $target, $source) = @_; + + my $path = join_paths($stow_path, $package, $target); + + debug(3, "Stowing $stow_path / $package / $target"); + debug(4, " => $source"); + + # Don't try to stow absolute symlinks (they can't be unstowed) + if (-l $source) { + my $second_source = $self->read_a_link($source); + if ($second_source =~ m{\A/}) { + $self->conflict( + 'stow', + $package, + "source is an absolute symlink $source => $second_source" + ); + debug(3, "Absolute symlinks cannot be unstowed"); + return; + } + } + + # Does the target already exist? + if ($self->is_a_link($target)) { + # Where is the link pointing? + my $existing_source = $self->read_a_link($target); + if (not $existing_source) { + error("Could not read link: $target"); + } + debug(4, " Evaluate existing link: $target => $existing_source"); + + # Does it point to a node under any stow directory? + my ($existing_path, $existing_stow_path, $existing_package) = + $self->find_stowed_path($target, $existing_source); + if (not $existing_path) { + $self->conflict( + 'stow', + $package, + "existing target is not owned by stow: $target" + ); + return; # XXX # + } + + # Does the existing $target actually point to anything? + if ($self->is_a_node($existing_path)) { + if ($existing_source eq $source) { + debug(2, "--- Skipping $target as it already points to $source"); + } + elsif ($self->defer($target)) { + debug(2, "--- Deferring installation of: $target"); + } + elsif ($self->override($target)) { + debug(2, "--- Overriding installation of: $target"); + $self->do_unlink($target); + $self->do_link($source, $target); + } + elsif ($self->is_a_dir(join_paths(parent($target), $existing_source)) && + $self->is_a_dir(join_paths(parent($target), $source)) ) { + + # If the existing link points to a directory, + # and the proposed new link points to a directory, + # then we can unfold (split open) the tree at that point + + debug(2, "--- Unfolding $target which was already owned by $existing_package"); + $self->do_unlink($target); + $self->do_mkdir($target); + $self->stow_contents( + $existing_stow_path, + $existing_package, + $target, + join_paths('..', $existing_source), + ); + $self->stow_contents( + $self->{stow_path}, + $package, + $target, + join_paths('..', $source), + ); + } + else { + $self->conflict( + 'stow', + $package, + "existing target is stowed to a different package: " + . "$target => $existing_source" + ); + } + } + else { + # The existing link is invalid, so replace it with a good link + debug(2, "--- replacing invalid link: $path"); + $self->do_unlink($target); + $self->do_link($source, $target); + } + } + elsif ($self->is_a_node($target)) { + debug(4, " Evaluate existing node: $target"); + if ($self->is_a_dir($target)) { + $self->stow_contents( + $self->{stow_path}, + $package, + $target, + join_paths('..', $source), + ); + } + else { + if ($self->{adopt}) { + $self->do_mv($target, $path); + $self->do_link($source, $target); + } + else { + $self->conflict( + 'stow', + $package, + "existing target is neither a link nor a directory: $target" + ); + } + } + } + elsif ($self->{'no-folding'} && -d $path && ! -l $path) { + $self->do_mkdir($target); + $self->stow_contents( + $self->{stow_path}, + $package, + $target, + join_paths('..', $source), + ); + } + else { + $self->do_link($source, $target); + } + return; +} + +#===== METHOD =============================================================== +# Name : should_skip_target_which_is_stow_dir() +# Purpose : determine whether target is a stow directory which should +# : not be stowed to or unstowed from +# Parameters: $target => relative path to symlink target from the current directory +# Returns : true iff target is a stow directory +# Throws : n/a +# Comments : none +#============================================================================ +sub should_skip_target_which_is_stow_dir { + my $self = shift; + my ($target) = @_; + + # Don't try to remove anything under a stow directory + if ($target eq $self->{stow_path}) { + warn "WARNING: skipping target which was current stow directory $target\n"; + return 1; + } + + if ($self->marked_stow_dir($target)) { + warn "WARNING: skipping protected directory $target\n"; + return 1; + } + + debug (4, "$target not protected"); + return 0; +} + +sub marked_stow_dir { + my $self = shift; + my ($target) = @_; + for my $f (".stow", ".nonstow") { + if (-e join_paths($target, $f)) { + debug(4, "$target contained $f"); + return 1; + } + } + return 0; +} + +#===== METHOD =============================================================== +# Name : unstow_contents_orig() +# Purpose : unstow the contents of the given directory +# Parameters: $stow_path => relative path from current (i.e. target) directory +# : to the stow dir containing the package to be unstowed +# : $package => the package whose contents are being unstowed +# : $target => relative path to symlink target from the current directory +# Returns : n/a +# Throws : a fatal error if directory cannot be read +# Comments : unstow_node_orig() and unstow_contents_orig() are mutually recursive +# : Here we traverse the target tree, rather than the source tree. +#============================================================================ +sub unstow_contents_orig { + my $self = shift; + my ($stow_path, $package, $target) = @_; + + my $path = join_paths($stow_path, $package, $target); + + return if $self->should_skip_target_which_is_stow_dir($target); + + my $cwd = getcwd(); + my $msg = "Unstowing from $target (compat mode, cwd=$cwd, stow dir=$self->{stow_path})"; + $msg =~ s!$ENV{HOME}(/|$)!~$1!g; + debug(3, $msg); + debug(4, " source path is $path"); + # In compat mode we traverse the target tree not the source tree, + # so we're unstowing the contents of /target/foo, there's no + # guarantee that the corresponding /stow/mypkg/foo exists. + error("unstow_contents_orig() called with non-directory target: $target") + unless -d $target; + + opendir my $DIR, $target + or error("cannot read directory: $target ($!)"); + my @listing = readdir $DIR; + closedir $DIR; + + NODE: + for my $node (@listing) { + next NODE if $node eq '.'; + next NODE if $node eq '..'; + my $node_target = join_paths($target, $node); + next NODE if $self->ignore($stow_path, $package, $node_target); + $self->unstow_node_orig($stow_path, $package, $node_target); + } +} + +#===== METHOD =============================================================== +# Name : unstow_node_orig() +# Purpose : unstow the given node +# Parameters: $stow_path => relative path from current (i.e. target) directory +# : to the stow dir containing the node to be stowed +# : $package => the package containing the node being stowed +# : $target => relative path to symlink target from the current directory +# Returns : n/a +# Throws : fatal error if a conflict arises +# Comments : unstow_node() and unstow_contents() are mutually recursive +#============================================================================ +sub unstow_node_orig { + my $self = shift; + my ($stow_path, $package, $target) = @_; + + my $path = join_paths($stow_path, $package, $target); + + debug(3, "Unstowing $target (compat mode)"); + debug(4, " source path is $path"); + + # Does the target exist? + if ($self->is_a_link($target)) { + debug(4, " Evaluate existing link: $target"); + + # Where is the link pointing? + my $existing_source = $self->read_a_link($target); + if (not $existing_source) { + error("Could not read link: $target"); + } + + # Does it point to a node under any stow directory? + my ($existing_path, $existing_stow_path, $existing_package) = + $self->find_stowed_path($target, $existing_source); + if (not $existing_path) { + # We're traversing the target tree not the package tree, + # so we definitely expect to find stuff not owned by stow. + # Therefore we can't flag a conflict. + return; # XXX # + } + + # Does the existing $target actually point to anything? + if (-e $existing_path) { + # Does link point to the right place? + if ($existing_path eq $path) { + $self->do_unlink($target); + } + elsif ($self->override($target)) { + debug(2, "--- overriding installation of: $target"); + $self->do_unlink($target); + } + # else leave it alone + } + else { + debug(2, "--- removing invalid link into a stow directory: $path"); + $self->do_unlink($target); + } + } + elsif (-d $target) { + $self->unstow_contents_orig($stow_path, $package, $target); + + # This action may have made the parent directory foldable + if (my $parent = $self->foldable($target)) { + $self->fold_tree($target, $parent); + } + } + elsif (-e $target) { + $self->conflict( + 'unstow', + $package, + "existing target is neither a link nor a directory: $target", + ); + } + else { + debug(2, "$target did not exist to be unstowed"); + } + return; +} + +#===== METHOD =============================================================== +# Name : unstow_contents() +# Purpose : unstow the contents of the given directory +# Parameters: $stow_path => relative path from current (i.e. target) directory +# : to the stow dir containing the package to be unstowed +# : $package => the package whose contents are being unstowed +# : $target => relative path to symlink target from the current directory +# Returns : n/a +# Throws : a fatal error if directory cannot be read +# Comments : unstow_node() and unstow_contents() are mutually recursive +# : Here we traverse the source tree, rather than the target tree. +#============================================================================ +sub unstow_contents { + my $self = shift; + my ($stow_path, $package, $target) = @_; + + my $path = join_paths($stow_path, $package, $target); + + return if $self->should_skip_target_which_is_stow_dir($target); + + my $cwd = getcwd(); + my $msg = "Unstowing from $target (cwd=$cwd, stow dir=$self->{stow_path})"; + $msg =~ s!$ENV{HOME}/!~/!g; + debug(3, $msg); + debug(4, " source path is $path"); + # We traverse the source tree not the target tree, so $path must exist. + error("unstow_contents() called with non-directory path: $path") + unless -d $path; + # When called at the top level, $target should exist. And + # unstow_node() should only call this via mutual recursion if + # $target exists. + error("unstow_contents() called with invalid target: $target") + unless $self->is_a_node($target); + + opendir my $DIR, $path + or error("cannot read directory: $path ($!)"); + my @listing = readdir $DIR; + closedir $DIR; + + NODE: + for my $node (@listing) { + next NODE if $node eq '.'; + next NODE if $node eq '..'; + my $node_target = join_paths($target, $node); + next NODE if $self->ignore($stow_path, $package, $node_target); + $self->unstow_node($stow_path, $package, $node_target); + } + if (-d $target) { + $self->cleanup_invalid_links($target); + } +} + +#===== METHOD =============================================================== +# Name : unstow_node() +# Purpose : unstow the given node +# Parameters: $stow_path => relative path from current (i.e. target) directory +# : to the stow dir containing the node to be stowed +# : $package => the package containing the node being unstowed +# : $target => relative path to symlink target from the current directory +# Returns : n/a +# Throws : fatal error if a conflict arises +# Comments : unstow_node() and unstow_contents() are mutually recursive +#============================================================================ +sub unstow_node { + my $self = shift; + my ($stow_path, $package, $target) = @_; + + my $path = join_paths($stow_path, $package, $target); + + debug(3, "Unstowing $path"); + debug(4, " target is $target"); + + # Does the target exist? + if ($self->is_a_link($target)) { + debug(4, " Evaluate existing link: $target"); + + # Where is the link pointing? + my $existing_source = $self->read_a_link($target); + if (not $existing_source) { + error("Could not read link: $target"); + } + + if ($existing_source =~ m{\A/}) { + warn "Ignoring an absolute symlink: $target => $existing_source\n"; + return; # XXX # + } + + # Does it point to a node under any stow directory? + my ($existing_path, $existing_stow_path, $existing_package) = + $self->find_stowed_path($target, $existing_source); + if (not $existing_path) { + $self->conflict( + 'unstow', + $package, + "existing target is not owned by stow: $target => $existing_source" + ); + return; # XXX # + } + + # Does the existing $target actually point to anything? + if (-e $existing_path) { + # Does link points to the right place? + if ($existing_path eq $path) { + $self->do_unlink($target); + } + + # XXX we quietly ignore links that are stowed to a different + # package. + + #elsif (defer($target)) { + # debug(2, "--- deferring to installation of: $target"); + #} + #elsif ($self->override($target)) { + # debug(2, "--- overriding installation of: $target"); + # $self->do_unlink($target); + #} + #else { + # $self->conflict( + # 'unstow', + # $package, + # "existing target is stowed to a different package: " + # . "$target => $existing_source" + # ); + #} + } + else { + debug(2, "--- removing invalid link into a stow directory: $path"); + $self->do_unlink($target); + } + } + elsif (-e $target) { + debug(4, " Evaluate existing node: $target"); + if (-d $target) { + $self->unstow_contents($stow_path, $package, $target); + + # This action may have made the parent directory foldable + if (my $parent = $self->foldable($target)) { + $self->fold_tree($target, $parent); + } + } + else { + $self->conflict( + 'unstow', + $package, + "existing target is neither a link nor a directory: $target", + ); + } + } + else { + debug(2, "$target did not exist to be unstowed"); + } + return; +} + +#===== METHOD =============================================================== +# Name : path_owned_by_package() +# Purpose : determine whether the given link points to a member of a +# : stowed package +# Parameters: $target => path to a symbolic link under current directory +# : $source => where that link points to +# Returns : the package iff link is owned by stow, otherwise '' +# Throws : n/a +# Comments : lossy wrapper around find_stowed_path() +#============================================================================ +sub path_owned_by_package { + my $self = shift; + my ($target, $source) = @_; + + my ($path, $stow_path, $package) = + $self->find_stowed_path($target, $source); + return $package; +} + +#===== METHOD =============================================================== +# Name : find_stowed_path() +# Purpose : determine whether the given link points to a member of a +# : stowed package +# Parameters: $target => path to a symbolic link under current directory +# : $source => where that link points to (needed because link +# : might not exist yet due to two-phase approach, +# : so we can't just call readlink()) +# Returns : ($path, $stow_path, $package) where $path and $stow_path are +# : relative from the current (i.e. target) directory. $path +# : is the full relative path, $stow_path is the relative path +# : to the stow directory, and $package is the name of the package. +# : or ('', '', '') if link is not owned by stow +# Throws : n/a +# Comments : Needs +# : Allow for stow dir not being under target dir. +# : We could put more logic under here for multiple stow dirs. +#============================================================================ +sub find_stowed_path { + my $self = shift; + my ($target, $source) = @_; + + # Evaluate softlink relative to its target + my $path = join_paths(parent($target), $source); + debug(4, " is path $path owned by stow?"); + + # Search for .stow files - this allows us to detect links + # owned by stow directories other than the current one. + my $dir = ''; + my @path = split m{/+}, $path; + for my $i (0 .. $#path) { + my $part = $path[$i]; + $dir = join_paths($dir, $part); + if ($self->marked_stow_dir($dir)) { + # FIXME - not sure if this can ever happen + internal_error("find_stowed_path() called directly on stow dir") + if $i == $#path; + + debug(4, " yes - $dir was marked as a stow dir"); + my $package = $path[$i + 1]; + return ($path, $dir, $package); + } + } + + # If no .stow file was found, we need to find out whether it's + # owned by the current stow directory, in which case $path will be + # a prefix of $self->{stow_path}. + my @stow_path = split m{/+}, $self->{stow_path}; + + # Strip off common prefixes until one is empty + while (@path && @stow_path) { + if ((shift @path) ne (shift @stow_path)) { + debug(4, " no - either $path not under $self->{stow_path} or vice-versa"); + return ('', '', ''); + } + } + + if (@stow_path) { # @path must be empty + debug(4, " no - $path is not under $self->{stow_path}"); + return ('', '', ''); + } + + my $package = shift @path; + + debug(4, " yes - by $package in " . join_paths(@path)); + return ($path, $self->{stow_path}, $package); +} + +#===== METHOD ================================================================ +# Name : cleanup_invalid_links() +# Purpose : clean up invalid links that may block folding +# Parameters: $dir => path to directory to check +# Returns : n/a +# Throws : no exceptions +# Comments : removing files from a stowed package is probably a bad practice +# : so this kind of clean up is not _really_ stow's responsibility; +# : however, failing to clean up can block tree folding, so we'll do +# : it anyway +#============================================================================= +sub cleanup_invalid_links { + my $self = shift; + my ($dir) = @_; + + if (not -d $dir) { + error("cleanup_invalid_links() called with a non-directory: $dir"); + } + + opendir my $DIR, $dir + or error("cannot read directory: $dir ($!)"); + my @listing = readdir $DIR; + closedir $DIR; + + NODE: + for my $node (@listing) { + next NODE if $node eq '.'; + next NODE if $node eq '..'; + + my $node_path = join_paths($dir, $node); + + if (-l $node_path and not exists $self->{link_task_for}{$node_path}) { + + # Where is the link pointing? + # (don't use read_a_link() here) + my $source = readlink($node_path); + if (not $source) { + error("Could not read link $node_path"); + } + + if ( + not -e join_paths($dir, $source) and # bad link + $self->path_owned_by_package($node_path, $source) # owned by stow + ){ + debug(2, "--- removing stale link: $node_path => " . + join_paths($dir, $source)); + $self->do_unlink($node_path); + } + } + } + return; +} + + +#===== METHOD =============================================================== +# Name : foldable() +# Purpose : determine whether a tree can be folded +# Parameters: $target => path to a directory +# Returns : path to the parent dir iff the tree can be safely folded +# Throws : n/a +# Comments : the path returned is relative to the parent of $target, +# : that is, it can be used as the source for a replacement symlink +#============================================================================ +sub foldable { + my $self = shift; + my ($target) = @_; + + debug(3, "--- Is $target foldable?"); + if ($self->{'no-folding'}) { + debug(3, "--- no because --no-folding enabled"); + return ''; + } + + opendir my $DIR, $target + or error(qq{Cannot read directory "$target" ($!)\n}); + my @listing = readdir $DIR; + closedir $DIR; + + my $parent = ''; + NODE: + for my $node (@listing) { + + next NODE if $node eq '.'; + next NODE if $node eq '..'; + + my $path = join_paths($target, $node); + + # Skip nodes scheduled for removal + next NODE if not $self->is_a_node($path); + + # If it's not a link then we can't fold its parent + return '' if not $self->is_a_link($path); + + # Where is the link pointing? + my $source = $self->read_a_link($path); + if (not $source) { + error("Could not read link $path"); + } + if ($parent eq '') { + $parent = parent($source) + } + elsif ($parent ne parent($source)) { + return ''; + } + } + return '' if not $parent; + + # If we get here then all nodes inside $target are links, and those links + # point to nodes inside the same directory. + + # chop of leading '..' to get the path to the common parent directory + # relative to the parent of our $target + $parent =~ s{\A\.\./}{}; + + # If the resulting path is owned by stow, we can fold it + if ($self->path_owned_by_package($target, $parent)) { + debug(3, "--- $target is foldable"); + return $parent; + } + else { + return ''; + } +} + +#===== METHOD =============================================================== +# Name : fold_tree() +# Purpose : fold the given tree +# Parameters: $source => link to the folded tree source +# : $target => directory that we will replace with a link to $source +# Returns : n/a +# Throws : none +# Comments : only called iff foldable() is true so we can remove some checks +#============================================================================ +sub fold_tree { + my $self = shift; + my ($target, $source) = @_; + + debug(3, "--- Folding tree: $target => $source"); + + opendir my $DIR, $target + or error(qq{Cannot read directory "$target" ($!)\n}); + my @listing = readdir $DIR; + closedir $DIR; + + NODE: + for my $node (@listing) { + next NODE if $node eq '.'; + next NODE if $node eq '..'; + next NODE if not $self->is_a_node(join_paths($target, $node)); + $self->do_unlink(join_paths($target, $node)); + } + $self->do_rmdir($target); + $self->do_link($source, $target); + return; +} + + +#===== METHOD =============================================================== +# Name : conflict() +# Purpose : handle conflicts in stow operations +# Parameters: $package => the package involved with the conflicting operation +# : $message => a description of the conflict +# Returns : n/a +# Throws : none +# Comments : none +#============================================================================ +sub conflict { + my $self = shift; + my ($action, $package, $message) = @_; + + debug(2, "CONFLICT when ${action}ing $package: $message"); + $self->{conflicts}{$action}{$package} ||= []; + push @{ $self->{conflicts}{$action}{$package} }, $message; + $self->{conflict_count}++; + + return; +} + +=head2 get_conflicts() + +Returns a nested hash of all potential conflicts discovered: the keys +are actions ('stow' or 'unstow'), and the values are hashrefs whose +keys are stow package names and whose values are conflict +descriptions, e.g.: + + ( + stow => { + perl => [ + "existing target is not owned by stow: bin/a2p" + "existing target is neither a link nor a directory: bin/perl" + ] + } + ) + +=cut + +sub get_conflicts { + my $self = shift; + return %{ $self->{conflicts} }; +} + +=head2 get_conflict_count() + +Returns the number of conflicts found. + +=cut + +sub get_conflict_count { + my $self = shift; + return $self->{conflict_count}; +} + +=head2 get_tasks() + +Returns a list of all symlink/directory creation/removal tasks. + +=cut + +sub get_tasks { + my $self = shift; + return @{ $self->{tasks} }; +} + +=head2 get_action_count() + +Returns the number of actions planned for this Stow instance. + +=cut + +sub get_action_count { + my $self = shift; + return $self->{action_count}; +} + +#===== METHOD ================================================================ +# Name : ignore +# Purpose : determine if the given path matches a regex in our ignore list +# Parameters: $stow_path => the stow directory containing the package +# : $package => the package containing the path +# : $target => the path to check against the ignore list +# : relative to its package directory +# Returns : true iff the path should be ignored +# Throws : no exceptions +# Comments : none +#============================================================================= +sub ignore { + my $self = shift; + my ($stow_path, $package, $target) = @_; + + internal_error(__PACKAGE__ . "::ignore() called with empty target") + unless length $target; + + for my $suffix (@{ $self->{ignore} }) { + if ($target =~ m/$suffix/) { + debug(4, " Ignoring path $target due to --ignore=$suffix"); + return 1; + } + } + + my $package_dir = join_paths($stow_path, $package); + my ($path_regexp, $segment_regexp) = + $self->get_ignore_regexps($package_dir); + debug(5, " Ignore list regexp for paths: " . + (defined $path_regexp ? "/$path_regexp/" : "none")); + debug(5, " Ignore list regexp for segments: " . + (defined $segment_regexp ? "/$segment_regexp/" : "none")); + + if (defined $path_regexp and "/$target" =~ $path_regexp) { + debug(4, " Ignoring path /$target"); + return 1; + } + + (my $basename = $target) =~ s!.+/!!; + if (defined $segment_regexp and $basename =~ $segment_regexp) { + debug(4, " Ignoring path segment $basename"); + return 1; + } + + debug(5, " Not ignoring $target"); + return 0; +} + +sub get_ignore_regexps { + my $self = shift; + my ($dir) = @_; + + # N.B. the local and global stow ignore files have to have different + # names so that: + # 1. the global one can be a symlink to within a stow + # package, managed by stow itself, and + # 2. the local ones can be ignored via hardcoded logic in + # GlobsToRegexp(), so that they always stay within their stow packages. + + my $local_stow_ignore = join_paths($dir, $LOCAL_IGNORE_FILE); + my $global_stow_ignore = join_paths($ENV{HOME}, $GLOBAL_IGNORE_FILE); + + for my $file ($local_stow_ignore, $global_stow_ignore) { + if (-e $file) { + debug(5, " Using ignore file: $file"); + return $self->get_ignore_regexps_from_file($file); + } + else { + debug(5, " $file didn't exist"); + } + } + + debug(4, " Using built-in ignore list"); + return @default_global_ignore_regexps; +} + +my %ignore_file_regexps; + +sub get_ignore_regexps_from_file { + my $self = shift; + my ($file) = @_; + + if (exists $ignore_file_regexps{$file}) { + debug(4, " Using memoized regexps from $file"); + return @{ $ignore_file_regexps{$file} }; + } + + if (! open(REGEXPS, $file)) { + debug(4, " Failed to open $file: $!"); + return undef; + } + + my @regexps = $self->get_ignore_regexps_from_fh(\*REGEXPS); + close(REGEXPS); + + $ignore_file_regexps{$file} = [ @regexps ]; + return @regexps; +} + +=head2 invalidate_memoized_regexp($file) + +For efficiency of performance, regular expressions are compiled from +each ignore list file the first time it is used by the Stow process, +and then memoized for future use. If you expect the contents of these +files to change during a single run, you will need to invalidate the +memoized value from this cache. This method allows you to do that. + +=cut + +sub invalidate_memoized_regexp { + my $self = shift; + my ($file) = @_; + if (exists $ignore_file_regexps{$file}) { + debug(4, " Invalidated memoized regexp for $file"); + delete $ignore_file_regexps{$file}; + } + else { + debug(2, " WARNING: no memoized regexp for $file to invalidate"); + } +} + +sub get_ignore_regexps_from_fh { + my $self = shift; + my ($fh) = @_; + my %regexps; + while (<$fh>) { + chomp; + s/^\s+//; + s/\s+$//; + next if /^#/ or length($_) == 0; + s/\s+#.+//; # strip comments to right of pattern + s/\\#/#/g; + $regexps{$_}++; + } + + # Local ignore lists should *always* stay within the stow directory, + # because this is the only place stow looks for them. + $regexps{"^/\Q$LOCAL_IGNORE_FILE\E\$"}++; + + return $self->compile_ignore_regexps(%regexps); +} + +sub compile_ignore_regexps { + my $self = shift; + my (%regexps) = @_; + + my @segment_regexps; + my @path_regexps; + for my $regexp (keys %regexps) { + if (index($regexp, '/') < 0) { + # No / found in regexp, so use it for matching against basename + push @segment_regexps, $regexp; + } + else { + # / found in regexp, so use it for matching against full path + push @path_regexps, $regexp; + } + } + + my $segment_regexp = join '|', @segment_regexps; + my $path_regexp = join '|', @path_regexps; + $segment_regexp = @segment_regexps ? + $self->compile_regexp("^($segment_regexp)\$") : undef; + $path_regexp = @path_regexps ? + $self->compile_regexp("(^|/)($path_regexp)(/|\$)") : undef; + + return ($path_regexp, $segment_regexp); +} + +sub compile_regexp { + my $self = shift; + my ($regexp) = @_; + my $compiled = eval { qr/$regexp/ }; + die "Failed to compile regexp: $@\n" if $@; + return $compiled; +} + +sub get_default_global_ignore_regexps { + my $class = shift; + # Bootstrap issue - first time we stow, we will be stowing + # .cvsignore so it might not exist in ~ yet, or if it does, it could + # be an old version missing the entries we need. So we make sure + # they are there by hardcoding some crucial entries. + return $class->get_ignore_regexps_from_fh(\*DATA); +} + +#===== METHOD ================================================================ +# Name : defer +# Purpose : determine if the given path matches a regex in our defer list +# Parameters: $path +# Returns : Boolean +# Throws : no exceptions +# Comments : none +#============================================================================= +sub defer { + my $self = shift; + my ($path) = @_; + + for my $prefix (@{ $self->{defer} }) { + return 1 if $path =~ m/$prefix/; + } + return 0; +} + +#===== METHOD ================================================================ +# Name : override +# Purpose : determine if the given path matches a regex in our override list +# Parameters: $path +# Returns : Boolean +# Throws : no exceptions +# Comments : none +#============================================================================= +sub override { + my $self = shift; + my ($path) = @_; + + for my $regex (@{ $self->{override} }) { + return 1 if $path =~ m/$regex/; + } + return 0; +} + +############################################################################## +# +# The following code provides the abstractions that allow us to defer operating +# on the filesystem until after all potential conflcits have been assessed. +# +############################################################################## + +#===== METHOD =============================================================== +# Name : process_tasks() +# Purpose : process each task in the tasks list +# Parameters: none +# Returns : n/a +# Throws : fatal error if tasks list is corrupted or a task fails +# Comments : none +#============================================================================ +sub process_tasks { + my $self = shift; + + debug(2, "Processing tasks..."); + + # Strip out all tasks with a skip action + $self->{tasks} = [ grep { $_->{action} ne 'skip' } @{ $self->{tasks} } ]; + + if (not @{ $self->{tasks} }) { + return; + } + + $self->within_target_do(sub { + for my $task (@{ $self->{tasks} }) { + $self->process_task($task); + } + }); + + debug(2, "Processing tasks... done"); +} + +#===== METHOD =============================================================== +# Name : process_task() +# Purpose : process a single task +# Parameters: $task => the task to process +# Returns : n/a +# Throws : fatal error if task fails +# Comments : Must run from within target directory. +# : Task involve either creating or deleting dirs and symlinks +# : an action is set to 'skip' if it is found to be redundant +#============================================================================ +sub process_task { + my $self = shift; + my ($task) = @_; + + if ($task->{action} eq 'create') { + if ($task->{type} eq 'dir') { + mkdir($task->{path}, 0777) + or error("Could not create directory: $task->{path} ($!)"); + return; + } + elsif ($task->{type} eq 'link') { + symlink $task->{source}, $task->{path} + or error( + "Could not create symlink: %s => %s ($!)", + $task->{path}, + $task->{source} + ); + return; + } + } + elsif ($task->{action} eq 'remove') { + if ($task->{type} eq 'dir') { + rmdir $task->{path} + or error("Could not remove directory: $task->{path} ($!)"); + return; + } + elsif ($task->{type} eq 'link') { + unlink $task->{path} + or error("Could not remove link: $task->{path} ($!)"); + return; + } + } + elsif ($task->{action} eq 'move') { + if ($task->{type} eq 'file') { + # rename() not good enough, since the stow directory + # might be on a different filesystem to the target. + move $task->{path}, $task->{dest} + or error("Could not move $task->{path} -> $task->{dest} ($!)"); + return; + } + } + + # Should never happen. + internal_error("bad task action: $task->{action}"); +} + +#===== METHOD =============================================================== +# Name : link_task_action() +# Purpose : finds the link task action for the given path, if there is one +# Parameters: $path +# Returns : 'remove', 'create', or '' if there is no action +# Throws : a fatal exception if an invalid action is found +# Comments : none +#============================================================================ +sub link_task_action { + my $self = shift; + my ($path) = @_; + + if (! exists $self->{link_task_for}{$path}) { + debug(4, " link_task_action($path): no task"); + return ''; + } + + my $action = $self->{link_task_for}{$path}->{action}; + internal_error("bad task action: $action") + unless $action eq 'remove' or $action eq 'create'; + + debug(4, " link_task_action($path): link task exists with action $action"); + return $action; +} + +#===== METHOD =============================================================== +# Name : dir_task_action() +# Purpose : finds the dir task action for the given path, if there is one +# Parameters: $path +# Returns : 'remove', 'create', or '' if there is no action +# Throws : a fatal exception if an invalid action is found +# Comments : none +#============================================================================ +sub dir_task_action { + my $self = shift; + my ($path) = @_; + + if (! exists $self->{dir_task_for}{$path}) { + debug(4, " dir_task_action($path): no task"); + return ''; + } + + my $action = $self->{dir_task_for}{$path}->{action}; + internal_error("bad task action: $action") + unless $action eq 'remove' or $action eq 'create'; + + debug(4, " dir_task_action($path): dir task exists with action $action"); + return $action; +} + +#===== METHOD =============================================================== +# Name : parent_link_scheduled_for_removal() +# Purpose : determine whether the given path or any parent thereof +# : is a link scheduled for removal +# Parameters: $path +# Returns : Boolean +# Throws : none +# Comments : none +#============================================================================ +sub parent_link_scheduled_for_removal { + my $self = shift; + my ($path) = @_; + + my $prefix = ''; + for my $part (split m{/+}, $path) { + $prefix = join_paths($prefix, $part); + debug(4, " parent_link_scheduled_for_removal($path): prefix $prefix"); + if (exists $self->{link_task_for}{$prefix} and + $self->{link_task_for}{$prefix}->{action} eq 'remove') { + debug(4, " parent_link_scheduled_for_removal($path): link scheduled for removal"); + return 1; + } + } + + debug(4, " parent_link_scheduled_for_removal($path): returning false"); + return 0; +} + +#===== METHOD =============================================================== +# Name : is_a_link() +# Purpose : determine if the given path is a current or planned link +# Parameters: $path +# Returns : Boolean +# Throws : none +# Comments : returns false if an existing link is scheduled for removal +# : and true if a non-existent link is scheduled for creation +#============================================================================ +sub is_a_link { + my $self = shift; + my ($path) = @_; + debug(4, " is_a_link($path)"); + + if (my $action = $self->link_task_action($path)) { + if ($action eq 'remove') { + debug(4, " is_a_link($path): returning 0 (remove action found)"); + return 0; + } + elsif ($action eq 'create') { + debug(4, " is_a_link($path): returning 1 (create action found)"); + return 1; + } + } + + if (-l $path) { + # Check if any of its parent are links scheduled for removal + # (need this for edge case during unfolding) + debug(4, " is_a_link($path): is a real link"); + return $self->parent_link_scheduled_for_removal($path) ? 0 : 1; + } + + debug(4, " is_a_link($path): returning 0"); + return 0; +} + +#===== METHOD =============================================================== +# Name : is_a_dir() +# Purpose : determine if the given path is a current or planned directory +# Parameters: $path +# Returns : Boolean +# Throws : none +# Comments : returns false if an existing directory is scheduled for removal +# : and true if a non-existent directory is scheduled for creation +# : we also need to be sure we are not just following a link +#============================================================================ +sub is_a_dir { + my $self = shift; + my ($path) = @_; + debug(4, " is_a_dir($path)"); + + if (my $action = $self->dir_task_action($path)) { + if ($action eq 'remove') { + return 0; + } + elsif ($action eq 'create') { + return 1; + } + } + + return 0 if $self->parent_link_scheduled_for_removal($path); + + if (-d $path) { + debug(4, " is_a_dir($path): real dir"); + return 1; + } + + debug(4, " is_a_dir($path): returning false"); + return 0; +} + +#===== METHOD =============================================================== +# Name : is_a_node() +# Purpose : determine whether the given path is a current or planned node +# Parameters: $path +# Returns : Boolean +# Throws : none +# Comments : returns false if an existing node is scheduled for removal +# : true if a non-existent node is scheduled for creation +# : we also need to be sure we are not just following a link +#============================================================================ +sub is_a_node { + my $self = shift; + my ($path) = @_; + debug(4, " is_a_node($path)"); + + my $laction = $self->link_task_action($path); + my $daction = $self->dir_task_action($path); + + if ($laction eq 'remove') { + if ($daction eq 'remove') { + internal_error("removing link and dir: $path"); + return 0; + } + elsif ($daction eq 'create') { + # Assume that we're unfolding $path, and that the link + # removal action is earlier than the dir creation action + # in the task queue. FIXME: is this a safe assumption? + return 1; + } + else { # no dir action + return 0; + } + } + elsif ($laction eq 'create') { + if ($daction eq 'remove') { + # Assume that we're folding $path, and that the dir + # removal action is earlier than the link creation action + # in the task queue. FIXME: is this a safe assumption? + return 1; + } + elsif ($daction eq 'create') { + internal_error("creating link and dir: $path"); + return 1; + } + else { # no dir action + return 1; + } + } + else { + # No link action + if ($daction eq 'remove') { + return 0; + } + elsif ($daction eq 'create') { + return 1; + } + else { # no dir action + # fall through to below + } + } + + return 0 if $self->parent_link_scheduled_for_removal($path); + + if (-e $path) { + debug(4, " is_a_node($path): really exists"); + return 1; + } + + debug(4, " is_a_node($path): returning false"); + return 0; +} + +#===== METHOD =============================================================== +# Name : read_a_link() +# Purpose : return the source of a current or planned link +# Parameters: $path => path to the link target +# Returns : a string +# Throws : fatal exception if the given path is not a current or planned +# : link +# Comments : none +#============================================================================ +sub read_a_link { + my $self = shift; + my ($path) = @_; + + if (my $action = $self->link_task_action($path)) { + debug(4, " read_a_link($path): task exists with action $action"); + + if ($action eq 'create') { + return $self->{link_task_for}{$path}->{source}; + } + elsif ($action eq 'remove') { + internal_error( + "read_a_link() passed a path that is scheduled for removal: $path" + ); + } + } + elsif (-l $path) { + debug(4, " read_a_link($path): real link"); + my $target = readlink $path or error("Could not read link: $path ($!)"); + return $target; + } + internal_error("read_a_link() passed a non link path: $path\n"); +} + +#===== METHOD =============================================================== +# Name : do_link() +# Purpose : wrap 'link' operation for later processing +# Parameters: $oldfile => the existing file to link to +# : $newfile => the file to link +# Returns : n/a +# Throws : error if this clashes with an existing planned operation +# Comments : cleans up operations that undo previous operations +#============================================================================ +sub do_link { + my $self = shift; + my ($oldfile, $newfile) = @_; + + if (exists $self->{dir_task_for}{$newfile}) { + my $task_ref = $self->{dir_task_for}{$newfile}; + + if ($task_ref->{action} eq 'create') { + if ($task_ref->{type} eq 'dir') { + internal_error( + "new link (%s => %s) clashes with planned new directory", + $newfile, + $oldfile, + ); + } + } + elsif ($task_ref->{action} eq 'remove') { + # We may need to remove a directory before creating a link so continue. + } + else { + internal_error("bad task action: $task_ref->{action}"); + } + } + + if (exists $self->{link_task_for}{$newfile}) { + my $task_ref = $self->{link_task_for}{$newfile}; + + if ($task_ref->{action} eq 'create') { + if ($task_ref->{source} ne $oldfile) { + internal_error( + "new link clashes with planned new link: %s => %s", + $task_ref->{path}, + $task_ref->{source}, + ) + } + else { + debug(1, "LINK: $newfile => $oldfile (duplicates previous action)"); + return; + } + } + elsif ($task_ref->{action} eq 'remove') { + if ($task_ref->{source} eq $oldfile) { + # No need to remove a link we are going to recreate + debug(1, "LINK: $newfile => $oldfile (reverts previous action)"); + $self->{link_task_for}{$newfile}->{action} = 'skip'; + delete $self->{link_task_for}{$newfile}; + return; + } + # We may need to remove a link to replace it so continue + } + else { + internal_error("bad task action: $task_ref->{action}"); + } + } + + # Creating a new link + debug(1, "LINK: $newfile => $oldfile"); + my $task = { + action => 'create', + type => 'link', + path => $newfile, + source => $oldfile, + }; + push @{ $self->{tasks} }, $task; + $self->{link_task_for}{$newfile} = $task; + + return; +} + +#===== METHOD =============================================================== +# Name : do_unlink() +# Purpose : wrap 'unlink' operation for later processing +# Parameters: $file => the file to unlink +# Returns : n/a +# Throws : error if this clashes with an existing planned operation +# Comments : will remove an existing planned link +#============================================================================ +sub do_unlink { + my $self = shift; + my ($file) = @_; + + if (exists $self->{link_task_for}{$file}) { + my $task_ref = $self->{link_task_for}{$file}; + if ($task_ref->{action} eq 'remove') { + debug(1, "UNLINK: $file (duplicates previous action)"); + return; + } + elsif ($task_ref->{action} eq 'create') { + # Do need to create a link then remove it + debug(1, "UNLINK: $file (reverts previous action)"); + $self->{link_task_for}{$file}->{action} = 'skip'; + delete $self->{link_task_for}{$file}; + return; + } + else { + internal_error("bad task action: $task_ref->{action}"); + } + } + + if (exists $self->{dir_task_for}{$file} and $self->{dir_task_for}{$file} eq 'create') { + internal_error( + "new unlink operation clashes with planned operation: %s dir %s", + $self->{dir_task_for}{$file}->{action}, + $file + ); + } + + # Remove the link + debug(1, "UNLINK: $file"); + + my $source = readlink $file or error("could not readlink $file ($!)"); + + my $task = { + action => 'remove', + type => 'link', + path => $file, + source => $source, + }; + push @{ $self->{tasks} }, $task; + $self->{link_task_for}{$file} = $task; + + return; +} + +#===== METHOD =============================================================== +# Name : do_mkdir() +# Purpose : wrap 'mkdir' operation +# Parameters: $dir => the directory to remove +# Returns : n/a +# Throws : fatal exception if operation fails +# Comments : outputs a message if 'verbose' option is set +# : does not perform operation if 'simulate' option is set +# Comments : cleans up operations that undo previous operations +#============================================================================ +sub do_mkdir { + my $self = shift; + my ($dir) = @_; + + if (exists $self->{link_task_for}{$dir}) { + my $task_ref = $self->{link_task_for}{$dir}; + + if ($task_ref->{action} eq 'create') { + internal_error( + "new dir clashes with planned new link (%s => %s)", + $task_ref->{path}, + $task_ref->{source}, + ); + } + elsif ($task_ref->{action} eq 'remove') { + # May need to remove a link before creating a directory so continue + } + else { + internal_error("bad task action: $task_ref->{action}"); + } + } + + if (exists $self->{dir_task_for}{$dir}) { + my $task_ref = $self->{dir_task_for}{$dir}; + + if ($task_ref->{action} eq 'create') { + debug(1, "MKDIR: $dir (duplicates previous action)"); + return; + } + elsif ($task_ref->{action} eq 'remove') { + debug(1, "MKDIR: $dir (reverts previous action)"); + $self->{dir_task_for}{$dir}->{action} = 'skip'; + delete $self->{dir_task_for}{$dir}; + return; + } + else { + internal_error("bad task action: $task_ref->{action}"); + } + } + + debug(1, "MKDIR: $dir"); + my $task = { + action => 'create', + type => 'dir', + path => $dir, + source => undef, + }; + push @{ $self->{tasks} }, $task; + $self->{dir_task_for}{$dir} = $task; + + return; +} + +#===== METHOD =============================================================== +# Name : do_rmdir() +# Purpose : wrap 'rmdir' operation +# Parameters: $dir => the directory to remove +# Returns : n/a +# Throws : fatal exception if operation fails +# Comments : outputs a message if 'verbose' option is set +# : does not perform operation if 'simulate' option is set +#============================================================================ +sub do_rmdir { + my $self = shift; + my ($dir) = @_; + + if (exists $self->{link_task_for}{$dir}) { + my $task_ref = $self->{link_task_for}{$dir}; + internal_error( + "rmdir clashes with planned operation: %s link %s => %s", + $task_ref->{action}, + $task_ref->{path}, + $task_ref->{source} + ); + } + + if (exists $self->{dir_task_for}{$dir}) { + my $task_ref = $self->{link_task_for}{$dir}; + + if ($task_ref->{action} eq 'remove') { + debug(1, "RMDIR $dir (duplicates previous action)"); + return; + } + elsif ($task_ref->{action} eq 'create') { + debug(1, "MKDIR $dir (reverts previous action)"); + $self->{link_task_for}{$dir}->{action} = 'skip'; + delete $self->{link_task_for}{$dir}; + return; + } + else { + internal_error("bad task action: $task_ref->{action}"); + } + } + + debug(1, "RMDIR $dir"); + my $task = { + action => 'remove', + type => 'dir', + path => $dir, + source => '', + }; + push @{ $self->{tasks} }, $task; + $self->{dir_task_for}{$dir} = $task; + + return; +} + +#===== METHOD =============================================================== +# Name : do_mv() +# Purpose : wrap 'move' operation for later processing +# Parameters: $src => the file to move +# : $dst => the path to move it to +# Returns : n/a +# Throws : error if this clashes with an existing planned operation +# Comments : alters contents of package installation image in stow dir +#============================================================================ +sub do_mv { + my $self = shift; + my ($src, $dst) = @_; + + if (exists $self->{link_task_for}{$src}) { + # I don't *think* this should ever happen, but I'm not + # 100% sure. + my $task_ref = $self->{link_task_for}{$src}; + internal_error( + "do_mv: pre-existing link task for $src; action: %s, source: %s", + $task_ref->{action}, $task_ref->{source} + ); + } + elsif (exists $self->{dir_task_for}{$src}) { + my $task_ref = $self->{dir_task_for}{$src}; + internal_error( + "do_mv: pre-existing dir task for %s?! action: %s", + $src, $task_ref->{action} + ); + } + + # Remove the link + debug(1, "MV: $src -> $dst"); + + my $task = { + action => 'move', + type => 'file', + path => $src, + dest => $dst, + }; + push @{ $self->{tasks} }, $task; + + # FIXME: do we need this for anything? + #$self->{mv_task_for}{$file} = $task; + + return; +} + + +############################################################################# +# +# End of methods; subroutines follow. +# FIXME: Ideally these should be in a separate module. + + +#===== PRIVATE SUBROUTINE =================================================== +# Name : internal_error() +# Purpose : output internal error message in a consistent form and die +# Parameters: $message => error message to output +# Returns : n/a +# Throws : n/a +# Comments : none +#============================================================================ +sub internal_error { + my ($format, @args) = @_; + my $error = sprintf($format, @args); + my $stacktrace = Carp::longmess(); + die <. + +=cut + +use strict; +use warnings; + +use POSIX qw(getcwd); + +use base qw(Exporter); +our @EXPORT_OK = qw( + error debug set_debug_level set_test_mode + join_paths parent canon_path restore_cwd +); + +our $ProgramName = 'stow'; +our $VERSION = '2.2.2'; + +############################################################################# +# +# General Utilities: nothing stow specific here. +# +############################################################################# + +=head1 IMPORTABLE SUBROUTINES + +=head2 error($format, @args) + +Outputs an error message in a consistent form and then dies. + +=cut + +sub error { + my ($format, @args) = @_; + die "$ProgramName: ERROR: " . sprintf($format, @args) . "\n"; +} + +=head2 set_debug_level($level) + +Sets verbosity level for C. + +=cut + +our $debug_level = 0; + +sub set_debug_level { + my ($level) = @_; + $debug_level = $level; +} + +=head2 set_test_mode($on_or_off) + +Sets testmode on or off. + +=cut + +our $test_mode = 0; + +sub set_test_mode { + my ($on_or_off) = @_; + if ($on_or_off) { + $test_mode = 1; + } + else { + $test_mode = 0; + } +} + +=head2 debug($level, $msg) + +Logs to STDERR based on C<$debug_level> setting. C<$level> is the +minimum verbosity level required to output C<$msg>. All output is to +STDERR to preserve backward compatibility, except for in test mode, +when STDOUT is used instead. In test mode, the verbosity can be +overridden via the C environment variable. + +Verbosity rules: + +=over 4 + +=item 0: errors only + +=item >= 1: print operations: LINK/UNLINK/MKDIR/RMDIR/MV + +=item >= 2: print operation exceptions + +e.g. "_this_ already points to _that_", skipping, deferring, +overriding, fixing invalid links + +=item >= 3: print trace detail: trace: stow/unstow/package/contents/node + +=item >= 4: debug helper routines + +=item >= 5: debug ignore lists + +=back + +=cut + +sub debug { + my ($level, $msg) = @_; + if ($debug_level >= $level) { + if ($test_mode) { + print "# $msg\n"; + } + else { + warn "$msg\n"; + } + } +} + +#===== METHOD =============================================================== +# Name : join_paths() +# Purpose : concatenates given paths +# Parameters: path1, path2, ... => paths +# Returns : concatenation of given paths +# Throws : n/a +# Comments : factors out redundant path elements: +# : '//' => '/' and 'a/b/../c' => 'a/c' +#============================================================================ +sub join_paths { + my @paths = @_; + + # weed out empty components and concatenate + my $result = join '/', grep {! /\A\z/} @paths; + + # factor out back references and remove redundant /'s) + my @result = (); + PART: + for my $part (split m{/+}, $result) { + next PART if $part eq '.'; + if (@result && $part eq '..' && $result[-1] ne '..') { + pop @result; + } + else { + push @result, $part; + } + } + + return join '/', @result; +} + +#===== METHOD =============================================================== +# Name : parent +# Purpose : find the parent of the given path +# Parameters: @path => components of the path +# Returns : returns a path string +# Throws : n/a +# Comments : allows you to send multiple chunks of the path +# : (this feature is currently not used) +#============================================================================ +sub parent { + my @path = @_; + my $path = join '/', @_; + my @elts = split m{/+}, $path; + pop @elts; + return join '/', @elts; +} + +#===== METHOD =============================================================== +# Name : canon_path +# Purpose : find absolute canonical path of given path +# Parameters: $path +# Returns : absolute canonical path +# Throws : n/a +# Comments : is this significantly different from File::Spec->rel2abs? +#============================================================================ +sub canon_path { + my ($path) = @_; + + my $cwd = getcwd(); + chdir($path) or error("canon_path: cannot chdir to $path from $cwd"); + my $canon_path = getcwd(); + restore_cwd($cwd); + + return $canon_path; +} + +sub restore_cwd { + my ($prev) = @_; + chdir($prev) or error("Your current directory $prev seems to have vanished"); +} + +=head1 BUGS + +=head1 SEE ALSO + +=cut + +1; + +# Local variables: +# mode: perl +# cperl-indent-level: 4 +# end: +# vim: ft=perl