Skip to content

wilsonmar/dotfiles

Repository files navigation

url lastchange
v005 + mac-setup flows :README.md

dotfiles.png

WHY? This was created so that you can legitimately add to your resume and LinkedIn profile:

    Configured, on new Macs, from scratch, a large set of utilities, languages tools, local AI apps, and access to AWS, Azure, and Google cloud services. The custom automation reduces onboarding errors and time from days to less than an hour. Documentation of steps were validated by others. With a common set of tools, teams can now pair-program together efficiently. This makes it easy to achieve cybersecurity directives about keeping all software up-to-date frequently.

Customize the Base dotfiles

This wilsonmar/dotfiles repo currently makes use of open-source project named chezmoi (pronounced /ʃeɪ mwa/ (shay-mwa), a French phrase for "my home"). Chozmoi was created in 2021 by Zurich-based paraglider Tom Payne. Like many others, I coverted to Tom's Chezmoi from the custom CLI shell scripts I refined over several years at wilsonmar/mac-setup, as described at https://wilsonmar.github.io/mac-setup. My approach used a clumsy way to initiate utilities on a new macOS machine:

chezmoi-mac-setup-1710x780.png

Both approaches makes use of the default internet browser app (Safari), and type in the URL of the sample dotfiles repository in GitHub to fork it under the GitHub account of the new user. The browser can be used to edit (customize) the sample install files.

But the clumsy way of my mac-setup repo is to, on the new machine, click the "Code" button to click "Download.ZIP". Open the Finder app to Navigate to the "Downloads" folder, then drag-and-drop custom installer scripts to the user's home directory.


Advantages of Chezmoi

Use of Chezmoi similifies the above process solves several problems. Chezmoi has several advantages:

With Chezmoi, a user simply opens the Terminal app and executes the following command:

sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply $GITHUB_USERNAME

This uses the curl command already on the macOS.

??? where $GITHUB_USERNAME is the user name of the GitHub account where the Dotfiles repo is stored.

The command above downloads and installs an editor and other utilities specified among "dotfiles".

managing multiple dotfiles across multiple machines.

Conventions

dotfiles repository

Chezmoi assumes that install configuration files are within a dotfiles repository, like other options to automate installation, such as the symlink farm manager GNU Stow for Linux.

File dotfiles/.chezmoi.yaml at the repository's root specifies the repository's structure of folders and files.

Chozmoi looks for a Bash shell script file named install.sh to define folders on the machine.

This would include the variable script_folder which defines the location (file path)of the script.

The install.sh script is executed by the chezmoi utility.

Fork chezmoi dotfiles repo

  1. In an internet browser, click this URL to open it:

    https://github.com/twpayne/chezmoi

  2. You need to have created your own GitHub account.

  3. Click the "Start" if you find it helpful.

  4. Click "Fork" on the upper-right corner so that you have the version of the utility if the repo ever goes away.

  5. Note the release version identifier. At time of writing, it was "v2.50.0".

Single curl command

This automation script is idempotent. The script detects what has already been installed, then verifies the success of each step. It performs workarounds for known issues.

Chezmoi's approach has users craft a single curl command on the Terminal of a new, empty machine, Chezmoi retrieves the dotfiles repository of a named GitHub.com user. Specifications and scripts in that repo controls all Chezmoi installs.

The curl is built-in to macOS. But if you prefer to use wget:

  1. Install Apple's Command Line Tools using this built-in command:
    xcode-select --install
    
  2. Install Homebrew at https://brew.sh. VIDEO:
  3. Use brew to install wget:
    brew install wget
    
  4. Verify install of wget:
    wget -V
    

NOTE: wget references a certificate at default location at /etc/ssl/cert.pem

Public Dotfiles

Chezmoi uses the value within system variable $GITHUB_USERNAME to construct the Dotfiles repository URL where it obtains configuration files controlling installation.

    REMEMBER: The user's GitHub repository must be named "Dotfiles".

Manual actions described below make use of the most simplistic Dotfiles repo at:

Chezmoi is widely used, so it's interesting to explore the different hacks, configurations, and time-saving automations developers have in their dotfiles. Search for "dotfiles chezmoi" onx GitHub:

https://github.com/search?q=dotfiles%20chezmoi&type=repositories

The simplest case is if the Dotfiles repository is public. Then, the https:// protocol is used to install into the default folder $HOME/.local/bin (which Chezmoi creates):

GITHUB_USERNAME="johndoe"
sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply $GITHUB_USERNAME

Chezmoi Commands

https://www.chezmoi.io/user-guide/command-overview/

Once Chezmoi is installed, chezmoi init creates chezmoi's source directory and a git repo on a new machine.

Chezmoi Config files

By default, Chezmoi stores machine-specific config file at ~/.config/chezmoi/chezmoi.toml It contains entries such as this to set the default text editor to use Visual Studio Code:

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

