deadc0de6 / dotdrop

Save your dotfiles once, deploy them everywhere
https://dotdrop.readthedocs.io
GNU General Public License v3.0
1.78k stars 105 forks source link

[bug] link_children use template linking method when there are no templating #363

Closed Kritiqual closed 2 years ago

Kritiqual commented 2 years ago

Dotdrop version (and git commit if run from source): v1.10.3 Using dotdrop: as a submodule

Describe the bug When running dotdrop install, it install all dotfiles in ~/.config/dotdrop/.config

Steps to Reproduce

  1. I have dotdrop.sh in my dotfiles repo
  2. I have this alias: alias dotdrop='DOTDROP_CONFIG=~/.dots/config.yaml ~/.dots/dotdrop.sh' and I'm using zsh
  3. It works fine before I ran command in 4
  4. I ran git submodule update --init --remote dotdrop a couple days ago.
  5. When running dotdrop install -d to check, I see that it not install dotfiles in the desired path, instead in the "~/.config/dotdrop/.config"

Expected behavior

Install dotfiles into desired path in the config

Additional information

Link to my config file

Here is some line that show when running dotdrop install -d:

[DRY] would install /home/username/.config/dotdrop/.config/awesome/.git 
[DRY] would install /home/username/.config/dotdrop/.config/awesome/.gitmodules 
[DRY] would install /home/username/.config/dotdrop/.config/awesome/LICENSE 
[DRY] would install /home/username/.config/dotdrop/.config/awesome/README.md 
deadc0de6 commented 2 years ago

Ouch, that sounds bad, luckily you ran with -d. Do you have the env variable DOTDROP_WORKDIR defined by any chance?

Also can you provide the first part of the verbose logs, including the part that says settings block: and lists the settings dotdrop will apply?

I'm guessing the extract above is from the d_config dotfile? Can you provide the subsequent line that says how it would link, something like the following:

[DRY] would install /home/user/.config/dotdrop/.testdir/file2
[DRY] would remove /home/user/.testdir/file2 and link to /home/user/.config/dotdrop/.testdir/file2
Kritiqual commented 2 years ago

I checked and there is no DOTDROP_WORKDIR is set

Here is the first part of verbose log I think is important: gist link

Example for bat when running dotdrop install ...

[DRY] would install /home/kritiqual/.config/dotdrop/.config/bat/config 
[DRY] would remove /home/kritiqual/.config/bat and link to /home/kritiqual/.config/dotdrop/.config/bat 

I see this in the docs:

Entry: workdir

Description: 
    Path to the directory where templates are installed 
    before being symlinked when using link:absolute|relative|link_children 
    (absolute path or relative to the config file location)

Default: ~/.config/dotdrop

Is it because I use template, so this will be used? I don't think so, because even when I remove every template part, it still have this behavior

deadc0de6 commented 2 years ago

I'm sorry but I can't seem to be able to reproduce your issue, could you maybe provide the entire log file (you should be able to drag&drop it)? You could for example provide the logs from dotdrop install -d d_config so that it's limited to the d_config dotfile. Thanks and sorry you're having issues

Kritiqual commented 2 years ago

So, I did some test and there are some weird behavior of link: link_children

link: link_children always link dotfiles to ~/.config/dotdrop even there are no template used. I have config the same as in the example in the doc

When using link: link_children, if dotfiles entry have a directory in side src, then the output when install looks like it will link invidual file (recursively), but the result is that it will link the directory

Example:

$ ls ~/small_dir file_1.txt file_2.txt

deadc0de6 commented 2 years ago

Thanks for helping me identify the issue.

I see a few issues here.

The tild (~) is always expanded by dotdrop, I have continuous tests that shows it does, are you sure about that?

Your config is somehow wrong, especially the dst part of the config.

I created the same directory as you:

/home/user/.dotfiles
├── config.yaml
├── dotdrop
├── dotdrop.sh
├── file_3.txt
├── file_4.txt
└── small_dir
    ├── file_1.txt
    └── file_2.txt

I then imported the file dotdrop import ~/.dotfiles, which resulted in the following dotfile entry

dotfiles:
  d_dotfiles:
    src: dotfiles
    dst: ~/.dotfiles

Before going into link_children, I then assumed you somehow mv <dotpath>/dotfiles <dotpath>/dir1 and replaced the src to dir1 but then the dst is wrong since it must be the absolute path to the destination where the dotfile is to be installed, therefore ~/.dotfiles or /home/username/.dotfiles but not /home/username.

Can you retry by following below steps please

create the fake dotfile dir

$ mkdir -p ~/.dotfiles/small_dir
$ touch ~/.dotfiles/config.yaml
$ touch ~/.dotfiles/dotdrop
$ touch ~/.dotfiles/dotdrop.sh
$ touch ~/.dotfiles/file_3.txt
$ touch ~/.dotfiles/file_4.txt
$ touch ~/.dotfiles/small_dir
$ touch ~/.dotfiles/small_dir/file_1.txt
$ touch ~/.dotfiles/small_dir/file_2.txt

import it in dotdrop

$ dotdrop import ~/.dotfiles

edit config.yaml and add link: link_children to the imported dotfile (d_dotfiles or similar). Then install it

