Skip to main content

2 posts tagged with "chezmoi"

View All Tags

Getting the Most Out of chezmoi

· 5 min read
Haril Song
Owner, Software Engineer at 42dot

Following on from the previous post, I'll share some ways to make better use of chezmoi.

info

You can check out the settings I'm currently using here.

How to Use It

You can find the usage of chezmoi commands with chezmoi help and in the official documentation. In this post, I'll explain some advanced ways to use chezmoi more conveniently.

Settings

chezmoi uses the ~/.config/chezmoi/chezmoi.toml file for settings. If you need tool-specific settings, you can define them in this file. It supports not only toml but also yaml and json, so you can write in a format you are familiar with. Since the official documentation guides with toml, I'll also explain using toml as the default.

Setting Merge Tool and Default Editor

chezmoi uses vi as the default editor. Since I mainly use nvim, I'll show you how to modify it to use nvim as the default editor.

chezmoi edit-config
[edit]
command = "nvim"

[merge]
command = "nvim"
args = ["-d", "{{ .Destination }}", "{{ .Source }}", "{{ .Target }}"]

If you use VScode, you can set it up like this:

[edit]
command = "code"
args = ["--wait"]

Managing gitconfig Using Templates

Sometimes you may need separate configurations rather than uniform settings. For example, you might need different gitconfig settings for work and personal environments. In such cases where only specific data needs to be separated while the rest remains similar, chezmoi allows you to control this through a method called templates, which inject environment variables.

First, create a gitconfig file:

mkdir ~/.config/git
touch ~/.config/git/config

Register gitconfig as a template to enable the use of variables:

chezmoi add --template ~/.config/git/config

Write the parts where data substitution is needed:

chezmoi edit ~/.config/git/config
[user]
name = {{ .name }}
email = {{ .email }}

These curly braces will be filled with variables defined in the local environment. You can check the default variable list with chezmoi data.

Write the variables in chezmoi.toml:

# Write local settings instead of `chezmoi edit-config`.
vi ~/.config/chezmoi/chezmoi.toml
[data]
name = "privateUser"
email = "private@gmail.com"

After writing all this, try using chezmoi apply -vn or chezmoi init -vn to see the template variables filled with data values in the config file that is generated.

Auto Commit and Push

Simply editing dotfiles with chezmoi edit does not automatically reflect changes to the git in the local repository.

# You have to do it manually.
chezmoi cd
git add .
git commit -m "update something"
git push

To automate this process, you need to add settings to chezmoi.toml.

# `~/.config/chezmoi/chezmoi.toml`
[git]
# autoAdd = true
autoCommit = true # add + commit
autoPush = true

However, if you automate the push as well, sensitive files could accidentally be uploaded to the remote repository. Therefore, personally, I recommend activating only the auto option until commit.

Managing Brew Packages

If you find a useful tool at work, don't forget to install it in your personal environment too. Let's manage it with chezmoi.

chezmoi cd
vi run_once_before_install-packages-darwin.sh.tmpl

The run_once_ is a script keyword used by chezmoi. It is used when you want to run a script only if it has not been executed before. By using the before_ keyword, you can run the script before creating dotfiles. The script written using these keywords is executed in two cases:

  • When it has never been executed before (initial setup)
  • When the script itself has been modified (update)

By scripting brew bundle using these keywords, you can have uniform brew packages across all environments. Here is the script I am using:

# Only run on MacOS
{{- if eq .chezmoi.os "darwin" -}}
#!/bin/bash

PACKAGES=(
asdf
exa
ranger
chezmoi
difftastic
gnupg
fzf
gh
glab
htop
httpie
neovim
nmap
starship
daipeihust/tap/im-select
)

CASKS=(
alt-tab
shottr
raycast
docker
hammerspoon
hiddenbar
karabiner-elements
obsidian
notion
slack
stats
visual-studio-code
warp
wireshark
google-chrome
)

# Install Homebrew if not already installed
if test ! $(which brew); then
printf '\n\n\e[33mHomebrew not found. \e[0mInstalling Homebrew...'
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
else
printf '\n\n\e[0mHomebrew found. Continuing...'
fi

# Update homebrew packages
printf '\nInitiating Homebrew update...\n'
brew update

printf '\nInstalling packages...\n'
brew install ${PACKAGES[@]}

printf '\n\nRemoving out of date packages...\n'
brew cleanup

printf '\n\nInstalling cask apps...\n'
brew install --cask ${CASKS[@]}

{{ end -}}

Even if you are not familiar with sh, it shouldn't be too difficult to understand. Define the PACKAGES list for packages installed with brew install and CASKS for applications installed with brew install --cask. The installation process will be carried out by the script.

Scripting is a relatively complex feature among the functionalities available in chezmoi. There are various ways to apply it, and the same function can be defined differently. For more detailed usage, refer to the official documentation.

Conclusion

In this post, I summarized useful chezmoi settings following the basic usage explained in the previous post. The usage of the script I introduced at the end may seem somewhat complex, contrary to the title of basic settings, but once applied, it can be very convenient to use.

Reference

Managing Dotfiles Conveniently with Chezmoi

· 7 min read
Haril Song
Owner, Software Engineer at 42dot

Have you ever felt overwhelmed at the thought of setting up your development environment again after getting a new MacBook? Or perhaps you found a fantastic tool during work, but felt too lazy to set it up again in your personal environment at home? Have you ever hesitated to push your configurations to GitHub due to security concerns?

If you've ever used multiple devices, you might have faced these dilemmas. How can you manage your configurations consistently across different platforms?

Problem

