twpayne / chezmoi

Manage your dotfiles across multiple diverse machines, securely.
https://www.chezmoi.io/
MIT License
13.4k stars 493 forks source link

.chezmoiexternal - support for git repositories? #1838

Closed twpayne closed 2 years ago

twpayne commented 2 years ago

Discussed in https://github.com/twpayne/chezmoi/discussions/1831

Originally posted by **j-xella** January 19, 2022 Hi, Currently, `.chezmoiexternal` supports files and archives. Is it possible for it to also support git repositories? So that: archive add ~ git clone archive update ~ git update --rebase Here is a use case - many vim plugins these days can simply be installed via `git clone` into `~/.vim/pack/author/start/xxx` folder. It would be great if chezmoi could be configured to do this as a part of set-up. After reading the documentation, I could only come with the following solutions: * use archives provided by github - but then I would not have access to plugin history * create some `run_xxx.sh` script(-s) that would do it - but that would not be very declarative, and potentially require different code for different platforms, etc...
twpayne commented 2 years ago

Previous related issues: #1421 and #1623.

The previous related issues were based around chezmoi generating the target state from a git repo. If I understand correctly, what's being requested here is for chezmoi to effectively run git clone and git pull in a subdirectory in the target state.

How would you imagine the config of a git-repo external in .chezmoiexternals.toml? Maybe something like the following:

[".vim/pack/author/start/xxx"]
    type = "git-repo"
    url = "https://github.com/author/xxx.git"
    ref = "master" # or a commit hash or tag
    refreshPeriod = "168h"

chezmoi's logic would then look something like:

  1. If .vim/pack/author/start/xxx either does not exist or is not a git working copy, then run git clone to create it.
  2. Otherwise, run git pull if more time than refreshPeriod has passed since the last git clone/git pull.

ref defaults to master but could be any git ref (e.g. a commit hash or tag). chezmoi will run appropriate git commands to reset the state of .vim/pack/author/xxx to the desired ref.

Does this sound reasonable?

j-xella commented 2 years ago

Previous related issues: #1421 and #1623.

The previous related issues were based around chezmoi generating the target state from a git repo. If I understand correctly, what's being requested here is for chezmoi to effectively run git clone and git pull in a subdirectory in the target state.

Basically, yes. If this is a git repository, git may as well do the syncing ...

How would you imagine the config of a git-repo external in .chezmoiexternals.toml? Maybe something like the following:

[".vim/pack/author/start/xxx"]
    type = "git-repo"
    url = "https://github.com/author/xxx.git"
    ref = "master" # or a commit hash or tag
    refreshPeriod = "168h"

chezmoi's logic would then look something like:

  1. If .vim/pack/author/start/xxx either does not exist or is not a git working copy, then run git clone to create it.
  2. Otherwise, run git pull if more time than refreshPeriod has passed since the last git clone/git pull.

ref defaults to master but could be any git ref (e.g. a commit hash or tag). chezmoi will run appropriate git commands to reset the state of .vim/pack/author/xxx to the desired ref.

Does this sound reasonable?

Sounds perfectly fine. I would maybe also:

j-xella commented 2 years ago

Below is an example of how I currently implemented this functionality via scripts and templates (for linux only).

  1. .chezmoitemplates/update_vim_plugin_from_git.sh :
    
    {{- if (ne .core.chezmoi.os "windows") -}}
    #! /usr/bin/sh

Run the script weekly (ish). Last run : {{ div (now | unixEpoch) 604800 }} week(-s) since epoch

{{ $git_folder := regexReplaceAll "^./([^/])\.git$" .git_url "${1}" -}} if [ -d {{ $git_folder | quote }} ]; then cd {{ $git_folder | quote }} echo "*** Getting the latest of $PWD ..." git pull --rebase --autostash else git clone {{ .git_url }} cd {{ $git_folder | quote }} fi

if [ -d doc ]; then echo "*** Indexing plugin documentation ..." vim -Es -c "helptags doc | qa!" fi {{- end -}}


 2. `private_dot_vim/private_pack/private_alker0/private_opt/run_onchange_chezmoi.sh.tmpl` :

{{- template "update_vim_plugin_from_git.sh" dict "core" . "git_url" "https://github.com/alker0/chezmoi.vim.git" -}}

lucasff commented 2 years ago

Hi! I would like to request this feature as well. oh-my-zsh has a auto-update feature integrated, but it fails since it's downloaded via an archive, so you get the following error every startup:

[oh-my-zsh] Can't update: not a git repository.

Would be happy to help, but it seems there's already some work done for it. I'd expect chezmoi to simply run git pull --ff-only on the repo.