./setup.shDetects the current OS, installs packages, symlinks configs, and runs OS-specific configuration scripts.
setup.shneeds a genuine MSYS2 UCRT64 shell to run in, which a stock Windows install doesn't have yet.
powershell -ExecutionPolicy Bypass -File .\bootstrap.ps1Installs MSYS2 if it isn't already present, then runs ./setup.sh inside
a real UCRT64 shell.
scripts/get-os.sh identifies the current OS and returns a key such as
linux-arch, macos, or windows. This key is used throughout to select
the right configs and scripts. The OS is identified from $OSTYPE (set by
the shell). When running inside WSL, $WSL_DISTRO_NAME (set by the WSL
kernel for all WSL processes) is used to distinguish WSL from a native Linux
host so that WSL-specific scripts apply.
scripts/install.sh runs every install-*.sh script found in
scripts/<os>/, installing packages and tools for that OS. Where one script
genuinely depends on another running first, it's named
install-<order>-<name>.sh (a two-digit prefix, e.g. 10, 20, 50 -
same idea as configs/linux-arch/.zsh.d/'s numbered drop-ins) so the plain
directory listing sorts them correctly; everything else is just
install-<name>.sh, with no ordering guarantee relative to the others.
scripts/configure.sh iterates over configs/<os>/ and creates a symlink
in $HOME for each tracked file or directory. Only files tracked by git are
linked - untracked files are skipped. If something already exists at the
target path, it is backed up with a timestamp suffix before being replaced.
It then re-sources ~/.profile, so the PATH changes made by the
installation step above (e.g. newly installed tools) are picked up before
continuing.
Finally, it runs every configure-*.sh script found in scripts/<os>/.
These handle OS-specific setup that can't be expressed as a config file
(registry entries, service enablement, symlinks outside $HOME, etc.).
On Windows, there is additional ceremony involved. The shell is zsh running inside MSYS2, which provides a Unix-like layer over Win32. Several things need to be massaged into place to make it behave consistently:
~/.configis symlinked toAppData/Roamingsince Windows doesn't follow XDG conventions, so config files land where apps expect them.- Symlinks require
MSYS=winsymlinks:nativestrictto produce real Windows native symlinks rather than MSYS copies or junctions. Set inconfigs/windows/.env.localfor regular shells, but also explicitly in every setup/configure script that creates a symlink -.env.localonly exists first afterconfigure.shhas symlinked it into place at least once, so scripts that run before or during first-time setup can't rely on it. - Some setup can't go through dotfiles at all and is applied directly:
registry imports via
reg.exe, persistent env vars viasetx, and autostart/Start Menu shortcuts copied into the appropriate Windows directories. scripts/windows/require-ucrt64.shrefuses to continue outside a genuine MSYS2 UCRT64 shell (checked via$MSYSTEM, sinceuname -scan't tell UCRT64 apart from MINGW64) rather than limping along in the wrong subsystem, and points tobootstrap.ps1or the UCRT64 shortcut instead.setup.sh,scripts/install.sh, andscripts/configure.sheach source it independently, since any of them can be run standalone rather than only viasetup.sh.
setup.sh # entry point
bootstrap.ps1 # Windows only: gets a fresh machine to a UCRT64 shell, then runs setup.sh
configs/
<os>/ # files here get symlinked to $HOME
.zshrc
.bashrc
.config/
...
scripts/
get-os.sh # OS detection
install.sh # runs install-* scripts for the OS
configure.sh # symlinks configs/, runs configure-* scripts
<os>/
install-*.sh # package/tool installation (install-<order>-<name>.sh if order matters)
configure-*.sh # post-install configuration
windows/
require-ucrt64.sh # guard: refuse to run outside genuine MSYS2 UCRT64Drop the file or directory into configs/<os>/ and git add it. The next
run of setup.sh (or scripts/configure.sh directly) will symlink it.
Files shared across platforms live under the most complete platform (currently
linux-arch) and are symlinked or referenced from other platforms where needed.