The above configuration entry can also be set using CLI command:

export EDITOR="code --wait"

Rather than using a text editor, Chezmoi provides commands:

chezmoi data prints the available template data.

chezmoi add --template $FILE adds $FILE as a template.

chezmoi chattr +template $FILE makes an existing file a template.

chezmoi cat $FILE prints the target contents of $FILE, without changing $FILE.

chezmoi execute-template for testing and debugging templates.

Chezmoi Template files

folders

By default, Chezmoi stores the source state at ~/.local/share/chezmoi

The config file is used to configure the source state used to generate the destination state.

The target state is the desired state of the destination directory.

The target state includes regular files and directories, and may also include symbolic links, scripts to be run, and targets to be removed.

Private Dotfiles

If the user's dotfiles repository is private, and git has been configured, the git@ protocol is used in the command:

GITHUB_USERNAME="johndoe"
sh -c "$(curl -fsLS get.chezmoi.io)" -- -b $HOME/.local/bin \
   init --apply [email protected]:$GITHUB_USERNAME/dotfiles.git

Use of sh (shell) means the command is portable to any machine which has the POSIX shell provided by default on popular operating systems (macOS, Linux, Windows).

Chezmoi has 4 areas where it stores data: "Remote repo", "Working copy", "Home directory", "local repo".

  • Like other Git-controlled projects, the "Working copy" area is the local copy of the remote repo in GitHub.

  • Also like Git, chezmoi init creates the "Working copy" area.

  • If a $GITHUB_USERNAME is specified with chezmoi init, that user's "dotfiles" repo is cloned into the "Working copy" area.

  • As with other Git repos, the "git commit" commits changes from the "Working copy" area to the local repo area, from which the "git push" pushes changes from the "Working copy" area to the remote GitHub repo.

  • QUESTION: What is there a chezmoi add command like git add?

  • chezmoi init --apply $GITHUB_USERNAME clones the remote repo into the "Home direcotry" area.

  • chezmoi update $GITHUB_USERNAME updates the remote dotfiles repo into the "Home direcotry".

chezmoi-setup-1690x500.png

  • The apply parameter copies the remote repo into the "Home directory" area.
  • The apply parameter without the remote repo copies from "Working copy" to "Home directory".

chezmoi-git-1686x465.png

The -b parameter tells the script to install in a folder other than the default /.local/bin /bin which does not require root (sudo) access and the need to type in a password.

So we download that as the starting point to adapt it for our own use.

  • In the assets folder, I don't have a Keychron K2 Pro Wireless Mechanical Keyboard, so I don't need his keychron json files.
  • I replaced his [email protected] photo file with my own.
  • In folder Documents/WindowsPowerShell Microsoft.PowerShell_profile.ps1 file containing:
$env:Path += ";$env:UserProfile\bin"
Set-Alias -Name g -Value git

Operating Systems

In folder home/.chezmoiscripts is a file for each operating system:

  • darwin
  • linux
  • windows

File run_onchange_after_configure-dock.sh lists Apple apps to remove from the Dock. QUESTION: DOes this remove files of apps not wanted (to save disk space)?

Within home/.chezmoiscripts/darwin are:

  • run_onchange_before_install-google-earth-pro.sh updates rosetta as well

  • run_onchange_before_install-packages.sh.tmpl lists brew packages to install

  • run_onchange_after_configure-defaults.sh lists commands instead of Apple System Settings GUI. TODO: replace with mac-setup/mydotfile.sh which lists commands by System Settings GUI menu order.

  • run_onchange_after_configure-notificationcenter.sh

  • run_onchange_after_configure-desktop.sh says "osascript -e 'tell application "System Events" to tell every desktop to set picture to "/System/Library/Desktop Pictures/Solid Colors/Space Gray Pro.png" as POSIX file'

~/Library/Fonts/ contains .ttf files

Automation using Lua

Hammerspoon is a desktop automation tool bridges the macOS operating system to the Lua scripting language in .lua files. It's installed using:

brew install --cask hammerspoon

which creates a .hammerspoon folder containing init.lua - the primary configuration file where users can write custom automation scripts.

Aliases (Keyboard shortcuts)

In file home/dot_bash_aliases.tmpl

  • dot_bash_aliases.tmpl sets keyboard aliases. TODO: macsetup/aliases.sh

VSCode Extensions

File home/.chezmoiscripts/run_onchange_after_configure-vscode.sh.tmpl adds extentions. TODO: Reconcile list at vscode-ext-all.txt.

Tom's install.sh script sets chemoi's installation folder

script_dir="$(cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P)"
echo $script_dir

On a macOS Silicon machine, the output is:

/opt/homebrew/bin

On a macOS Intel machine, the output is:

/usr/local/bin

