Commit a6f9589
authored
Linux support (#1)
* feat: detect the platform and dispatch per os
The installer hardcoded macos/install and macos/update, so a Linux run went
straight into fdesetup, defaults and softwareupdate. utils/os detects the
system once and the scripts dispatch to the matching topic instead.
Constants that differ per platform (projects directory, font directory, the
iCloud store) move here too, and force_link replaces the BSD-only 'ln -Fs'
and 'ln -sfh' spellings, which GNU ln rejects.
* feat: add a linux topic
Linux is a headless configuration target, not a provisioning one: nothing here
calls a package manager or asks for sudo. linux/tooling installs the few tools
the other topics depend on into $HOME (fnm, uv, starship), linux/install
reports the system packages that are missing with the exact install line, and
linux/aliases.zsh and linux/functions.zsh are the counterparts to the macOS
ones β clipboard() for pbcopy, notify-send for terminal-notifier, resolvectl
for dscacheutil.
Deliberately no 'ip' alias: on Linux that is iproute2's own command.
* fix: skip the macOS-only topics on linux
Homebrew, iTerm2, Zed, fonts and the iCloud-synced Claude state all guard
themselves now and report a skip rather than failing.
The Claude one mattered most: with no iCloud Drive present it would create a
fake 'Library/Mobile Documents' tree on a Linux box and then move the real
~/.claude into it. The private-file linking in system/install had the same
blind spot and warned once per file instead of once.
tmux keeps working β TPM and the sidebar patches are portable β only the
launchd dark-mode watcher is macOS-bound. tmux.conf falls back to
DOTFILES_THEME since 'defaults' does not exist to read the appearance from.
* fix: make the shell config load on linux
Two unguarded evals ran on every shell start: '/opt/homebrew/bin/brew shellenv'
in system/paths.zsh and 'pyenv init -' in python/paths.zsh. Neither exists on a
Linux box, so both printed an error before the prompt appeared. The brew prefix
is probed now, and the pyenv eval is dropped β system/paths.zsh already does a
cached init, so it was running twice on macOS as well.
The **/aliases.zsh glob also pulled in macos/aliases.zsh regardless of platform,
shadowing working aliases with pbcopy and defaults calls. All three loaders skip
the other platform's topic now, and the macOS-only entries moved out of
system/aliases.zsh into macos/ where the loader can exclude them.
Also fixes three things this uncovered:
- CODE_DIR was only ever set in utils/constants, which the shell never sources,
so $PROJECTS and $PROJECT_HOME were both silently empty
- the dclint and 8000 aliases were double-quoted, so $(pwd) and the lsof
lookup were expanded once at load time and baked in
- copyssh still pointed at id_rsa.pub, while git/install generates ed25519
* fix: make git work off macOS
gitconfig pinned gpg and gh to /opt/homebrew, so with commit.gpgsign on every
commit failed on a machine without Homebrew, and the GitHub credential helper
went with it. Both resolve from $PATH now.
git/install picked osxkeychain, --apple-use-keychain, UseKeychain and
pinentry-mac unconditionally β OpenSSH rejects the keychain options outright
elsewhere. Each has a Linux branch now: libsecret when the distribution built
it, the in-memory cache otherwise (never 'store', which writes credentials to
disk in plain text), and pinentry-curses so signing still works over ssh.
The devguard includeIf gained a ~/code counterpart, since the projects
directory differs per platform.
* fix: stop one missing tool aborting the whole run
Under 'set -e' several topics took the entire installer down when a tool was
absent, which is the normal state on a box these dotfiles do not provision:
- node and python called fail_hard on a missing fnm or uv
- zsh/update ran 'sh /tools/upgrade.sh' when $ZSH was unset, i.e. on any
machine that had not been through the installer yet
- zsh/install ran the oh-my-zsh installer, which bails when zsh is missing
- herdr aborted when the installer had no build for the platform
All of them warn and skip now. vim/install also asks for neovim explicitly and
installs plugins with nvim rather than vim β the autoload path it writes to is
neovim's, so plain vim reported success without ever loading plug.vim.
* chore: document linux support and soften the linter
The README claimed macOS or Linux while the code only ever ran on macOS. It now
describes what Linux actually gets: configuration plus $HOME-local tooling, no
package manager, no sudo, with the missing packages reported at the end.
scripts/lint skips zsh and ruby when they are not installed instead of failing,
matching how it already treats shellcheck β CI installs both explicitly, so
coverage is unchanged. 'dotfiles -e' falls back through $VISUAL and $EDITOR to
a terminal editor, since a headless box has no GUI editor to hand over to.
* feat: install declared system packages on linux
linux/packages is the counterpart to homebrew/Brewfile: a declared list of
system packages, installed with apt when missing. It replaces the earlier
report-only behaviour, so a fresh box reaches a working shell from
'dotfiles -i' alone rather than from a warning telling you what to type.
Entries are 'probe:package' because the two halves cannot be derived from each
other β nvim comes from neovim, delta from git-delta β and a probe may be a
file rather than a command, which is how the two zsh plugins are detected.
Alternatives separated by '|' cover the Debian-renamed binaries (bat/batcat,
fd/fdfind).
Packages install from linux/tooling, early enough that zsh/install and
vim/install find what they need, and 'dotfiles -u' picks up newly declared
entries the way 'brew bundle' does. The update also upgrades installed
packages, mirroring brew upgrade and softwareupdate on the mac.
Sudo is requested only when something is actually missing, so the usual run
never prompts, and a machine without sudo reports what to run instead of
failing. unzip is declared because fnm's installer refuses to run without it,
which is how it was found.
* fix: let ~/.gitconfig.local actually own the identity
Two bugs that only show on a fresh machine, found setting this up on linux.
create_symlinks runs from system/install, several topics before git/install
generates gitconfig.local.symlink β so on a first run the file did not exist
yet when the symlinker looked, ~/.gitconfig.local was never created, and the
[include] resolved to nothing. git/install links the file it generates now.
Even with the link in place the identity was ignored: gitconfig.symlink has
the [include] at the top but carried a hardcoded [user] block near the bottom,
and in git the later value wins. So the name and email entered at the prompt
were overridden by the committed ones, and a personal address shipped in a
public repository for no benefit. The block is gone; the per-machine file is
the only thing that sets an identity, which is what the installer generating
it implied all along.
github.user also took AUTHORNAME, writing a person's name where tooling wants
an account name, so it is prompted for separately.
* fix: report when the installer finishes
The closing message was commented out, so 'dotfiles -i' ended on whatever the
last topic happened to print and read as though it had stopped partway. The
updater has always said when it was done β this makes the two match.
* fix: run the oh-my-zsh upgrade with zsh, not sh
upgrade.sh declares '#!/usr/bin/env zsh' and uses 'local' at the top level, but
it was being invoked through 'sh'. On macOS that is bash, which tolerates it;
on debian it is dash, which rejects it with 'local: not in a function' and
exits 2. Since the output went to /dev/null and 'set -e' was on, every
'dotfiles -u' on linux died silently at 'Update [zsh]' β two topics in, with
node, python, tmux, herdr and the platform update never running at all.
Now invoked with zsh, and a failure warns and points at the script instead of
ending the run. vim/update gets the same treatment: a plugin that fails to
fetch should not take everything after it down either.1 parent 49f3a41 commit a6f9589
46 files changed
Lines changed: 907 additions & 120 deletions
File tree
- bin
- claude
- fonts
- git
- herdr
- homebrew
- iterm2
- linux
- macos
- node
- python
- scripts
- system
- tmux
- utils
- vim
- zed
- zsh
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
25 | 52 | | |
26 | 53 | | |
27 | 54 | | |
| |||
58 | 85 | | |
59 | 86 | | |
60 | 87 | | |
61 | | - | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
62 | 98 | | |
63 | 99 | | |
64 | 100 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
39 | | - | |
40 | | - | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
41 | 49 | | |
42 | 50 | | |
43 | 51 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
7 | 14 | | |
8 | 15 | | |
9 | 16 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
7 | 11 | | |
8 | 12 | | |
9 | 13 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
6 | 14 | | |
7 | 15 | | |
8 | 16 | | |
9 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
10 | 21 | | |
11 | 22 | | |
12 | 23 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
130 | 130 | | |
131 | 131 | | |
132 | 132 | | |
133 | | - | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
134 | 136 | | |
135 | 137 | | |
136 | 138 | | |
| |||
186 | 188 | | |
187 | 189 | | |
188 | 190 | | |
189 | | - | |
190 | | - | |
191 | | - | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
192 | 197 | | |
193 | 198 | | |
194 | 199 | | |
| |||
205 | 210 | | |
206 | 211 | | |
207 | 212 | | |
208 | | - | |
| 213 | + | |
209 | 214 | | |
210 | 215 | | |
211 | 216 | | |
212 | | - | |
| 217 | + | |
213 | 218 | | |
214 | 219 | | |
215 | 220 | | |
216 | 221 | | |
217 | 222 | | |
218 | | - | |
219 | | - | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
220 | 227 | | |
221 | 228 | | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
31 | 37 | | |
32 | 38 | | |
33 | 39 | | |
| |||
36 | 42 | | |
37 | 43 | | |
38 | 44 | | |
39 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
40 | 56 | | |
41 | 57 | | |
42 | 58 | | |
43 | 59 | | |
44 | 60 | | |
45 | 61 | | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
46 | 66 | | |
47 | | - | |
| 67 | + | |
48 | 68 | | |
49 | 69 | | |
50 | 70 | | |
51 | 71 | | |
52 | 72 | | |
53 | 73 | | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
54 | 82 | | |
55 | | - | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
56 | 86 | | |
57 | 87 | | |
58 | 88 | | |
| |||
62 | 92 | | |
63 | 93 | | |
64 | 94 | | |
65 | | - | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
66 | 98 | | |
67 | | - | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
68 | 105 | | |
69 | 106 | | |
70 | 107 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
12 | | - | |
| 11 | + | |
13 | 12 | | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
14 | 17 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
10 | | - | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
0 commit comments