Summary
--ignore=<regex>
lines that I put in my .stowrc
does not work. When running Stow, it says "Loading defaults from .stowrc", yet it has no effect. But passing the --ignore=<regex>
lines to the command directly works.
Problem
Assume this directory:
user@user-machine:~/test-stow/stow$ tree -a
.
├── a
│ └── car
└── .stowrc
1 directory, 2 files
Contents of ./.stowrc
:
--ignore='car'
So my expectation is that running the command stow --verbose=3 a/
while in that directory is equivalent to running stow --ignore='car' --verbose=3 a/
if the ./.stowrc
file wasn't there.
Now I run:
user@user-machine:~/test-stow/stow$ stow --verbose=3 a
Loading defaults from .stowrc
stow dir is /home/user/test-stow/stow
stow dir path relative to target /home/user/test-stow is stow
cwd now /home/user/test-stow
cwd restored to /home/user/test-stow/stow
cwd now /home/user/test-stow
Planning stow of package a...
Stowing contents of stow/a (cwd=~/test-stow)
Stowing stow/a/car
LINK: car => stow/a/car
Planning stow of package a... done
cwd restored to /home/user/test-stow/stow
Processing tasks...
cwd now /home/user/test-stow
cwd restored to /home/user/test-stow/stow
Processing tasks... done
Note that this does create the symlink to ./car
, despite the ignore
line in ./.stowrc
.
Now I undo the operation by running stow -D --verbose=3 a/
:
user@user-machine:~/test-stow/stow$ stow -D --verbose=3 a/
stow dir is /home/user/test-stow/stow
stow dir path relative to target /home/user/test-stow is stow
cwd now /home/user/test-stow
Planning unstow of package a...
Unstowing from . (cwd=~/test-stow, stow dir=stow)
Unstowing stow/a/car
car did not exist to be unstowed
Planning unstow of package a... done
cwd restored to /home/user/test-stow/stow
cwd now /home/user/test-stow
cwd restored to /home/user/test-stow/stow
Processing tasks...
If I delete everything in ./.stowrc
and run stow --verbose=3 --ignore='car' a/
, I get a different result:
user@user-machine:~/test-stow/stow$ stow --verbose=3 --ignore='car' a/
stow dir is /home/user/test-stow/stow
stow dir path relative to target /home/user/test-stow is stow
cwd now /home/user/test-stow
cwd restored to /home/user/test-stow/stow
cwd now /home/user/test-stow
Planning stow of package a...
Stowing contents of stow/a (cwd=~/test-stow)
Planning stow of package a... done
cwd restored to /home/user/test-stow/stow
Processing tasks...
Now a symlink to ./car
was not created, as expected and desired.
What about $HOME/.stowrc
?
Placing the .stowrc
file in the home directory instead of $HOME/test-stow/stow
has the same effect; a symlink to the file car
still gets made.
Ignore lists
Having a file $HOME/test-stow/stow/.stow-local-ignore
with the content "car" instead of the .stowrc
file doesn't work, either. The symlink to the file named car
still gets created.
GNU Stow version: 2.2.0
Perl version: perl 5, version 18
Update
Here is my reply to Adam Spiers' answer.
Best Answer
Thanks for the excellent bug report! I can answer your questions, and as the Stow maintainer I can also fix the issues, but I'd appreciate your feedback from a UX perspective so we can figure out the best fix.
Firstly, it's worth noting that
--verbose=5
will give you much more detail about the internals of the ignore mechanism, although in this case it would not be sufficient to explain why things are not behaving the way you expect.There are two reasons why neither of your
.stowrc
files worked:.stowrc
parser splits (option, value) pairs based on the space character, not on=
. So a line for an ignore option in that file should start--ignore
not--ignore=
..stowrc
parser doesn't automatically strip quotes. When the--ignore
option (or any other option, for that matter) is passed via the CLI, the shell will strip the quotes before Stow sees them. That's why it works there.So the combination of these two means that your
.stowrc
should contain:I've tested that, and indeed it works.
Now, there are probably valid arguments saying that either or even both of these points are actually UX bugs. I certainly agree that they do not provide an intuitive UI. The question is whether the behaviour should be changed, or whether it's better to simply make this clearer in the docs.
My current thinking is that based on Postel's Law, the parser should accept splitting on both space and
=
, but it should not strip quotes because what if the user really did want to ignore'car'
rather than justcar
? Also there is an existing and related bug report that options with spaces break instowrc
, so this should be taken into account when implementing any fix. (I'll update that bug after posting this answer.)I'd welcome your opinions on these.
Finally, I believe your
.stow-local-ignore
did not work because you placed it in the stow directory rather than in thea/
package directory. The documentation about this seems clear to me, so I think it's fair to write this one off as pilot error. However if you have any suggestions for how to make the docs clearer than I'm all ears.Thanks again! BTW in future you may want to consider sending bug reports to the
bug-stow
mailing list (or to the horrible but ethically correct Savannah bug tracker or to the less ethical but more usable github issue tracker) and help requests to thehelp-stow
mailing list. Yes, I know that these are too many options for such a small and quiet project; that's a TODO for another day ...