Configuration files like .zshrc for various software are scattered across different paths, including $HOME (root). However, setting up Git at the root for version control of these files can be daunting. The wide range of scanning involved can actually make managing the files more difficult.

Maintaining a consistent development environment across three devices – a MacBook for work, an iMac at home, and a personal MacBook – seemed practically impossible.

Modifying just one Vim shortcut at work and realizing you have to do the same on the other two devices after work... 😭

With the advent of the Apple Silicon era, the significant disparity between Intel Macs and the new devices made achieving a unified environment even more challenging. I had pondered over this issue for quite some time, as I often forgot to set up aliases frequently used at work on my home machine.

Some of the methods I tried to solve this problem briefly were:

  1. Centralizing dotfiles in a specific folder and managing them as a Git project

    1. The locations of dotfiles vary. In most cases, there are predefined locations even if they are not in the root.
    2. You cannot work directly in a folder with Git set up, and you still have to resort to copy-pasting on other devices.
  2. Symbolic link

    1. To set up on a new device, you need to recreate symbolic links for all files in the correct locations(...). If you have many files to manage, this can be a tiresome task.
    2. The usage is more complex than Git, requiring attention to various details.

In the end, I resorted to using the Git method but only for files not in the root (~/.ssh/config, ~/.config/nvim, etc.), partially giving up on files using the root as the location (~/.zshrc, ~/.gitconfig, etc.) until I discovered chezmoi!

Now, let me introduce you to chezmoi, which elegantly solves this challenging problem.

What is Chezmoi?

Manage your dotfiles across multiple diverse machines, securely. - chezmoi.io

Chezmoi is a tool that allows you to manage numerous dotfiles consistently across various environments and devices. As described in the official documentation, with just a few settings, you can ensure 'security'. You don't need to worry about where your dotfiles are or where they should be. You simply need to inform chezmoi of the dotfiles to manage.

Concept

How is this seemingly magical feat possible? 🤔

In essence, chezmoi stores dotfiles in ~/.local/share/chezmoi and when you run chezmoi apply, it checks the status of each dotfile, making minimal changes to ensure they match the desired state. For more detailed concepts, refer to the reference manual.

Let's now briefly explain how to use it.

Getting Started with Chezmoi

Once you have installed chezmoi (installation guide here), perform the initialization with the following command:

chezmoi init

This action creates a new Git repository in ~/.local/share/chezmoi (working directory) on your local device to store dotfiles. By default, chezmoi reflects modifications in the working directory on your local device.

If you want to manage your ~/.zshrc file through chezmoi, run the following command:

chezmoi add ~/.zshrc

You will see that the ~/.zshrc file has been copied to ~/.local/share/chezmoi/dot_zshrc.

To edit the ~/.zshrc file managed by chezmoi, use the following command:

chezmoi edit ~/.zshrc

This command opens ~/.local/share/chezmoi/dot_zshrc with $EDITOR for editing. Make some changes for testing and save.

info

If $EDITOR is not in the environment variables, it defaults to using vi.

To check what changes have been made in the working directory, use the following command:

chezmoi diff

If you want to apply the changes made by chezmoi to your local device, use the following command:

chezmoi apply -v

All chezmoi commands can use the -v (verbose) option. This option visually displays what is being applied to your local device, making it clear in the console. By using the -n (dry run) option, you can execute commands without applying them. Therefore, combining the -v and -n options allows you to preview what actions will be taken when running unfamiliar commands.

Now, let's access the source directory directly and push the contents of chezmoi to a remote repository. It is recommended to name the repository dotfiles, as I will explain later.

chezmoi cd
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/$GITHUB_USERNAME/dotfiles.git
git push
tip

By writing the relevant settings in the chezmoi.toml file, you can automate the repository synchronization process for more convenient use.

To exit the chezmoi working directory, use the following command:

exit

Visualizing the process up to this point, it looks like this:

image

Using Chezmoi on Another Device

This is why we use chezmoi. Let's fetch the contents on the second device using chezmoi. I have used an SSH URL for this example. Assume that chezmoi is already installed on the second device.

chezmoi init git@github.com:$GITHUB_USERNAME/dotfiles.git

By initializing with a specific repository, chezmoi automatically checks for submodules or necessary external source files and generates the chezmoi config file based on the options.

Inspect what changes chezmoi will bring to the second device using the diff command we saw earlier.

chezmoi diff

If you are satisfied with applying all the changes, use the apply command we discussed earlier.

chezmoi apply -v

If you need to modify some files before applying locally, use edit.

chezmoi edit $FILE

Alternatively, you can use a merge tool to apply local changes as if you were using Git merge.

chezmoi merge $FILE
tip

Using chezmoi merge-all will perform a merge operation on all files that require merging.

You can perform all these steps at once with the following command:

chezmoi update -v

Visualizing this process, it looks like this:

image

You can also apply all the steps needed on the second device at initialization...! This feature can be incredibly useful if the second device is a newly purchased one.

chezmoi init --apply https://github.com/$GITHUB_USERNAME/dotfiles.git

I recommended naming the repository dotfiles earlier because if the repository is named dotfiles, you can use a shortened version of the previous command.

chezmoi init --apply $GITHUB_USERNAME

image

It's truly convenient...🥹 I believe it will be one of the best open-source tools discovered in 2023.

Conclusion

Chezmoi is impressively well-documented and actively developed. Developed in Golang, it feels quite fast 😄. With some knowledge of shell scripting, you can implement highly automated processes, creating an environment where you hardly need to intervene for settings across multiple devices.

In this article, I covered the basic usage of chezmoi. In the next article, we will delve into managing chezmoi configuration files and maintaining security.

info

If you are curious about my configurations, you can check them here.

Reference