Rebuild stow based on v2.3.2-fixbug56727
This commit is contained in:
parent
d7da96382f
commit
23daff4a9f
42 changed files with 8741 additions and 5290 deletions
|
@ -1,4 +1,19 @@
|
|||
#!/usr/bin/perl
|
||||
#!/usr/local/bin/perl
|
||||
#
|
||||
# This file is part of GNU Stow.
|
||||
#
|
||||
# GNU Stow 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 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# GNU Stow 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 https://www.gnu.org/licenses/.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
@ -8,7 +23,7 @@ require 5.006_001;
|
|||
use File::Find;
|
||||
use Getopt::Long;
|
||||
|
||||
my $DEFAULT_TARGET = '/usr/local/';
|
||||
my $DEFAULT_TARGET = $ENV{STOW_DIR} || '/usr/local/';
|
||||
|
||||
our $Wanted = \&bad_links;
|
||||
our %Package = ();
|
||||
|
@ -93,7 +108,7 @@ sub aliens {
|
|||
!-l && !-d && print "Unstowed file: $File::Find::name\n";
|
||||
}
|
||||
|
||||
# just list the packages in the the target directory
|
||||
# just list the packages in the target directory
|
||||
# FIXME: what if the stow dir is not called 'stow'?
|
||||
sub list {
|
||||
if (-l) {
|
||||
|
|
323
local/bin/stow
323
local/bin/stow
|
@ -1,27 +1,29 @@
|
|||
#!/usr/bin/perl
|
||||
#!/usr/local/bin/perl
|
||||
|
||||
# GNU Stow - manage the installation of multiple software packages
|
||||
# GNU Stow - manage farms of symbolic links
|
||||
# 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
|
||||
# This file is part of GNU Stow.
|
||||
#
|
||||
# GNU Stow 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 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# GNU Stow 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
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
# along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
=head1 NAME
|
||||
|
||||
stow - software package installation manager
|
||||
stow - manage farms of symbolic links
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
@ -29,33 +31,34 @@ 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.
|
||||
This manual page describes GNU Stow 2.3.2-fixbug56727. This is not the
|
||||
definitive documentation for Stow; for that, see the accompanying info
|
||||
manual, e.g. by typing C<info stow>.
|
||||
|
||||
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</usr/local>. When one
|
||||
does so, one winds up (as of Perl 4.036 and Emacs 19.22) with the
|
||||
following files in F</usr/local/man/man1>: F<a2p.1>; F<ctags.1>;
|
||||
F<emacs.1>; F<etags.1>; F<h2ph.1>; F<perl.1>; and F<s2p.1>. Now
|
||||
suppose it's time to uninstall Perl. Which man pages get removed?
|
||||
Obviously F<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.
|
||||
Stow is a symlink farm manager which takes distinct sets of software
|
||||
and/or data located in separate directories on the filesystem, and
|
||||
makes them all appear to be installed in a single directory tree.
|
||||
|
||||
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<bin>
|
||||
directory containing executables, a F<man/man1> directory containing
|
||||
section 1 man pages, and so on.
|
||||
Originally Stow was born to address the need to administer, upgrade,
|
||||
install, and remove files in independent software packages without
|
||||
confusing them with other files sharing the same file system space.
|
||||
For instance, many years ago it used to be common to compile programs
|
||||
such as Perl and Emacs from source. By using Stow, F</usr/local/bin>
|
||||
could contain symlinks to files within F</usr/local/stow/emacs/bin>,
|
||||
F</usr/local/stow/perl/bin> etc., and likewise recursively for any
|
||||
other subdirectories such as F<.../share>, F<.../man>, and so on.
|
||||
|
||||
While this is useful for keeping track of system-wide and per-user
|
||||
installations of software built from source, in more recent times
|
||||
software packages are often managed by more sophisticated package
|
||||
management software such as rpm, dpkg, and Nix / GNU Guix, or
|
||||
language-native package managers such as Ruby's gem, Python's pip,
|
||||
Javascript's npm, and so on.
|
||||
|
||||
However Stow is still used not only for software package management,
|
||||
but also for other purposes, such as facilitating a more controlled
|
||||
approach to management of configuration files in the user's home
|
||||
directory, especially when coupled with version control systems.
|
||||
|
||||
Stow was inspired by Carnegie Mellon's Depot program, but is
|
||||
substantially simpler and safer. Whereas Depot required database files
|
||||
|
@ -66,6 +69,9 @@ will never delete any files, directories, or links that appear in a
|
|||
Stow directory (e.g., F</usr/local/stow/emacs>), so it's always
|
||||
possible to rebuild the target tree (e.g., F</usr/local>).
|
||||
|
||||
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.
|
||||
|
||||
=head1 TERMINOLOGY
|
||||
|
||||
A "package" is a related collection of files and directories that
|
||||
|
@ -129,6 +135,8 @@ C<-D>).
|
|||
|
||||
=item --no
|
||||
|
||||
=item --simulate
|
||||
|
||||
Do not perform any operations that modify the filesystem; merely show
|
||||
what would happen.
|
||||
|
||||
|
@ -152,7 +160,7 @@ directory.
|
|||
=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.
|
||||
doing. Verbosity levels are from 0 to 5; 0 is the default.
|
||||
Using C<-v> or C<--verbose> increases the verbosity by one; using
|
||||
`--verbose=N' sets it to N.
|
||||
|
||||
|
@ -214,6 +222,22 @@ stowed to another package.
|
|||
Force stowing files beginning with this Perl regex if the file is
|
||||
already stowed to another package.
|
||||
|
||||
=item --dotfiles
|
||||
|
||||
Enable special handling for "dotfiles" (files or folders whose name
|
||||
begins with a period) in the package directory. If this option is
|
||||
enabled, Stow will add a preprocessing step for each file or folder
|
||||
whose name begins with "dot-", and replace the "dot-" prefix in the
|
||||
name by a period (.). This is useful when Stow is used to manage
|
||||
collections of dotfiles, to avoid having a package directory full of
|
||||
hidden files.
|
||||
|
||||
For example, suppose we have a package containing two files,
|
||||
F<stow/dot-bashrc> and F<stow/dot-emacs.d/init.el>. With this option,
|
||||
Stow will create symlinks from F<.bashrc> to F<stow/dot-bashrc> and
|
||||
from F<.emacs.d/init.el> to F<stow/dot-emacs.d/init.el>. Any other
|
||||
files, whose name does not begin with "dot-", will be processed as usual.
|
||||
|
||||
=item -V
|
||||
|
||||
=item --version
|
||||
|
@ -323,6 +347,28 @@ 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 RESOURCE FILES
|
||||
|
||||
F<Stow> searches for default command line options at F<.stowrc> (current
|
||||
directory) and F<~/.stowrc> (home directory) in that order. If both
|
||||
locations are present, the files are effectively appended together.
|
||||
|
||||
The effect of options in the resource file is similar to simply prepending
|
||||
the options to the command line. For options that provide a single value,
|
||||
such as F<--target> or F<--dir>, the command line option will overwrite any
|
||||
options in the resource file. For options that can be given more than once,
|
||||
F<--ignore> for example, command line options and resource options are
|
||||
appended together.
|
||||
|
||||
Environment variables and the tilde character (F<~>) will be expanded for
|
||||
options that take a file path.
|
||||
|
||||
The options F<-D>, F<-R>, F<-S>, and any packages listed in the resource
|
||||
file are ignored.
|
||||
|
||||
See the info manual for more information on how stow handles resource
|
||||
file.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
The full documentation for F<stow> is maintained as a Texinfo manual.
|
||||
|
@ -412,11 +458,10 @@ use warnings;
|
|||
require 5.006_001;
|
||||
|
||||
use POSIX qw(getcwd);
|
||||
use Getopt::Long;
|
||||
use Getopt::Long qw(GetOptionsFromArray);
|
||||
use Scalar::Util qw(reftype);
|
||||
|
||||
use Cwd qw(abs_path);
|
||||
use File::Basename qw(dirname);
|
||||
use lib dirname(dirname(abs_path($0))) . '/share/perl';
|
||||
use FindBin; use lib "$FindBin::Bin/../lib/perl";
|
||||
use Stow;
|
||||
use Stow::Util qw(parent error);
|
||||
|
||||
|
@ -463,27 +508,75 @@ sub main {
|
|||
|
||||
#===== SUBROUTINE ===========================================================
|
||||
# Name : process_options()
|
||||
# Purpose : parse command line options
|
||||
# Purpose : Parse and process command line and .stowrc file options
|
||||
# Parameters: none
|
||||
# Returns : (\%options, \@pkgs_to_unstow, \@pkgs_to_stow)
|
||||
# Throws : a fatal error if a bad command line option is given
|
||||
# Throws : a fatal error if a bad option is given
|
||||
# Comments : checks @ARGV for valid package names
|
||||
#============================================================================
|
||||
sub process_options {
|
||||
# Get cli options.
|
||||
my ($cli_options,
|
||||
$pkgs_to_unstow,
|
||||
$pkgs_to_stow) = parse_options(@ARGV);
|
||||
|
||||
# Get the .stowrc options.
|
||||
# Note that rc_pkgs_to_unstow and rc_pkgs_to_stow are ignored.
|
||||
my ($rc_options,
|
||||
$rc_pkgs_to_unstow,
|
||||
$rc_pkgs_to_stow) = get_config_file_options();
|
||||
|
||||
# Merge .stowrc and command line options.
|
||||
# Preference is given to cli options.
|
||||
my %options = %$rc_options;
|
||||
foreach my $option (keys %$cli_options) {
|
||||
my $rc_value = $rc_options->{$option};
|
||||
my $cli_value = $cli_options->{$option};
|
||||
my $type = reftype($cli_value);
|
||||
|
||||
if (defined $type && $type eq 'ARRAY' && defined $rc_value) {
|
||||
# rc options come first in merged arrays.
|
||||
$options{$option} = [@{$rc_value}, @{$cli_value}];
|
||||
} else {
|
||||
# cli options overwrite conflicting rc options.
|
||||
$options{$option} = $cli_value;
|
||||
}
|
||||
}
|
||||
|
||||
# Run checks on the merged options.
|
||||
sanitize_path_options(\%options);
|
||||
check_packages($pkgs_to_unstow, $pkgs_to_stow);
|
||||
|
||||
# Return merged and processed options.
|
||||
return (\%options, $pkgs_to_unstow, $pkgs_to_stow);
|
||||
}
|
||||
|
||||
#===== SUBROUTINE ===========================================================
|
||||
# Name : parse_options()
|
||||
# Purpose : parse command line options
|
||||
# Parameters: @arg_array => array of options to parse
|
||||
# Example: parse_options(@ARGV)
|
||||
# Returns : (\%options, \@pkgs_to_unstow, \@pkgs_to_stow)
|
||||
# Throws : a fatal error if a bad command line option is given
|
||||
# Comments : Used for parsing both command line options and rc file. Used
|
||||
# for parsing only. Sanity checks and post-processing belong in
|
||||
# process_options().
|
||||
#============================================================================
|
||||
sub parse_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
|
||||
#$,="\n"; print @_,"\n"; # for debugging rc file
|
||||
|
||||
Getopt::Long::config('no_ignore_case', 'bundling', 'permute');
|
||||
GetOptions(
|
||||
GetOptionsFromArray(
|
||||
\@_,
|
||||
\%options,
|
||||
'verbose|v:+', 'help|h', 'simulate|n|no',
|
||||
'version|V', 'compat|p', 'dir|d=s', 'target|t=s',
|
||||
'adopt', 'no-folding',
|
||||
'adopt', 'no-folding', 'dotfiles',
|
||||
|
||||
# clean and pre-compile any regex's at parse time
|
||||
'ignore=s' =>
|
||||
|
@ -525,31 +618,27 @@ sub process_options {
|
|||
push @pkgs_to_stow, $_[0];
|
||||
}
|
||||
},
|
||||
) or usage();
|
||||
) 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();
|
||||
unless (exists $options->{dir}) {
|
||||
$options->{dir} = length $ENV{STOW_DIR} ? $ENV{STOW_DIR} : getcwd();
|
||||
}
|
||||
|
||||
usage("--dir value '$options->{dir}' is not a valid directory")
|
||||
unless -d $options->{dir};
|
||||
|
||||
if (exists $options->{target}) {
|
||||
$options->{target} =~ s/\A +//;
|
||||
$options->{target} =~ s/ +\z//;
|
||||
usage("--target value '$options->{target}' is not a valid directory")
|
||||
unless -d $options->{target};
|
||||
}
|
||||
else {
|
||||
$options->{target} = parent($options->{dir}) || '.';
|
||||
|
@ -572,22 +661,25 @@ sub check_packages {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#===== 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).
|
||||
# Returns : (\%rc_options, \@rc_pkgs_to_unstow, \@rc_pkgs_to_stow)
|
||||
# Throws : a fatal error if a bad option is given
|
||||
# Comments : Parses the contents of '~/.stowrc' and '.stowrc' with the same
|
||||
# parser as the command line options. Additionally expands any
|
||||
# environment variables or ~ character in --target or --dir
|
||||
# options.
|
||||
#=============================================================================
|
||||
sub get_config_file_options {
|
||||
my @defaults = ();
|
||||
for my $file ("$ENV{HOME}/.stowrc", '.stowrc') {
|
||||
my @dirlist = ('.stowrc');
|
||||
if (defined($ENV{HOME})) {
|
||||
unshift(@dirlist, "$ENV{HOME}/.stowrc");
|
||||
}
|
||||
for my $file (@dirlist) {
|
||||
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>){
|
||||
|
@ -597,9 +689,102 @@ sub get_config_file_options {
|
|||
close $FILE or die "Could not close open file: $file\n";
|
||||
}
|
||||
}
|
||||
return @defaults;
|
||||
|
||||
# Parse the options
|
||||
my ($rc_options, $rc_pkgs_to_unstow, $rc_pkgs_to_stow) = parse_options(@defaults);
|
||||
|
||||
# Expand environment variables and glob characters.
|
||||
if (exists $rc_options->{target}) {
|
||||
$rc_options->{target} =
|
||||
expand_filepath($rc_options->{target}, '--target option');
|
||||
}
|
||||
if (exists $rc_options->{dir}) {
|
||||
$rc_options->{dir} =
|
||||
expand_filepath($rc_options->{dir}, '--dir option');
|
||||
}
|
||||
|
||||
return ($rc_options, $rc_pkgs_to_unstow, $rc_pkgs_to_stow);
|
||||
}
|
||||
|
||||
#===== SUBROUTINE ============================================================
|
||||
# Name : expand_filepath()
|
||||
# Purpose : Handles expansions that need to be applied to
|
||||
# : file paths. Currently expands environment
|
||||
# : variables and the tilde.
|
||||
# Parameters: $path => string to perform expansion on.
|
||||
# : $source => where the string came from
|
||||
# Returns : String with replacements performed.
|
||||
# Throws : n/a
|
||||
# Comments : n/a
|
||||
#=============================================================================
|
||||
sub expand_filepath {
|
||||
my ($path, $source) = @_;
|
||||
|
||||
$path = expand_environment($path, $source);
|
||||
$path = expand_tilde($path);
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
#===== SUBROUTINE ============================================================
|
||||
# Name : expand_environment()
|
||||
# Purpose : Expands evironment variables.
|
||||
# Parameters: $path => string to perform expansion on.
|
||||
# : $source => where the string came from
|
||||
# Returns : String with replacements performed.
|
||||
# Throws : n/a
|
||||
# Comments : Variable replacement mostly based on SO answer
|
||||
# : http://stackoverflow.com/a/24675093/558820
|
||||
#=============================================================================
|
||||
sub expand_environment {
|
||||
my ($path, $source) = @_;
|
||||
# Replace non-escaped $VAR and ${VAR} with $ENV{VAR}
|
||||
# If $ENV{VAR} does not exist, perl will raise a warning
|
||||
# and then happily treat it as an empty string.
|
||||
$path =~ s/(?<!\\)\$\{((?:\w|\s)+)\}/
|
||||
_safe_expand_env_var($1, $source)
|
||||
/ge;
|
||||
$path =~ s/(?<!\\)\$(\w+)/
|
||||
_safe_expand_env_var($1, $source)
|
||||
/ge;
|
||||
# Remove \$ escapes.
|
||||
$path =~ s/\\\$/\$/g;
|
||||
return $path;
|
||||
}
|
||||
|
||||
sub _safe_expand_env_var {
|
||||
my ($var, $source) = @_;
|
||||
unless (exists $ENV{$var}) {
|
||||
die "$source references undefined environment variable \$$var; " .
|
||||
"aborting!\n";
|
||||
}
|
||||
return $ENV{$var};
|
||||
}
|
||||
|
||||
#===== SUBROUTINE ============================================================
|
||||
# Name : expand_tilde()
|
||||
# Purpose : Expands tilde to user's home directory path.
|
||||
# Parameters: $path => string to perform expansion on.
|
||||
# Returns : String with replacements performed.
|
||||
# Throws : n/a
|
||||
# Comments : http://docstore.mik.ua/orelly/perl4/cook/ch07_04.htm
|
||||
#=============================================================================
|
||||
sub expand_tilde {
|
||||
my ($path) = @_;
|
||||
# Replace tilde with home path.
|
||||
$path =~ s{ ^ ~ ( [^/]* ) }
|
||||
{ $1
|
||||
? (getpwnam($1))[7]
|
||||
: ( $ENV{HOME} || $ENV{LOGDIR}
|
||||
|| (getpwuid($<))[7]
|
||||
)
|
||||
}ex;
|
||||
# Replace espaced tilde with regular tilde.
|
||||
$path =~ s/\\~/~/g;
|
||||
return $path
|
||||
}
|
||||
|
||||
|
||||
#===== SUBROUTINE ===========================================================
|
||||
# Name : usage()
|
||||
# Purpose : print program usage message and exit
|
||||
|
@ -612,7 +797,7 @@ sub usage {
|
|||
my ($msg) = @_;
|
||||
|
||||
if ($msg) {
|
||||
print "$ProgramName: $msg\n\n";
|
||||
warn "$ProgramName: $msg\n\n";
|
||||
}
|
||||
|
||||
print <<"EOT";
|
||||
|
@ -638,10 +823,12 @@ OPTIONS:
|
|||
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.
|
||||
--dotfiles Enables special handling for dotfiles that are
|
||||
Stow packages that start with "dot-" and not "."
|
||||
-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, --verbose[=N] Increase verbosity (levels are from 0 to 5;
|
||||
-v or --verbose adds 1; --verbose=N sets level)
|
||||
-V, --version Show stow version number
|
||||
-h, --help Show this help
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue