Something went wrong. Try again.
My personal dotfiles, for now.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214#!/usr/bin/env -S nu --no-config-file
# Tests for bootstrap.nu using disposable HOME/repo fixtures and fake commands.# No hardware, network, or real brew/chezmoi/jj required.## Run from the repository root:# nu --no-config-file tests/run_bootstrap_tests.nu
use ../home/dot_config/nushell/scripts/dotfiles.nu brewfile-third-party-entries
let REPO_ROOT = ($env.FILE_PWD | path dirname)
const BASE_BREWFILE = 'brew "bat"brew "foo/tap/thing"cask "bar/tap/baz"cask "claude-code@latest"'
# Fake body for logging commands: records its own name plus arguments.const LOG_FAKE = '($env.CURRENT_FILE | path basename) + " " + ($rest | str join " ") + "\n" | save --append $env.FAKE_LOG'
mut results: list<record> = []mut fixtures: list<path> = []
def check [name: string, ok: bool, detail: string = ""] { {name: $name, ok: $ok, detail: $detail}}
# Create an executable fake command in the fixture bin directory. The body is# Nushell and runs inside `def main [...rest: string]`.def make-fake-command [bin_dir: path, name: string, body: string] { let path = ($bin_dir | path join $name) $"#!/usr/bin/env -S nu --no-config-file\ndef main --wrapped [...rest: string] {\n ($body)\n}\n" | save --force $path chmod 755 $path}
# Build a disposable HOME with a minimal but valid repository layout at# ~/.local/share/chezmoi, plus a bin directory of fake commands.def make-fixture [brewfile: string] { let root = (mktemp --directory --tmpdir "bootstrap-test.XXXXXX") let home_dir = ($root | path join "home") let repo = ($home_dir | path join ".local" "share" "chezmoi") mkdir $home_dir mkdir ($repo | path join ".jj") mkdir ($repo | path join "home" "dot_config" "nushell" "scripts") mkdir ($repo | path join "secrets") "home\n" | save --force ($repo | path join ".chezmoiroot") "# test fixture; the real template prompts and is not exercised here\n" | save --force ($repo | path join "home" ".chezmoi.toml.tmpl") $brewfile | save --force ($repo | path join "home" "dot_Brewfile") "# fixture placeholder; only existence is validated\n" | save --force ($repo | path join "secrets" "ssh.sops.yaml") for module in [dotfiles.nu dotfiles-secrets.nu] { cp ($REPO_ROOT | path join "home" "dot_config" "nushell" "scripts" $module) ($repo | path join "home" "dot_config" "nushell" "scripts" $module) } cp ($REPO_ROOT | path join "bootstrap.nu") ($repo | path join "bootstrap.nu") let bin_dir = ($root | path join "bin") mkdir $bin_dir for name in [brew chezmoi jj fc-cache rustup] { make-fake-command $bin_dir $name $LOG_FAKE } make-fake-command $bin_dir fc-match 'if (($env.FC_MATCH_FORCE? | default "") | is-not-empty) { print $env.FC_MATCH_FORCE } else { print ($rest | last) }' {root: $root, home: $home_dir, repo: $repo, bin: $bin_dir, log: ($root | path join "fake.log")}}
# Run the fixture's bootstrap.nu copy with a disposable HOME and a PATH limited# to the fake bin directory plus core tools. Returns the `complete` record.def run-bootstrap [fixture: record, arguments: list<string>, extra_env: record = {}] { let nu_dir = ((which nu | first).path | path dirname) let path = [$fixture.bin $nu_dir "/usr/bin" "/bin"] let environment = ({HOME: $fixture.home, PATH: $path, FAKE_LOG: $fixture.log} | merge $extra_env) with-env $environment { do { ^nu --no-config-file ($fixture.repo | path join "bootstrap.nu") ...$arguments } | complete }}
def read-log [fixture: record] { if ($fixture.log | path exists) { open --raw $fixture.log } else { "" }}
def font-drive [fixture: record, files: list<record>] { let drive = ($fixture.root | path join "font-drive") for file in $files { let target = ($drive | path join $file.path) mkdir ($target | path dirname) $file.content | save --force $target } $drive}
# --- T1: --plan lists the stages without touching anything -------------------let fixture = (make-fixture $BASE_BREWFILE)$fixtures = ($fixtures | append $fixture.root)let result = (run-bootstrap $fixture [--plan])$results = ($results | append (check "plan lists stages and exits zero" ($result.exit_code == 0 and ($result.stdout | str contains "Validate the cloned jj/chezmoi repository layout")) ($result.stderr | str trim)))
# --- T2: trust entries derive from the Brewfile ------------------------------let entries = (with-env {HOME: $fixture.home} { brewfile-third-party-entries })$results = ($results | append (check "third-party trust entries derive from the Brewfile" ($entries == [[kind name]; [brew "foo/tap/thing"] [cask "bar/tap/baz"]]) ($entries | to json)))
# --- T3: package stage trusts derived entries, never official ones -----------let result = (run-bootstrap $fixture [--yes --skip-fonts --skip-secrets --skip-themes --test-stop-after packages])let log = (read-log $fixture)$results = ($results | append (check "package stage succeeds with fakes" ($result.exit_code == 0) ($result.stderr | str trim)))$results = ($results | append (check "trusts derived third-party formula" ($log | str contains "brew trust --formula foo/tap/thing") $log))$results = ($results | append (check "trusts derived third-party cask" ($log | str contains "brew trust --cask bar/tap/baz") $log))$results = ($results | append (check "never trusts official brews" (not ($log | str contains "trust --formula bat")) $log))$results = ($results | append (check "runs brew bundle against the source Brewfile" ($log | str contains "brew bundle --no-upgrade") $log))
# --- T4: cargo stage initializes a toolchain when cargo is not ready ----------let fixture = (make-fixture ($BASE_BREWFILE + 'cargo "somepkg"\n'))$fixtures = ($fixtures | append $fixture.root)make-fake-command $fixture.bin cargo '($env.CURRENT_FILE | path basename) + " " + ($rest | str join " ") + "\n" | save --append $env.FAKE_LOGlet ready = ($env.FAKE_CARGO_READY | path exists)if $rest == [--version] and not $ready { exit 1 }if $rest == [--version] { print "cargo 1.85.0" }if $rest == [install --list] and $ready { print "" }'make-fake-command $fixture.bin rustup '($env.CURRENT_FILE | path basename) + " " + ($rest | str join " ") + "\n" | save --append $env.FAKE_LOGif $rest == [default stable] { touch $env.FAKE_CARGO_READY }'let result = (run-bootstrap $fixture [--yes --skip-fonts --skip-secrets --skip-themes --test-stop-after packages] {FAKE_CARGO_READY: ($fixture.root | path join "cargo-ready")})let log = (read-log $fixture)let rustup_at = ($log | str index-of "rustup default stable")let install_at = ($log | str index-of "cargo install --locked somepkg")$results = ($results | append (check "cargo stage initializes rustup before installing a crate" ($result.exit_code == 0 and $rustup_at >= 0 and $install_at > $rustup_at) ($result.stderr | str trim)))
# --- T5: cargo stage stays out of the way when cargo works -------------------let fixture = (make-fixture ($BASE_BREWFILE + 'cargo "somepkg"\n'))$fixtures = ($fixtures | append $fixture.root)make-fake-command $fixture.bin cargo '($env.CURRENT_FILE | path basename) + " " + ($rest | str join " ") + "\n" | save --append $env.FAKE_LOGif $rest == [--version] { print "cargo 1.85.0" }if $rest == [install --list] { print "somepkg v1.0.0:" }'let result = (run-bootstrap $fixture [--yes --skip-fonts --skip-secrets --skip-themes --test-stop-after packages])let log = (read-log $fixture)$results = ($results | append (check "cargo stage skips rustup and an installed crate" ($result.exit_code == 0 and not ($log | str contains "rustup default stable") and not ($log | str contains "cargo install --locked")) ($result.stderr | str trim)))
# --- T6: font restore accepts uppercase extensions ---------------------------let fixture = (make-fixture $BASE_BREWFILE)$fixtures = ($fixtures | append $fixture.root)let drive = (font-drive $fixture [{path: "PragmataProMono.OTF", content: "fake otf"} {path: "BerkeleyMono.TTF", content: "fake ttf"}])let installed = ($fixture.home | path join ".local" "share" "fonts")let result = (run-bootstrap $fixture [--yes --font-source $drive --skip-secrets --skip-themes --test-stop-after fonts])$results = ($results | append (check "uppercase font extensions are installed" ($result.exit_code == 0 and ($installed | path join "PragmataProMono.OTF" | path exists) and ($installed | path join "BerkeleyMono.TTF" | path exists)) ($result.stderr | str trim)))
# --- T7: font fallback resolution is rejected --------------------------------let fixture = (make-fixture $BASE_BREWFILE)$fixtures = ($fixtures | append $fixture.root)let drive = (font-drive $fixture [{path: "PragmataProMono.otf", content: "fake otf"}])let result = (run-bootstrap $fixture [--yes --font-source $drive --skip-secrets --skip-themes --test-stop-after fonts] {FC_MATCH_FORCE: "DejaVu Sans Mono"})$results = ($results | append (check "fallback font resolution fails the stage" ($result.exit_code != 0 and (($result.stdout + $result.stderr) | str contains "fallback family"))))
# --- T8: duplicate font basenames are rejected -------------------------------let fixture = (make-fixture $BASE_BREWFILE)$fixtures = ($fixtures | append $fixture.root)let drive = (font-drive $fixture [{path: "a/dup.otf", content: "one"} {path: "b/dup.otf", content: "two"}])let result = (run-bootstrap $fixture [--yes --font-source $drive --skip-secrets --skip-themes --test-stop-after fonts])$results = ($results | append (check "duplicate font basenames fail the stage" ($result.exit_code != 0 and (($result.stdout + $result.stderr) | str contains "duplicate filenames"))))
# --- T9: PC/SC environment set by preflight persists in main ----------------# validate-pcsc is an `--env` function because ordinary Nushell function# environment changes disappear on return. Probe the same contract directly so# a regression cannot silently send Homebrew-linked clients to the wrong socket.let pcsc_probe = ( env -u PCSCLITE_CSOCK_NAME nu --no-config-file -c ' const socket = "/run/pcscd/pcscd.comm" def --env set-pcsc [] { $env.PCSCLITE_CSOCK_NAME = $socket } set-pcsc $env.PCSCLITE_CSOCK_NAME ' | str trim)$results = ($results | append (check "PCSC environment persists after preflight" ($pcsc_probe == "/run/pcscd/pcscd.comm") $pcsc_probe))
# --- cleanup and summary -----------------------------------------------------for root in $fixtures { rm --recursive --force $root}print ""for result in $results { let status = if $result.ok { "PASS" } else { "FAIL" } let suffix = if ($result.detail | is-not-empty) and not $result.ok { $" — ($result.detail)" } else { "" } print $"($status) ($result.name)($suffix)"}let failures = ($results | where {|result| not $result.ok })print ""if ($failures | is-empty) { print "All bootstrap tests passed."} else { print $"($failures | length) tests failed." exit 1}