Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dotfiles option doesn't work with directories #33

Closed
lhindir opened this issue Apr 9, 2019 · 53 comments · Fixed by #107
Closed

Dotfiles option doesn't work with directories #33

lhindir opened this issue Apr 9, 2019 · 53 comments · Fixed by #107
Assignees
Labels
bug dotfiles Issues with --dotfiles option help wanted
Milestone

Comments

@lhindir
Copy link

lhindir commented Apr 9, 2019

Paging @jvkersch in case he has any insight.

I use stow to manage my dotfiles. If I am trying to stow my config for zathura, I run stow --dotfiles zathura from ~/dotfiles, which contains zathura/dot-config/zathura/zathurarc. This outputs:

stow: ERROR: stow_contents() called with non-directory path: dotfiles/zathura/.config

I have no problem if I change the path to zathura/.config. Furthermore, stow --dotfiles bash works fine on the file bash/dot-bashrc. It only fails with directories.

I'll freely admit I know little of the internals here, so I'm sorry if I'm just misunderstanding how to use it. But the error message makes it seem like stow is converting the path before getting the path contents and stowing, when it should be getting the path contents, then converting the path, and finally stowing.

Thanks for any insight you can provide.

@aspiers
Copy link
Owner

aspiers commented Jun 28, 2019

Thanks for the report! I didn't implement --dotfiles, so would welcome some help triaging this one.

@bricewge
Copy link
Contributor

bricewge commented Jun 29, 2019

I got bitten by this one too when trying the new release 2.3.0, following is more verbose log when the issue is triggered. Hopefully my comment isn't just seen as a noisy +1 and can help in debugging...

