anishathalye / dotbot

A tool that bootstraps your dotfiles ⚡️
MIT License
7.14k stars 296 forks source link

New feature: copy/initialize a file instead of linking #355

Open denilsonsa opened 9 months ago

denilsonsa commented 9 months ago

The problem

With the current capabilities of dotbot, I can have a ~/.vim/vimrc file in my dotfiles, and dotbot will correctly create the link. Inside that file, I am sourcing another file ~/.vimrc/vimrc-local, which should contain local changes that should not be stored in the dotfiles. So far, so good.

However, the tricky part is initializing the -local file. It should have a certain structure, it should declare a few functions. In other words, there is some boilerplate it should have.

The proposed solution

I am proposing a new directive: skel (or initialize or seed or copy or copy_without_overwriting or… well, naming is hard!)

It would be declared in a similar way to the link directive, but instead of creating a symlink, it would just copy the file over there. Look:

- link:
    '~/.vim/vimrc': 'base/.vim/vimrc'
- skel:
    '~/.vim/vimrc-local': 'base/.vim/vimrc-local'

On a fresh machine, the outcome would be:

On subsequent runs on the same machine:

The proposed behavior reminds me of /etc/skel/.

Additional configuration

Maybe the name should be copy, and it should have the same configuration keys as link:

Alternatives

  1. I keep the -local file in my dotfiles, and I have to remember to copy/create it manually.
  2. I keep the -local file in my dotfiles, and I add some custom shell directive to copy only if it doesn't exist.
  3. I can keep different versions of -local, one for each machine. Many people do that, but it is not desirable for files that contain sensitive information (such as API keys or tokens).
  4. Templating as requested in #117. It has the same drawbacks as alternative 3, plus the additional complexity of requiring additional Python modules.

Compared to the alternatives, the skel/copy solution has the following advantages:

kurtmckee commented 2 months ago

Nice suggestion! I'm currently doing this with my shared git config:

- shell:
    - description: "Copy shared/git/gitconfig.ini to ~/.gitconfig (if needed)"
      command: >
        if [ ! -e ~/.gitconfig ]; then
            cp shared/git/gitconfig.ini ~/.gitconfig;
        fi
      quiet: true

A copy directive might be just the ticket in this situation.