$ dotdrop install -f d_dotfiles

Then running tree on ~/.dotfiles should output something similar:

$ tree ~/.dotfiles
/home/user/.dotfiles
├── config.yaml -> /home/user/dotdrop/dotfiles/dotfiles/config.yaml
├── dotdrop -> /home/user/dotdrop/dotfiles/dotfiles/dotdrop
├── dotdrop.sh -> /home/user/dotdrop/dotfiles/dotfiles/dotdrop.sh
├── file_3.txt -> /home/user/dotdrop/dotfiles/dotfiles/file_3.txt
├── file_4.txt -> /home/user/dotdrop/dotfiles/dotfiles/file_4.txt
└── small_dir -> /hom/user/dotdrop/dotfiles/dotfiles/small_dir

Which does symlink all the children from .dotfiles to the dotdrop dotpath(/home/user/dotdrop/dotfiles).

Kritiqual commented 2 years ago

Just to clarify my usage with dotdrop:

  1. I also want to control some files is kinda hardcoded to ~, i.e: .bashrc, .bash_profile, etc

  2. The repo is configured by git is ~/.dots and have dotdrop as submodule

  3. My repo ~/.dots is kinda mirroring my system: ~/.dots/home is like ~, ~/.dots/home/.config is like ~/.config (a bit confusing but it actually not that hard to understand ;)) so that the dotpath is ~/.dots

  4. When I run dotdrop install, I want it to link file/directory the exact same way how I put them in ~/.dots, i.e:

    • ~/.bashrc is linked to ~/.dots/home/.bashrc
    • ~/.config/awesome is linked to ~/.dots/home/.config/awesome
    • ~/.local/share/bin is linked to ~/.dots/home/.local/share/bin
    • config.yaml,dotdrop.sh, dotdrop (submodule) isn't need to be linked elsewhere, I always configure my dotfiles by open ~/.dots and run dotdrop in that
  5. Here is example of ~ and ~/.dots would looks like:

    • This is ~
      ~
      ├── .config/
      │  ├── awesome -> ~/.dots/home/.config/awesome/
      │  ├── nvim -> ~/.dots/home/.config/nvim/
      │  ├── mimeapps.list -> ~/.dots/home/.config/mimeapps.list
      │  └── xdg-user.dirs -> ~/.dots/home/.config/xdg-user.dirs
      ├── .bash_profile -> ~/.dots/home/.bash_profile
      └── .bashrc -> ~/.dots/home/.bashrc
    • And this is ~/.dots
      dots/
      ├── dotdrop/
      ├── home/
      │  ├── .config/
      │  │  ├── awesome/
      │  │  ├── nvim/
      │  │  ├── mimeapps.list
      │  │  └── xdg-user.dirs
      │  ├── .bash_profile
      │  └── .bashrc
      ├── .gitmodules
      ├── config.yaml
      └── dotdrop.sh
  6. I read the docs, and see that:

    • If not using templating, the dotfiles in dst is linked directly to the src in dots repo (using link:)
    • If using templating, the dotfiles in dots repo is first installed into ~/.config/dotdrop and then the dst is linked to src in dots in ~/.config/dotdrop -> I don't use templating, so I want the dotfiles is linked directly, not through ~/.config/dotdrop
  7. It somehow works normally by adding template_dotfile_default: false in config: block

deadc0de6 commented 2 years ago

Did the above fix worked? Did you solve the issue with ~ not being expanded?

Regarding your setup, it is absolutely doable. Assuming your config.yaml is in ~/.dots you would simply change the dotpath entry to home and then import the files you want to link

cd ~/.dots
./dotdrop.sh import -l absolute ~/.bash_profile 
./dotdrop.sh import -l absolute ~/.bashrc
./dotdrop.sh import -l absolute ~/.config/awesome
./dotdrop.sh import -l absolute ~/.local/share/bin
## and so on

and finally install those:

## start by testing what would be done
./dotdrop.sh install -d 
## if everything is ok
./dotdrop.sh install

template_dotfile_default disables the handling of template entirely, this is probably not what you want. Dotdrop will handle a dotfile as a template (and thus symlink it through the workdir) when it contains one of the following markers: '{%@@' or '{{@@' or '{#@@'. Unless your dotfiles have any of those, there's no reason it should be handled as template.

Kritiqual commented 2 years ago

That's fix is only work for dst: ~/path but not dst: ~. I guess I need to rewrite the config

deadc0de6 commented 2 years ago

@Kritiqual although having a dst entry set to your home base path (with ~) is probably not what you want, I still found why a single ~ entry value is not expanded in dotdrop. ~ is considered as the null char in yaml and thus the parsed yaml files ended up with an empty dst value.

If you still want to set your dst to tild, you need to quote it:

dotfiles:
  d_dir1:
    src: dir1
    dst: "~"
    link: link_children
Kritiqual commented 2 years ago

Oh, I found my issue, one of my submodule, which have submodules in it have a syntax that make dotdrop think that is template. So, I think the fix is to ignore that folder, can I ignore folder being recognize as template?

deadc0de6 commented 2 years ago

Yes, see the template entry in the dotfile doc.

Kritiqual commented 2 years ago

Issue fixed, I'll close this now