$ stow --ignore='^setup.sh' --ignore='^README.*' --ignore='^@.*'--ignore='^_.*' --target="$HOME" --no-folding --dotfiles alacritty --verbose=5
stow dir is /home/bricewge/project/dotfiles
stow dir path relative to target /home/bricewge is project/dotfiles
cwd now /home/bricewge
cwd restored to /home/bricewge/project/dotfiles
cwd now /home/bricewge
Planning stow of package alacritty...
. not protected
Stowing contents of project/dotfiles/alacritty (cwd=/home/bricewge)
  => project/dotfiles/alacritty
  is_a_node(.)
  link_task_action(.): no task
  dir_task_action(.): no task
    parent_link_scheduled_for_removal(.): prefix
    parent_link_scheduled_for_removal(.): returning false
  is_a_node(.): really exists
  Ignoring path _alacritty.terminfo due to --ignore=(?^:^_.*\z)
  Ignoring path setup.sh due to --ignore=(?^:^setup.sh\z)
  project/dotfiles/alacritty/.stow-local-ignore didn't exist
  /home/bricewge/.stow-global-ignore didn't exist
  Using built-in ignore list
    Ignore list regexp for paths:    /(?^:(^|/)(^/COPYING|^/LICENSE.*|^/README.*|^/\.stow\-local\-ignore$)(/|$))/
    Ignore list regexp for segments: /(?^:^(\.git|.+~|\.#.+|\.svn|CVS|#.*#|\.gitignore|_darcs|\.hg|\.cvsignore|.+,v|RCS)$)/
  Not ignoring dot-config
  Adjusting: dot-config => .config
Stowing project/dotfiles / alacritty / .config
  => project/dotfiles/alacritty/dot-config
  is_a_link(.config)
  link_task_action(.config): no task
  is_a_link(.config): returning 0
  is_a_node(.config)
  link_task_action(.config): no task
  dir_task_action(.config): no task
    parent_link_scheduled_for_removal(.config): prefix .config
    parent_link_scheduled_for_removal(.config): returning false
  is_a_node(.config): really exists
  Evaluate existing node: .config
  is_a_dir(.config)
  dir_task_action(.config): no task
    parent_link_scheduled_for_removal(.config): prefix .config
    parent_link_scheduled_for_removal(.config): returning false
  is_a_dir(.config): real dir
.config not protected
Stowing contents of project/dotfiles/alacritty/.config (cwd=/home/bricewge)
  => ../project/dotfiles/alacritty/dot-config
stow: ERROR: stow_contents() called with non-directory path: project/dotfiles/alacritty/.config

@aspiers
Copy link
Owner

aspiers commented Jun 29, 2019

Definitely not noise, thanks a lot @bricewge for the extra debug! Unfortunately I'm now packing for a 2 week holiday so am unlikely to have time to look at this soon, but if anyone else can make headway in my absence that would be awesome :)

@jvkersch
Copy link
Contributor

Apologies for not replying to the earlier report. I will try to reproduce and I'll see if I can make any headway before @aspiers returns from vacation.

@jvkersch
Copy link
Contributor

I was able to reproduce, thanks all for the detailed info. I think we expand the stow directory too early on; my assumption when originally implementing this was that the dot- entries would be at the top-level in the stow directory, but this is not the case here. Will do some more digging.

@mattmc3
Copy link

mattmc3 commented Aug 24, 2019

In the mean time, I've been using --target and a separate stow directory for ~/.config as a work around:

stow -v --dotfiles --target=$HOME/.config stow-config

@gutierri
Copy link
Contributor

gutierri commented Sep 6, 2019

I have this same structure, one way that works is to keep ~/dotfiles at the root of $ HOME and this command works (@lhindir):

$ (~/dotfiles) stow -R --dotfiles zathura/ -v
LINK: .config => laptop/zathura/dot-config

And yes, indeed there is a bug, because in my environment if I try to pass a target it returns this same message:

$ (~/dotfiles) stow -R --dotfiles -t ~ zathura/ -v
stow: ERROR: unstow_contents() called with non-directory path: Workspace/git.gutierri.me/laptop/zathura/.config

pSub added a commit to pSub/configs that referenced this issue Jan 7, 2020
Unfortunately the dotfiles options is currently broken
for directories, see aspiers/stow#33.
@NPastorale
Copy link

NPastorale commented Jan 28, 2020

I just came across this bug. and read through this issue and #63. It's not a dealbreaker (at least not for my use case), but it would be nice to have this feature working. Is there any ETA for this fix?
Thanks!!

@rdrr
Copy link

rdrr commented Mar 29, 2020

Also, stow -D --dotfiles does not seem to work at all, even when files do not contain any "dot-filename" replacements.

We get the to:
Planning unstow of package *...done
but there is no
UNLINK: *
when normally unstowing a package.

To echo NPastorale, this would be a great feature. Thanks!

aanders added a commit to aanders/rcfiles that referenced this issue Apr 26, 2020
`stow` supports the `--dotfiles` option which causes files beginning
with the prefix `dot-` in the stow directory to be symlinked with a literal
period character instead.  This avoids the need to have hidden files in
the stow directory.

Unfortunately, this option is not fully working for hidden directories
(see aspiers/stow#33).  Hence, packages
containing hidden directories remain unchanged for now.

Add a README file to help with remembering how the installation works
for each package.
sirhc added a commit to sirhc/dotfiles that referenced this issue Apr 28, 2020
The recent addition of the `--dotfiles` option allows me to name the
files in a way so that they are not hidden by the shell. However, as
noted in the README, Stow does not yet support using this option with
subdirectories (see <aspiers/stow#33>), so
these have not been converted to use the `dot-*` names.
@AitorATuin
Copy link
Contributor

AitorATuin commented May 24, 2020

This attempts to fix this problem: #70

I did not test it properly (a very basic use case with a directory) yet. I will test it with a deeper layer of directories.

I have added some unit tests and the pull requests is building in the CI system. I'm using it locally now also and seems to work.

@ghost
Copy link

ghost commented Jun 13, 2020

It would have been lovely to have the limitations of the --dotfiles option in the manual published/released while waiting for the fix to be pushed out

@samuelhnrq
Copy link

It's been more than a year the bug was reported and two months since a fix has been proposed, any updates on this?

@qbedard
Copy link

qbedard commented Jul 15, 2020

Indeed. Would love to see the fix get merged. 🙏

@queensferryme
Copy link

Came across the same issue today. Would highly appreciate if the fix got merged.

Also I can help noticing that it has been almost a whole year since the last commit on the master branch. Does the dev team need any help maintaining this project?

@frelind
Copy link

frelind commented Aug 10, 2020

Just stumbled on this bug, would be nice if the fix got released.

frelind added a commit to frelind/dotfiles that referenced this issue Aug 10, 2020
See aspiers/stow#33
Until it's resolved dirs can't use dot- prefix
@jamieeeeeeeee
Copy link

jamieeeeeeeee commented Jan 2, 2021

Just hit this too. Any timeline for a fix?

@han1475
Copy link

han1475 commented Jan 21, 2021

I got bitten by this one too when use stow to manage my dotfiles(e.g. ~/dotfiles/emacs/dot-emacs.d => ~/.emacs.d).

I found that ensuring the ~/.emacs.d directory doesn't exist(e.g. rm -rf ~/.emacs.d) before running stow --dotfiles emacs can solve this problem.

I don't know why, but it works for me. I use the latest release 2.3.1

@KucharczykL
Copy link

It would be nice to have this fixed!

@aspiers aspiers added this to the Release 2.3.3 milestone Apr 4, 2021
@aspiers aspiers added the dotfiles Issues with --dotfiles option label Apr 4, 2021
@SfyMantissa
Copy link

Bump.
Encountered the same issue and Google magic led me here.

  1. This workflow fails.
sfy@neonblaze: ~/repos/dotfiles ❱❱ tree -d local
local
└── dot-local
    └── share
        └── applications

4 directories
sfy@neonblaze: ~/repos/dotfiles ❱❱ stow --dotfiles --verbose --target=$HOME --restow local
stow: ERROR: unstow_contents() called with non-directory path: repos/dotfiles/local/.local
  1. Had to change dot- back to . — workflow below works fine.
sfy@neonblaze: ~/repos/dotfiles ❱❱ tree -ad local
local
└── .local
    └── share
        └── applications

4 directories
sfy@neonblaze: ~/repos/dotfiles ❱❱ stow --verbose --target=$HOME --restow local
LINK: .local/share/applications => ../../repos/dotfiles/local/.local/share/applications

Looking forward to tweaks for the --dotfiles flag, because it would be really handy.

@ErebusBat
Copy link

FWIW I ended up switching to twpayne/chezmoi specifically because of this issue.

It was a PIA; however it (Chezmoi) does handle things much better, especially secrets.

sinarf added a commit to sinarf/dotfiles that referenced this issue Aug 4, 2023
This is blocked by aspiers/stow#33
I get the following error:
stow: ERROR: stow_contents() called with non-directory path: .dotfiles/all/.config
sinarf added a commit to sinarf/dotfiles that referenced this issue Aug 4, 2023
sirhc added a commit to sirhc/dotfiles that referenced this issue Sep 13, 2023
The recent addition of the `--dotfiles` option allows me to name the
files in a way so that they are not hidden by the shell. However, as
noted in the README, Stow does not yet support using this option with
subdirectories (see <aspiers/stow#33>), so
these have not been converted to use the `dot-*` names.
@phunni
Copy link

phunni commented Nov 9, 2023

Surprised to see (what seems to me) such a major issue still unresolved. I've just started playing with stow in order to manage files in my home directory and it looks like I'll either have to rename dot-* to .* or switch to a different solution. Both of which would be fairly annoying...

@luisduque-ve
Copy link

Surprised to see (what seems to me) such a major issue still unresolved. I've just started playing with stow in order to manage files in my home directory and it looks like I'll either have to rename dot-* to .* or switch to a different solution. Both of which would be fairly annoying...

I don't understand why this project isn't archived already tbh, I was in love with stow so much but the lack of maintenance force me to look another alternatives, I tried chezmoi and is completely awesome, you probably want to take a look to it.

@doolio
Copy link

doolio commented Nov 10, 2023

it looks like I'll either have to rename dot-* to .*

The --dotfiles option works for files just not directories at the moment.

@phunni
Copy link

phunni commented Nov 26, 2023

it looks like I'll either have to rename dot-* to .*

The --dotfiles option works for files just not directories at the moment.

It's directories that are the problem in my case. Mostly anyway.

flokoe added a commit to flokoe/dotfiles-devcontainer that referenced this issue Jan 17, 2024
@diego898
Copy link

A real shame this still doesn’t work - any pull requests/forks that work for anyone?

@HaleTom
Copy link

HaleTom commented Jan 21, 2024

@diego898 take a look at #63 for a quick-start on a PR to fix this.

@HaleTom
Copy link

HaleTom commented Jan 21, 2024

This project seems largely unmaintained. Consider instead: https://www.chezmoi.io/

@niklaas
Copy link

niklaas commented Jan 22, 2024

This project seems largely unmaintained.

Hm, I'm wondering whether this is the wrong channel to raise attention about this issue. I just sent an email to the bug-stow mailing list to make sure.

Consider instead: https://www.chezmoi.io/

Thanks for the suggestion. According to https://www.chezmoi.io/comparison-table/, chezmoi uses files instead of symlinks which might be to much of an incompatibility for users of stow. Just mentioning to make people aware. :)

@HaleTom
Copy link

HaleTom commented Jan 22, 2024

Thanks @niklaas for raising this on the mailing list.

chezmoi does have a symlinks mode, but note the limitations.

@xentatt
Copy link

xentatt commented Feb 23, 2024

Still having this bug :(
just for anyone who wants to stick with stow can try this implementation of it in C++ https://github.com/majorkingleo/xstow

Kapocsi added a commit to Kapocsi/dotfiles that referenced this issue Mar 17, 2024
turn out dot-config -> .config not actually working gh issues has been open for a while

aspiers/stow#33
@aspiers
Copy link
Owner

aspiers commented Apr 5, 2024

For now, please see the interim update and apology here: #70 (comment)

TL;DR: this bug is fixed in the dev branch, and I will do my utmost to cut a release this weekend.

Proper communications to follow this weekend.

@Brottweiler
Copy link

Brottweiler commented Apr 5, 2024

@aspiers cheers mate, stow has always been perfect for me and while there could be bugs fixed or features added it does what it says on the tin and you never abandoned it. I'm thankful for that!

@lgrosz
Copy link

lgrosz commented Apr 6, 2024

Very excited to see progress on this issue. Hopefully this weekend I can finally remove the hidden directories in my dotfiles repository!

@aspiers
Copy link
Owner

aspiers commented Apr 6, 2024

I have now merged dev into master so technically this is fixed; however I have an improved fix nearly done which I'm hoping to be able to squeeze into the next release, so leaving this open for now.

@aspiers aspiers modified the milestones: Release 2.4.1, Release 2.4.0 Apr 6, 2024
@aspiers
Copy link
Owner

aspiers commented Apr 7, 2024

It was a nightmare to iron out all the details but I finally have the improved fix working locally, and I'm now documenting it.

aspiers added a commit that referenced this issue Apr 7, 2024
Stow walks the package and target tree hierarchies by using mutually
recursive pairs of functions:

- `stow_contents()` and `stow_node()`
- `unstow_contents()` and `unstow_node()`

As Stow runs its planning from the target directory (`plan_*()` both
call `within_target_do()`), previously the parameters for these
included:

- `$target_subpath` (or `$target_subdir` in the `*_node()` functions):
  the relative path from the target top-level directory to the target
  subdirectory (initially `.` at the beginning of recursion).  For
  example, this could be `dir1/subdir1/file1`.

- `$source`: the relative path from the target _subdirectory_ (N.B. _not_
  top-level directory) to the package subdirectory.  For example, if
  the relative path to the Stow directory is `../stow`, this could be
  `../../../stow/pkg1/dir1/subdir1/file1`.  This is used when stowing
  to construct a new link, or when unstowing to detect whether the
  link can be unstowed.

Each time it descends into a further subdirectory of the target and
package, it appends the new path segment onto both of these, and also
prefixes `$source` with another `..`.  When the `--dotfiles` parameter
is enabled, it adjusts `$target_subdir`, performing the `dot-foo` =>
`.foo` adjustment on all segments of the path in one go.  In this
case, `$target_subpath` could be something like `.dir1/subdir1/file1`,
and the corresponding `$source` could be something like
`../../../stow/pkg1/dot-dir1/subdir1/file1`.

However this doesn't leave an easy way to obtain the relative path
from the target _top-level_ directory to the package subdirectory
(i.e. `../stow/pkg1/dot-dir1/subdir1/file1`), which is needed for
checking its existence and if necessary iterating over its contents.

The current implementation solves this by including an extra `$level`
parameter which tracks the recursion depth, and uses that to strip the
right number of leading path segments off the front of `$source`.
(In the above example, it would remove `../..`.)

This implementation isn't the most elegant because:

- It involves adding things to `$source` and then removing them again.

- It performs the `dot-` => `.` adjustment on every path segment
  at each level, which is overkill, since when recursing down a level,
  only adjustment on the final subdirectory is required since the higher
  segments have already had any required adjustment.

  This in turn requires `adjust_dotfile` to be more complex than it
  needs to be.

  It also prevents a potential future where we might want Stow to
  optionally start iterating from within a subdirectory of the whole
  package install image / target tree, avoiding adjustment at higher
  levels and only doing it at the levels below the starting point.

- It requires passing an extra `$level` parameter which can be
  automatically calculated simply by counting the number of slashes
  in `$target_subpath`.

So change the `$source` recursion parameter to instead track the
relative path from the top-level package directory to the package
subdirectory or file being considered for (un)stowing, and rename it
to avoid the ambiguity caused by the word "source".

Also automatically calculate the depth simply by counting the number
of slashes, and reconstruct `$source` when needed by combining the
relative path to the Stow directory with the package name and
`$target_subpath`.

Closes #33.
@aspiers aspiers self-assigned this Apr 7, 2024
@aspiers
Copy link
Owner

aspiers commented Apr 7, 2024

v2.4.0 is released with this fix! See https://ftp.gnu.org/gnu/stow/

I'm just updating the website and preparing an announcement email.

kittydoor added a commit to kittydoor/dotfiles that referenced this issue Jun 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment