Skip to content

Commit

Permalink
Fix parsing of regexp options like --override=bin|man
Browse files Browse the repository at this point in the history
Previously the \A and \z anchoring for --ignore / --override / --defer
was being applied without wrapping the user-specified regexp in
parentheses, so if it was something like bin|man then the anchor would
only apply to one half of those two paths.  So add parentheses, and
also change from qr() to qr{} syntax to visually differentiate between
regexp boundaries and parentheses inside the regexp.
  • Loading branch information
aspiers committed Jun 15, 2024
1 parent d760f96 commit f0ec80f
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 15 deletions.
6 changes: 3 additions & 3 deletions bin/stow.in
Original file line number Diff line number Diff line change
Expand Up @@ -582,19 +582,19 @@ sub parse_options {
'ignore=s' =>
sub {
my $regex = $_[1];
push @{$options{ignore}}, qr($regex\z);
push @{$options{ignore}}, qr{($regex)\z};
},

'override=s' =>
sub {
my $regex = $_[1];
push @{$options{override}}, qr(\A$regex);
push @{$options{override}}, qr{\A($regex)};
},

'defer=s' =>
sub {
my $regex = $_[1];
push @{$options{defer}}, qr(\A$regex);
push @{$options{defer}}, qr{\A($regex)};
},

# a little craziness so we can do different actions on the same line:
Expand Down
6 changes: 3 additions & 3 deletions t/cli_options.t
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ local @ARGV = (
'dummy'
);
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is_deeply($options->{defer}, [ qr(\Aman), qr(\Ainfo) ] => 'defer man and info');
is_deeply($options->{defer}, [ qr{\A(man)}, qr{\A(info)} ] => 'defer man and info');

#
# Check setting override paths
Expand All @@ -84,7 +84,7 @@ local @ARGV = (
'dummy'
);
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is_deeply($options->{override}, [qr(\Aman), qr(\Ainfo)] => 'override man and info');
is_deeply($options->{override}, [qr{\A(man)}, qr{\A(info)}] => 'override man and info');

#
# Check setting ignored paths
Expand All @@ -95,7 +95,7 @@ local @ARGV = (
'dummy'
);
($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.
Expand Down
24 changes: 15 additions & 9 deletions t/rc_options.t
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ is($options->{target}, "$ABS_TEST_DIR/target"
=> "--target overridden by \$PWD/.stowrc");
is($options->{dir}, "$ABS_TEST_DIR/stow"
=> "-d overridden \$PWD/.stowrc");
is_deeply($options->{defer}, [qr(\Ainfo), qr(\Aman)],
is_deeply($options->{defer}, [qr{\A(info)}, qr{\A(man)}],
'defer man and info');
unlink($CWD_RC_FILE) or die "Failed to unlink $CWD_RC_FILE";

Expand All @@ -179,7 +179,7 @@ make_file($HOME_RC_FILE, <<HERE);
--defer=info
HERE
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is_deeply($options->{defer}, [qr(\Ainfo), qr(\Aman)],
is_deeply($options->{defer}, [qr{\A(info)}, qr{\A(man)}],
'defer man and info');

# ======== Filepath Expansion Tests ========
Expand Down Expand Up @@ -229,24 +229,30 @@ is(expand_tilde('\~/path'), '~/path', 'escaped tilde');

#
# Test that environment variable expansion is applied unless quoted.
# Include examples from the manual
#
make_file($HOME_RC_FILE, <<'HERE');
--dir=$HOME/stow
--target="$HOME/dir with space in/file with space in"
--ignore=\\$FOO\\$
--defer="foo\\b.*bar"
--defer="\\.jpg\$"
--override=\\.jpg\$
--override=\\.png\$
--override=bin|man
--ignore='perllocal\.pod'
--ignore='\.packlist'
--ignore='\.bs'
HERE
($options, $pkgs_to_delete, $pkgs_to_stow) = get_config_file_options();
is($options->{dir}, "$ABS_TEST_DIR/stow",
"apply environment expansion on --dir");
is($options->{target}, "$ABS_TEST_DIR/dir with space in/file with space in",
"apply environment expansion on --target");
is_deeply($options->{ignore}, [qr(\$FOO\$\z)],
is_deeply($options->{ignore}, [qr{(\$FOO\$)\z}, qr{(perllocal\.pod)\z}, qr{(\.packlist)\z}, qr{(\.bs)\z}],
'environment expansion not applied on --ignore but backslash removed');
is_deeply($options->{defer}, [qr(\A\.jpg$)],
is_deeply($options->{defer}, [qr{\A(foo\b.*bar)}, qr{\A(\.jpg$)}],
'environment expansion not applied on --defer but backslash removed');
is_deeply($options->{override}, [qr(\A\.jpg$)],
is_deeply($options->{override}, [qr{\A(\.png$)}, qr{\A(bin|man)}],
'environment expansion not applied on --override but backslash removed');

#
Expand All @@ -264,11 +270,11 @@ is($options->{dir}, "$ABS_TEST_DIR/stow",
"apply tilde expansion on \$HOME/.stowrc --dir");
is($options->{target}, "$ABS_TEST_DIR/stow",
"apply tilde expansion on \$HOME/.stowrc --target");
is_deeply($options->{ignore}, [qr(~/stow\z)],
is_deeply($options->{ignore}, [qr{(~/stow)\z}],
"tilde expansion not applied on --ignore");
is_deeply($options->{defer}, [qr(\A~/stow)],
is_deeply($options->{defer}, [qr{\A(~/stow)}],
"tilde expansion not applied on --defer");
is_deeply($options->{override}, [qr(\A~/stow)],
is_deeply($options->{override}, [qr{\A(~/stow)}],
"tilde expansion not applied on --override");

#
Expand Down

0 comments on commit f0ec80f

Please sign in to comment.