Tom's home/private_dot_config folder contains repository a file for each CLI package to install:

  • forge
  • git
  • homebrew
  • nvim
  • private_karabiner
  • psql
  • readline
  • ripgrep
  • tmux
  • wezterm - A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust

I add:

  • warp (improved CLI)
  • gh (GitHub.com CLI)
  • ???

QUESTION: What about apps?

Secrets handling

Chezmoi's functionality include integration with password manager 1Password app.

See https://www.chezmoi.io/user-guide/tools/editor/

  1. TODO: Install 1Password app

  2. TODO: Install the 1Password CLI

  3. Edit file home/dot_zshrc.tmpl

    {{- if .personal }}
    export CHEZMOI_GITHUB_ACCESS_TOKEN={{ onepasswordRead "op://chezmoi/chezmoi GitHub API Token/credential" .onepasswordAccount | trim }}
    {{-   if eq .chezmoi.os "darwin" }}
    {{-   end }}
    {{- end }}
    
  4. Invoke 1Password's "op" command for signing into 1Password as API:

eval $(op signin)

Files which vary from machine to machine are executed as templates, typically using data from the local machine's config file to tune the final contents specific to the local machine.

Edit each ".tmpl" (template) file in home/private_dot_ssh folder:

Edit file authorized_keys.tmpl to change "twpayne" to your own GitHub user name (which TODO: should be templatized):

{{ range (gitHubKeys "twpayne") -}}
{{   .Key }}
{{ end -}}

Also edit the name TODO: exchange with a variable? at:

  • home/private_dot_config/git/config.tmpl
  • home/.chezmoiscripts/run_onchange_after_configure-vscode.sh.tmpl

Although you can use JSON or YAML:

  • home/private_dot_config/forge/forge.toml.tmpl
  • home/.chezmoi.toml.tmpl
  • home/.chezmoiexternal.toml.tmpl contains several external websites specific to twpayne

Edit file home/private_dot_ssh/config.tmpl to contain only the web properties you use (github.com), and remove the others.

Files home/private_dot_ssh/id_rsa.pub.tmpl and private_id_rsa.tmpl contains the onepasswordRead function to read secrets from 1Password:

{{ if .flarm -}}
{{   onepasswordRead "op://FLARM/SSH Key/public key" .onepasswordAccount }}
{{ else if .personal -}}
{{   onepasswordRead "op://Personal/SSH Key/public key" .onepasswordAccount }}
{{ end -}}

Replace "FLARM" and "flarm" (which stands for "FLight alARM"), the enterprise work machine Tom uses for, with the keyword for your work machine.

Also edit:

  • home/.chezmoi.toml.tmpl defines boolean feature tags used by other Chezmoi template files.

  • home/dot_zshrc.tmpl to configure .zshrc

  • home/dot_p10k.zsh.tmpl to configure the Powerlevel10k theme customization tool specified in file .zshrc for Zshell on top of "Oh My ZSH" already installed. CAUTION: As of 2024, the project is reportedly in "life support mode", with some developers suggesting alternatives like Oh My Posh.

  • home/private_dot_ssh/config.tmpl

  • home/private_dot_config/forge/forge.toml.tmpl

  • home/private_dot_ssh/private_id_rsa.tmpl

Dotfiles locally

By default, Chezmoi stores the desired state of your dotfiles in the directory

~/.local/share/chezmoi

Dotfiles are idempotent.

Base on Golang

Unlike Python and Java, which first require a compiler to be installed, Chezmoi's binary was created using the Go language, which has no dependencies.

The internal/uv.lock file is used by the package manager UV to prevent concurrent access to the Go runtime.

Variables in .gitconfig

~/.gitconfig that controls Git is an example of a dotfile.

Within the dotfiles repository, Variables can be used to vary configuration settings for different environments (such as work and personal machines).

BLOG: This sample file uses Go’s text/template syntax to first check if email and name variables exist using the hasKey function so that it can fall back to default values if a custom value is not provided.

[user]
    email = {{ if hasKey . "email" }}{{ .email | quote }}{{ else }}"[email protected]"{{ end }}
    name = {{ if hasKey . "name" }}{{ .name | quote }}{{ else }}"John Doe"{{ end }}
[core]
    excludesFile = "{{ .chezmoi.homeDir }}/.gitignore_global"
[pull]
    rebase = false
[init]
    defaultbranch = main
[merge]
    ff = no
    commit = no

Go's hasKey function references values in Chezmoi's config file at

~/.config/chezmoi/chezmoi.toml

Google Sign-in pop-up

To disable Google sign-in prompts across your accounts:

  1. Go to https://myaccount.google.com
  2. Click "Security" on the left menu.
  3. Click "See All Connections"
  4. Click the gear icon
  5. Turn off the "Google Account Sign-in Prompts" toggle

The above needs to repeated for each of your Google accounts:

Fonts

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published