Perform shell expansion on the contents of .stowrc (#40)
Perform shell expansion on the contents of .stowrc
This commit is contained in:
commit
42ed9ed942
10 changed files with 386 additions and 24 deletions
1
Build.PL
1
Build.PL
|
@ -45,6 +45,7 @@ my $build = Module::Build->new(
|
||||||
'perl' => '5.006',
|
'perl' => '5.006',
|
||||||
'Carp' => 0,
|
'Carp' => 0,
|
||||||
'IO::File' => 0,
|
'IO::File' => 0,
|
||||||
|
'Hash::Merge' => 0,
|
||||||
},
|
},
|
||||||
script_files => [ 'bin/stow', 'bin/chkstow' ],
|
script_files => [ 'bin/stow', 'bin/chkstow' ],
|
||||||
all_from => 'lib/Stow.pm.in',
|
all_from => 'lib/Stow.pm.in',
|
||||||
|
|
1
MANIFEST
1
MANIFEST
|
@ -45,6 +45,7 @@ t/ignore.t
|
||||||
t/join_paths.t
|
t/join_paths.t
|
||||||
t/parent.t
|
t/parent.t
|
||||||
t/stow.t
|
t/stow.t
|
||||||
|
t/rc_options.t
|
||||||
t/testutil.pm
|
t/testutil.pm
|
||||||
t/unstow.t
|
t/unstow.t
|
||||||
t/unstow_orig.t
|
t/unstow_orig.t
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
"build" : {
|
"build" : {
|
||||||
"requires" : {
|
"requires" : {
|
||||||
"IO::Scalar" : "0",
|
"IO::Scalar" : "0",
|
||||||
|
"Hash::Merge": "0",
|
||||||
"Test::More" : "0",
|
"Test::More" : "0",
|
||||||
"Test::Output" : "0"
|
"Test::Output" : "0"
|
||||||
}
|
}
|
||||||
|
|
1
META.yml
1
META.yml
|
@ -4,6 +4,7 @@ author:
|
||||||
- unknown
|
- unknown
|
||||||
build_requires:
|
build_requires:
|
||||||
IO::Scalar: '0'
|
IO::Scalar: '0'
|
||||||
|
Hash::Merge: '0'
|
||||||
Test::More: '0'
|
Test::More: '0'
|
||||||
Test::Output: '0'
|
Test::Output: '0'
|
||||||
configure_requires:
|
configure_requires:
|
||||||
|
|
10
NEWS
10
NEWS
|
@ -22,6 +22,16 @@ News file for Stow.
|
||||||
|
|
||||||
Thanks to Joris Vankerschaver for this feature!
|
Thanks to Joris Vankerschaver for this feature!
|
||||||
|
|
||||||
|
*** Shell-like expansion in .stowrc files
|
||||||
|
|
||||||
|
For options within .stowrc files which describe file paths, "~" can
|
||||||
|
be included to expand to the current value of $HOME, and
|
||||||
|
environment variables can be referenced e.g. via "$FOO" or
|
||||||
|
"${FOO}". To prevent expansion, escape with a backslash.
|
||||||
|
|
||||||
|
Thanks a lot to Charles LeDoux for his diligent work on this
|
||||||
|
feature!
|
||||||
|
|
||||||
*** chkstow now honours the $STOW_DIR environment variable
|
*** chkstow now honours the $STOW_DIR environment variable
|
||||||
|
|
||||||
The stow script already honoured the $STOW_DIR environment
|
The stow script already honoured the $STOW_DIR environment
|
||||||
|
|
188
bin/stow.in
188
bin/stow.in
|
@ -343,6 +343,28 @@ Stow will re-fold the tree by removing the symlinks to the surviving
|
||||||
package, removing the directory, then linking the directory back to
|
package, removing the directory, then linking the directory back to
|
||||||
the surviving package.
|
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
|
=head1 SEE ALSO
|
||||||
|
|
||||||
The full documentation for F<stow> is maintained as a Texinfo manual.
|
The full documentation for F<stow> is maintained as a Texinfo manual.
|
||||||
|
@ -432,12 +454,14 @@ use warnings;
|
||||||
require 5.006_001;
|
require 5.006_001;
|
||||||
|
|
||||||
use POSIX qw(getcwd);
|
use POSIX qw(getcwd);
|
||||||
use Getopt::Long;
|
use Getopt::Long qw(GetOptionsFromArray);
|
||||||
|
|
||||||
@USE_LIB_PMDIR@
|
@USE_LIB_PMDIR@
|
||||||
use Stow;
|
use Stow;
|
||||||
use Stow::Util qw(parent error);
|
use Stow::Util qw(parent error);
|
||||||
|
|
||||||
|
use Hash::Merge qw( merge );
|
||||||
|
|
||||||
my $ProgramName = $0;
|
my $ProgramName = $0;
|
||||||
$ProgramName =~ s{.*/}{};
|
$ProgramName =~ s{.*/}{};
|
||||||
|
|
||||||
|
@ -481,23 +505,61 @@ sub main {
|
||||||
|
|
||||||
#===== SUBROUTINE ===========================================================
|
#===== SUBROUTINE ===========================================================
|
||||||
# Name : process_options()
|
# Name : process_options()
|
||||||
# Purpose : parse command line options
|
# Purpose : Parse and process command line and .stowrc file options
|
||||||
# Parameters: none
|
# Parameters: none
|
||||||
# Returns : (\%options, \@pkgs_to_unstow, \@pkgs_to_stow)
|
# 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
|
# Comments : checks @ARGV for valid package names
|
||||||
#============================================================================
|
#============================================================================
|
||||||
sub process_options {
|
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.
|
||||||
|
# rc options come first in merged arrays.
|
||||||
|
# cli options overwrite conflicting rc options.
|
||||||
|
Hash::Merge::set_behavior('RIGHT_PRECEDENT');
|
||||||
|
my $options = merge($rc_options, $cli_options);
|
||||||
|
|
||||||
|
# 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 %options = ();
|
||||||
my @pkgs_to_unstow = ();
|
my @pkgs_to_unstow = ();
|
||||||
my @pkgs_to_stow = ();
|
my @pkgs_to_stow = ();
|
||||||
my $action = 'stow';
|
my $action = 'stow';
|
||||||
|
|
||||||
unshift @ARGV, get_config_file_options();
|
#$,="\n"; print @_,"\n"; # for debugging rc file
|
||||||
#$,="\n"; print @ARGV,"\n"; # for debugging rc file
|
|
||||||
|
|
||||||
Getopt::Long::config('no_ignore_case', 'bundling', 'permute');
|
Getopt::Long::config('no_ignore_case', 'bundling', 'permute');
|
||||||
GetOptions(
|
GetOptionsFromArray(
|
||||||
|
\@_,
|
||||||
\%options,
|
\%options,
|
||||||
'verbose|v:+', 'help|h', 'simulate|n|no',
|
'verbose|v:+', 'help|h', 'simulate|n|no',
|
||||||
'version|V', 'compat|p', 'dir|d=s', 'target|t=s',
|
'version|V', 'compat|p', 'dir|d=s', 'target|t=s',
|
||||||
|
@ -548,12 +610,8 @@ sub process_options {
|
||||||
usage() if $options{help};
|
usage() if $options{help};
|
||||||
version() if $options{version};
|
version() if $options{version};
|
||||||
|
|
||||||
sanitize_path_options(\%options);
|
|
||||||
check_packages(\@pkgs_to_unstow, \@pkgs_to_stow);
|
|
||||||
|
|
||||||
return (\%options, \@pkgs_to_unstow, \@pkgs_to_stow);
|
return (\%options, \@pkgs_to_unstow, \@pkgs_to_stow);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub sanitize_path_options {
|
sub sanitize_path_options {
|
||||||
my ($options) = @_;
|
my ($options) = @_;
|
||||||
|
|
||||||
|
@ -589,22 +647,21 @@ sub check_packages {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#===== SUBROUTINE ============================================================
|
#===== SUBROUTINE ============================================================
|
||||||
# Name : get_config_file_options()
|
# Name : get_config_file_options()
|
||||||
# Purpose : search for default settings in any .stowrc files
|
# Purpose : search for default settings in any .stowrc files
|
||||||
# Parameters: none
|
# Parameters: none
|
||||||
# Returns : a list of default options
|
# Returns : (\%rc_options, \@rc_pkgs_to_unstow, \@rc_pkgs_to_stow)
|
||||||
# Throws : no exceptions
|
# Throws : a fatal error if a bad option is given
|
||||||
# Comments : prepends the contents of '~/.stowrc' and '.stowrc' to the command
|
# Comments : Parses the contents of '~/.stowrc' and '.stowrc' with the same
|
||||||
# : line so they get parsed just like normal arguments. (This was
|
# parser as the command line options. Additionally expands any
|
||||||
# : hacked in so that Emil and I could set different preferences).
|
# environment variables or ~ character in --target or --dir
|
||||||
|
# options.
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
sub get_config_file_options {
|
sub get_config_file_options {
|
||||||
my @defaults = ();
|
my @defaults = ();
|
||||||
for my $file ("$ENV{HOME}/.stowrc", '.stowrc') {
|
for my $file ("$ENV{HOME}/.stowrc", '.stowrc') {
|
||||||
if (-r $file) {
|
if (-r $file) {
|
||||||
warn "Loading defaults from $file\n";
|
|
||||||
open my $FILE, '<', $file
|
open my $FILE, '<', $file
|
||||||
or die "Could not open $file for reading\n";
|
or die "Could not open $file for reading\n";
|
||||||
while (my $line = <$FILE>){
|
while (my $line = <$FILE>){
|
||||||
|
@ -614,9 +671,102 @@ sub get_config_file_options {
|
||||||
close $FILE or die "Could not close open file: $file\n";
|
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 ===========================================================
|
#===== SUBROUTINE ===========================================================
|
||||||
# Name : usage()
|
# Name : usage()
|
||||||
# Purpose : print program usage message and exit
|
# Purpose : print program usage message and exit
|
||||||
|
@ -629,7 +779,7 @@ sub usage {
|
||||||
my ($msg) = @_;
|
my ($msg) = @_;
|
||||||
|
|
||||||
if ($msg) {
|
if ($msg) {
|
||||||
print "$ProgramName: $msg\n\n";
|
warn "$ProgramName: $msg\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
print <<"EOT";
|
print <<"EOT";
|
||||||
|
|
|
@ -881,9 +881,10 @@ directory.
|
||||||
|
|
||||||
Default command line options may be set in @file{.stowrc} (current
|
Default command line options may be set in @file{.stowrc} (current
|
||||||
directory) or @file{~/.stowrc} (home directory). These are parsed in
|
directory) or @file{~/.stowrc} (home directory). These are parsed in
|
||||||
that order, and effectively prepended to the command line arguments
|
that order, and are appended together if they both exist. The effect of
|
||||||
(with the notable difference that they won't be processed by the shell).
|
the options in the resource file is similar to simply prepending the
|
||||||
This feature can be used for some interesting effects.
|
options to the command line. This feature can be used for some
|
||||||
|
interesting effects.
|
||||||
|
|
||||||
For example, suppose your site uses more than one stow directory, perhaps in
|
For example, suppose your site uses more than one stow directory, perhaps in
|
||||||
order to share around responsibilities with a number of systems
|
order to share around responsibilities with a number of systems
|
||||||
|
@ -922,6 +923,22 @@ immediate parent directory @file{/usr/local/stow}), overriding any
|
||||||
pre-existing links to bin files or man pages, and ignoring some cruft
|
pre-existing links to bin files or man pages, and ignoring some cruft
|
||||||
that gets installed by default.
|
that gets installed by default.
|
||||||
|
|
||||||
|
If an option is provided both on the command line and in a resource file,
|
||||||
|
the command line option takes precedence. For options that provide a single
|
||||||
|
value, such as @command{--target} or @command{--dir}, the command line
|
||||||
|
option will overwrite any options in the resource file. For options that can
|
||||||
|
be given more than once, @command{--ignore} for example, command line
|
||||||
|
options and resource options are appended together.
|
||||||
|
|
||||||
|
For options that take a file path, environment variables and the tilde
|
||||||
|
character (@command{~}) are expanded. An environment variable can be
|
||||||
|
given in either the @command{$VAR} or @command{$@{VAR@}} form. To
|
||||||
|
prevent expansion, escape the @command{$} or @command{~} with a
|
||||||
|
backslash.
|
||||||
|
|
||||||
|
The options @command{-D}, @command{-S}, and @command{-R} are ignored in
|
||||||
|
resource files. This is also true of any package names given in the
|
||||||
|
resource file.
|
||||||
|
|
||||||
@c ===========================================================================
|
@c ===========================================================================
|
||||||
@node Compile-time vs Install-time, Bootstrapping, Resource Files, Top
|
@node Compile-time vs Install-time, Bootstrapping, Resource Files, Top
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Test::More tests => 9;
|
use Test::More tests => 10;
|
||||||
|
|
||||||
use testutil;
|
use testutil;
|
||||||
|
|
||||||
|
@ -82,5 +82,16 @@ local @ARGV = (
|
||||||
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
|
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
|
||||||
is_deeply($options->{ignore}, [ qr(~\z), qr(\.#.*\z) ] => 'ignore temp files');
|
is_deeply($options->{ignore}, [ qr(~\z), qr(\.#.*\z) ] => 'ignore temp files');
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check that expansion not applied.
|
||||||
|
#
|
||||||
|
local @ARGV = (
|
||||||
|
"--target=$OUT_DIR/".'$HOME',
|
||||||
|
'dummy'
|
||||||
|
);
|
||||||
|
make_dir("$OUT_DIR/".'$HOME');
|
||||||
|
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
|
||||||
|
is($options->{target}, "$OUT_DIR/".'$HOME', 'no expansion');
|
||||||
|
remove_dir("$OUT_DIR/".'$HOME');
|
||||||
|
|
||||||
# vim:ft=perl
|
# vim:ft=perl
|
||||||
|
|
170
t/rc_options.t
Executable file
170
t/rc_options.t
Executable file
|
@ -0,0 +1,170 @@
|
||||||
|
#!/usr/local/bin/perl
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test processing of stowrc file.
|
||||||
|
#
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use Test::More tests => 23;
|
||||||
|
|
||||||
|
use testutil;
|
||||||
|
|
||||||
|
require 'stow';
|
||||||
|
|
||||||
|
# stowrc file used for testing.
|
||||||
|
my $RC_FILE = "$OUT_DIR/.stowrc";
|
||||||
|
# Take the safe route and cowardly refuse to continue if there's
|
||||||
|
# already a file at $RC_FILE.
|
||||||
|
if (-e $RC_FILE) {
|
||||||
|
die "RC file location $RC_FILE already exists!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Define the variable that will be used to write stowrc.
|
||||||
|
my $rc_contents;
|
||||||
|
|
||||||
|
# Init testing directory structure and overwrite ENV{HOME} to prevent
|
||||||
|
# squashing existing stowrc file.
|
||||||
|
init_test_dirs();
|
||||||
|
|
||||||
|
# =========== RC Loading Tests ===========
|
||||||
|
# Basic parsing and loading rc file tests.
|
||||||
|
# ========================================
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test stowrc file with one options per line.
|
||||||
|
#
|
||||||
|
local @ARGV = ('dummy');
|
||||||
|
$rc_contents = <<HERE;
|
||||||
|
-d $OUT_DIR/stow
|
||||||
|
--target $OUT_DIR/target
|
||||||
|
HERE
|
||||||
|
make_file($RC_FILE, $rc_contents);
|
||||||
|
my ($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
|
||||||
|
is($options->{target}, "$OUT_DIR/target", "rc options different lines");
|
||||||
|
is($options->{dir}, "$OUT_DIR/stow", "rc options different lines");
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test that scalar cli option overwrites conflicting stowrc option.
|
||||||
|
#
|
||||||
|
local @ARGV = ('-d', "$OUT_DIR/stow",'dummy');
|
||||||
|
$rc_contents = <<HERE;
|
||||||
|
-d bad/path
|
||||||
|
HERE
|
||||||
|
make_file($RC_FILE, $rc_contents);
|
||||||
|
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
|
||||||
|
is($options->{dir}, "$OUT_DIR/stow", "cli overwrite scalar rc option.");
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test that list cli option merges with conflicting stowrc option.
|
||||||
|
# Documentation states that stowrc options are prepended to cli options.
|
||||||
|
#
|
||||||
|
local @ARGV = (
|
||||||
|
'--defer=man',
|
||||||
|
'dummy'
|
||||||
|
);
|
||||||
|
$rc_contents = <<HERE;
|
||||||
|
--defer=info
|
||||||
|
HERE
|
||||||
|
make_file($RC_FILE, $rc_contents);
|
||||||
|
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
|
||||||
|
is_deeply($options->{defer}, [qr(\Ainfo), qr(\Aman)],
|
||||||
|
'defer man and info');
|
||||||
|
|
||||||
|
# ======== Filepath Expansion Tests ========
|
||||||
|
# Test proper filepath expansion in rc file.
|
||||||
|
# Expansion is only applied to options that
|
||||||
|
# take a filepath, namely target and dir.
|
||||||
|
# ==========================================
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test environment variable expansion function.
|
||||||
|
#
|
||||||
|
# Basic expansion
|
||||||
|
is(expand_environment('$HOME/stow'), "$OUT_DIR/stow", 'expand $HOME');
|
||||||
|
is(expand_environment('${HOME}/stow'), "$OUT_DIR/stow", 'expand ${HOME}');
|
||||||
|
|
||||||
|
delete $ENV{UNDEFINED}; # just in case
|
||||||
|
foreach my $var ('$UNDEFINED', '${UNDEFINED}') {
|
||||||
|
eval {
|
||||||
|
expand_environment($var, "--foo option");
|
||||||
|
};
|
||||||
|
is(
|
||||||
|
$@,
|
||||||
|
"--foo option references undefined environment variable \$UNDEFINED; " .
|
||||||
|
"aborting!\n",
|
||||||
|
"expand $var"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Expansion with an underscore.
|
||||||
|
$ENV{'WITH_UNDERSCORE'} = 'test string';
|
||||||
|
is(expand_environment('${WITH_UNDERSCORE}'), 'test string',
|
||||||
|
'expand ${WITH_UNDERSCORE}');
|
||||||
|
delete $ENV{'WITH_UNDERSCORE'};
|
||||||
|
# Expansion with escaped $
|
||||||
|
is(expand_environment('\$HOME/stow'), '$HOME/stow', 'expand \$HOME');
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test tilde (~) expansion
|
||||||
|
#
|
||||||
|
# Basic expansion
|
||||||
|
is(expand_tilde('~/path'), "$ENV{HOME}/path", 'tilde expansion to $HOME');
|
||||||
|
# Should not expand if middle of path
|
||||||
|
is(expand_tilde('/path/~/here'), '/path/~/here', 'middle ~ not expanded');
|
||||||
|
# Test escaped ~
|
||||||
|
is(expand_tilde('\~/path'), '~/path', 'escaped tilde');
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test that environment variable expansion is applied.
|
||||||
|
#
|
||||||
|
$rc_contents = <<'HERE';
|
||||||
|
--dir=$HOME/stow
|
||||||
|
--target=$HOME/stow
|
||||||
|
--ignore=\$HOME
|
||||||
|
--defer=\$HOME
|
||||||
|
--override=\$HOME
|
||||||
|
HERE
|
||||||
|
make_file($RC_FILE, $rc_contents);
|
||||||
|
($options, $pkgs_to_delete, $pkgs_to_stow) = get_config_file_options();
|
||||||
|
is($options->{dir}, "$OUT_DIR/stow",
|
||||||
|
"apply environment expansion on stowrc --dir");
|
||||||
|
is($options->{target}, "$OUT_DIR/stow",
|
||||||
|
"apply environment expansion on stowrc --target");
|
||||||
|
is_deeply($options->{ignore}, [qr(\$HOME\z)],
|
||||||
|
"environment expansion not applied on --ignore");
|
||||||
|
is_deeply($options->{defer}, [qr(\A\$HOME)],
|
||||||
|
"environment expansion not applied on --defer");
|
||||||
|
is_deeply($options->{override}, [qr(\A\$HOME)],
|
||||||
|
"environment expansion not applied on --override");
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test that tilde expansion is applied in correct places.
|
||||||
|
#
|
||||||
|
$rc_contents = <<'HERE';
|
||||||
|
--dir=~/stow
|
||||||
|
--target=~/stow
|
||||||
|
--ignore=~/stow
|
||||||
|
--defer=~/stow
|
||||||
|
--override=~/stow
|
||||||
|
HERE
|
||||||
|
make_file($RC_FILE, $rc_contents);
|
||||||
|
($options, $pkgs_to_delete, $pkgs_to_stow) = get_config_file_options();
|
||||||
|
is($options->{dir}, "$OUT_DIR/stow",
|
||||||
|
"apply environment expansion on stowrc --dir");
|
||||||
|
is($options->{target}, "$OUT_DIR/stow",
|
||||||
|
"apply environment expansion on stowrc --target");
|
||||||
|
is_deeply($options->{ignore}, [qr(~/stow\z)],
|
||||||
|
"environment expansion not applied on --ignore");
|
||||||
|
is_deeply($options->{defer}, [qr(\A~/stow)],
|
||||||
|
"environment expansion not applied on --defer");
|
||||||
|
is_deeply($options->{override}, [qr(\A~/stow)],
|
||||||
|
"environment expansion not applied on --override");
|
||||||
|
|
||||||
|
# Clean up files used for testing.
|
||||||
|
#
|
||||||
|
unlink $RC_FILE or die "Unable to clean up $RC_FILE.\n";
|
||||||
|
remove_dir($OUT_DIR);
|
||||||
|
|
|
@ -55,7 +55,7 @@ sub init_test_dirs {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Don't let user's ~/.stow-global-ignore affect test results
|
# Don't let user's ~/.stow-global-ignore affect test results
|
||||||
$ENV{HOME} = '/tmp/fake/home';
|
$ENV{HOME} = $OUT_DIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub new_Stow {
|
sub new_Stow {
|
||||||
|
|
Loading…
Reference in a new issue