Skip to content

dotkit-run/example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dotkit example

A reference kit showing the folder structure, file formats, and execution order used by dotkit.

Provision a new machine

curl dotkit.run/sh | sh

Pass options with --. See dotkit-run/install for more details.

curl -fsSL dotkit.run/sh | sh -s -- --defaults

Day-to-day

The examples below are assuming an active profile is set. So all "paths" are relative to that active profile. In this repo, the active profile would be called kit and its base dir would be ./profiles/kit.

# re-apply symlinks
dotkit link dotfiles

# re-run a package file
# tries to resolve missing file extension
# in order of .sh, .txt, then .md
dotkit run packages/brew

# add data to a run script's map block
# and execute added data with its parent map template
# this is a good way to update your dotkit
# and install packages on your system
dotkit add kit/packages/brew

Folder structure and execution order

dotkit apply processes folders by default in this order:

dotkit/
  profiles/
    kit/
      configs/
      tools/
      packages/
      <other run dirs>/
      <link dirs>/
      <todo dirs>/
      profile.env
  .gitignore
  dotkit.env
  1. configs - System preferences or that which requires no additional dependencies
  2. tools - Package managers and CLI toolchains (e.g. brew, npm, cargo can be used to install global packages)
  3. packages - Apps and packages installed via tools
  4. Other run folders, alphabetically
  5. Folders with link.env file - symlink farms
  6. Folders with todo.env - manual checklists

configs, tools, and packages are reserved names always run in that order, but their presence is not required. You could just as easily have a tasks folder and put everything in there instead, and it will be executed alphabetically in that subfolder.

The ordering can also be overridden with an order.txt file. You could place a tasks folder in between tools and packages as such:

> cat kit/order.txt
configs
tools
tasks
packages

Even more simply, it will identify that the reserved name packages has been ordered differently. The below example will execute in the same order as the example above:

> cat kit/order.txt
tasks
packages

Folder type markers

There are three kinds of folders:

  • run (default)
  • link (symlink farms)
  • todo (manual checklists)

They can be denoted by an .env file at the root of each folder. If no .env file is found, it will default to a "run" folder. If more than one applicaple .env file is found, the program will throw an error.

dotkit apply will source any dotkit.env in the root folder, followed by the profile's profile.env. And then any additional run, link, todo .env files will be sourced for each subfolder under profiles/kit/.

File Type Effect
link.env link dotkit link - symlinks your dotfiles
todo.env todo dotkit todo - generates a checklist
run.env run env vars sourced before running scripts
(none) run files executed with dotkit run

run.env

Run folders are only executed at that level. Subfolders are not executed. That way you can place additional info/data/runners inside subfolders for your base-dirs run files.

# env vars available to all scripts in this folder
DEV_DIR=$HOME/dev
GITHUB_USER=yourname

link.env

A link.env file can designate a target location. Therefore running dotkit link on that folder will automatically apply it to the correct location.

# destination for symlinks
DEST=~

# same thing, also equivalent to
DEST=$HOME

todo.env

A todo.env can designate a custom output location as well. If you want the To-do to show up on your desktop, you can set it to ~/Desktop or such. Since generating these files can clutter your personal dotkit's repo, it is recommended to have a .gitignore file with a line like **/TODO.md in it.

# output location (relative to todo.env)
DEST=..

# output filename (default: TODO.md)
NAME=MANUAL.md

# H1 heading (default: folder name)
TITLE="My Setup Checklist"

Order of operations

configs/ - Applied first because they have no dependencies. System preferences (dock layout, keyboard repeat rate, default browser) can be set on a brand new machine before anything is installed. Running these early means your environment feels right from the start, even mid-setup.

tools/ - The bootstrap layer. These install the package managers and toolchains everything else depends on: Homebrew, Rust/cargo, Node/fnm, Python/uv. A tools file can also install formulae that unlock later steps - for example, installing mas (Mac App Store CLI) here so the packages step can use it.

packages/ - With tools in place, install everything else: applications, global packages, fonts, casks. These files can use the package managers installed in the tools step.

Any remaining folders - Any additional folders without a type marker (or with run.env) run next.

Link folders - Folders with a link.env file are treated as symlink farms. This link.env file is required! Dotkit cannot parse the folder properly without it. It will not know whether to treat it as a run folder or not. In folders with a link.evn, dotkit link is called for each, symlinking every file to the configured destination. These run after all plain run folders because some tools or packages may need to be in place for the shell config to work correctly. Any existing file will be backed up in the same place before placing a symlink at its location.

Todo folders - Folders with a todo.env file generate a TODO.md checklist of manual steps that can't be automated: signing in to accounts, configuring VPN, installing apps that need a GUI, etc. These run last.

File formats

Dotkit files come in two flavors - .txt for structured blocks, .md for readable markdown. Both produce the same result. Dotkit cli also comes with helpful functions for shell scripts as well (e.g. dotkit map). Any .sh file found in a run folder will also be executed.

Block types

All txt and md files are parsed into shell scripts. Text files separate blocks by --- lines and Markdown files separate based on ## headers. Block types:

  • try <cmd> - run fallback commands in block only if cmd in first line fails
  • map <template> - run template once per data line, substituting {{1}}, {{2}}, {{3}} ...etc.
  • In map blocks item and key are aliases for 1. value is an alias for 2.
  • Elements of map block data lines are delimited by space-padded equal signs =.
  • ask - can be one of three kinds of interactive prompts.
  • Anything not starting their block with a try, map, or ask is plain shell, run all lines in that block as-is.

.txt format

Blocks are separated by ---. Lines beginning with # are comments. The first non-comment line of each block sets the type:

try command -v brew
NONINTERACTIVE=1
dotkit install https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh
for p in /opt/homebrew /usr/local ~/.linuxbrew; do eval "$($p/bin/brew shellenv 2>/dev/null)" 2>/dev/null || true; done
---
map brew install {{item}}
gh
git
ripgrep
neovim
---
map brew install --cask {{item}}
firefox
visual-studio-code

You can see here that a tools folder isn't necessary to pre-install homebrew. It can be part of your packages file as a try block. If it doesn't find it, it will install it for you, if it's found on the system, it skips that block and goes straight into the brew install {{item}} section. You could put in shell commands as well. For example, if you know you'll need mas to install Mac App Store, you could place that before the first map block as it's own line brew intall mas. Since brew install mas doesn't begin with a try, map, or ask, it will be executed as a shell command. And at the very bottom you could add another map block for mas items such as:

map mas install -y {{item}}

# Xcode
497799835

# WhatsApp
310633997

.md format

2nd-level Headers mark the block type. The first bullet is the rest of the command. Subsequent bullets are used for commands/data lines. Map templates do not use {{ }} but rather are marked in ** ** bold.

Lines without any ## or - at the start, are treated as comments. So a top-level header like # Title is not parsed by dotkit. Neither is something like Use github script: on it's own line.

Markdown links are parsed into plain URLs (whatever was in the parentheses).

# Install Homebrew & Formulae

This will check if homebrew is installed on the machine and also installs formulae.

## try

- command -v brew
- dotkit install [install.sh](https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)

## map

- brew install **item**
- gh
- ripgrep

**item** in markdown maps to {{item}} in the text format.

License

This repo is licensed under the BSD Zero Clause License, which is a modified ISC license. It is a permissive one that does not require any attribution. So forks/derivatives of this repo may add/modify/delete any and all files including the LICENSE itself.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages