stow 2.3.0 added external runtime dependencies on Hash::Merge and
Clone::Choose. Historically stow hasn't had runtime dependencies other
than Perl itself, which is a useful property if you're managing the
installation of Perl using stow; the bootstrapping instructions in
stow's manual would need updating to describe how to install these two
modules (and any dependencies they have now or in the future) as well.
However, Hash::Merge is much more general than stow actually needs, so
replace the merge() call with a few lines of equivalent code -- this
avoids the external dependencies, and is clearer than the merge()
call.
Many thanks to Adam Sampson for this patch:
https://lists.gnu.org/archive/html/bug-stow/2019-06/msg00001.html
.stowrc can be obtained from $HOME and/or the current working
directory; however only the $HOME case was tested before, because
during tests Stow was being run from $HOME.
So switch $TEST_DIR to an absolute path, create a new run_from/
subdirectory, and chdir to that before invoking any Stow code. This
allows us to test the behaviour of .stowrc in $HOME and run_from/
separately.
Add a new expand_tilde() function that performs tilde expansion of
strings, and corresponding unit tests:
* A ~ at the beginning of a path is expanded to the user's home
directory.
* Literal '~' can be provided with '\~'
Combine this with expand_environment() in a new expand_filepath()
function which applies all (both) required expansion functions to a
string, and use that in get_config_file_options() to expand .stowrc
options.
Add more tests to check that tilde expanded in correct places, i.e.:
* expanded for --target and --dir
* not expanded for --ignore, --defer, or --override
Update documentation on stowrc files according to this functionality
change.
Fixes#14: https://github.com/aspiers/stow/issues/14
Expand environment variables used in stowrc, as requested in
https://savannah.gnu.org/bugs/?41826
This is achieved by creating a new function expand_environment() that
replaces any substring of the form '$VAR' or '${VAR}' with contents of
environment variable $VAR. Literal '$' can be given by '\$'.
N.B. The function is only applied to the --target and --dir options,
and only for options specified in .stowrc; cli options are left
untouched.
Undefined variables are expanded to the empty string, as they would be
in normal shell parameter expansion.
Unit tests added accordingly:
- Test expand_environment():
* Expand $HOME
* Expand ${HOME}
* Expand ${WITH SPACE}
* Expand '\$HOME'. Expected is '$HOME'
* Expand ${UNDEFINED}. Expected is ''.
- Test that it's applied to the correct options.
- Test that CLI options are not expanded.
Why:
* We want to selectively apply expansion to:
* Only options from stowrc files.
* Only options that take a path.
* This requires ability to:
* Differentiate cli options from stowrc options
* Distinguish between individual stowrc options.
This change addresses the need by:
* Options from ARGV and stowrc files are separately parsed, resulting in
two options hashes.
* Creating an option hash from stowrc files allows modification of
specific arguments without having to rely on something like regex
parsing of the options.
* get_config_file_options modified to return options hash.
* Uses the same parse_options function that parses ARGV
* Add Hash:Merge to dependencies in order to merge the two option
hashes.
* process_options() merges the two option hashes.
* Get option hash for ARGV
* Get option hash from get_config_file_options().
* Merge the two hashes with Hash::Merge.
* Sanitation and checks are ran on the merged options.
* The options -S, -D, and -R are ignored in stowrc files.
* Due to the way argument parsing happens, the effect of these
actions is not carried from stowrc into parsing of cli options.
* It doesn't seem to make sense to put these options in stowrc
anyway.
Why:
* Want to be able to selectively apply filepath expansion to:
1. Only options in a stowrc file.
2. Only options that take a file path.
* Because of need 1, any expansion must be performed on stowrc options
before merging with cli options.
* Because of need 2, stowrc options need to be parsed before expansion
in order to know which options need expanding.
This change addresses the need by:
* Create parse_options()
* Implements option parsing logic previously in process_options()
* Takes an array as parameter instead of assuming ARGV
* Edit process_options() to still work as expected.
* Only change was to call parse_options() instead of directly
parsing ARGV
* By factoring out the option parsing code, we can reuse the existing
parsing code for stowrc options.
* Allows expansion of only the option itself, i.e expansion on
"$HOME/target" rather than "--target=$HOME/target"
* Allows easy determination of which options need expansion.
De-emphasise the package management aspects, since these days
almost everyone prefers to use modern package managers such as
rpm / dpkg / Nix for (system-wide) package management.
Also include more popular modern use cases for Stow such as management
of dotfiles and software compiled in the user's $HOME directory.
Fixes#22: https://github.com/aspiers/stow/issues/22
- The `sanitize_path_options` functions remove all trailing
and leading spaces. So any valid directory like ` 123`,
`123 ` can not be used
- Also if there are two directories ` 123` and `123`, and if
user pick the ` 123` as option to `-d` or `-t`, then stow pick
directory `123` as the argument instead of ` 123` as user want.
```
STOW_DIR=. stow -n -v3 -t \ 123 456
stow dir is /tmp/test
stow dir path relative to target 123 is ..
cwd now 123
cwd restored to /tmp/test
cwd now 123
Planning stow of package 456...
Stowing contents of ../456 (cwd=/tmp/test/123)
Planning stow of package 456... done
cwd restored to /tmp/test
WARNING: in simulation mode so not modifying filesystem.
```
- This commit remove the check in `sanitize_path_options` function,
and now stow can work with those directories. There have been a check
for valid directory, so we are safe.
Previously STOW_DIR=0 would cause the cwd to be used as the STOW_DIR.
Make that instead raise an error. Do similar validation on the target
directory.
Closes#7 - https://github.com/aspiers/stow/pull/7
In shell, a variable is often considered unset even if it is
set to the empty string. In other words,
STOW_DIR= stow [args]
is an idiomatic alternative to writing:
unset STOW_DIR
stow [args]
and it also has the advantage of temporarily "unsetting" STOW_DIR
for a single command.
Therefore we should treat STOW_DIR being set to the empty string
as equivalent to it not being set at all.
Thanks to Cuong Manh Le for highlighting this issue!
Fixes#6 - https://github.com/aspiers/stow/issues/6Closes#5 - https://github.com/aspiers/stow/pull/5
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).