Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

This repository uses [chezmoi](https://www.chezmoi.io/) to deploy regular dotfiles on Windows and Linux. Repository support files stay outside the `home/` source state.

Fresh bootstrap installations keep the Git working tree at `~/.dotfiles`. The generated chezmoi configuration persists that directory, so regular commands such as `chezmoi update` and `chezmoi cd` use it without extra flags. Because `.chezmoiroot` points to `home`, `chezmoi source-path` resolves to `~/.dotfiles/home`. Existing installations are not moved automatically.

## Quick installation

### Windows
Expand Down Expand Up @@ -42,6 +44,7 @@ For dotfiles plus installer-managed package/application/module updates, use `upd

## State details

- `home/.chezmoi.toml.tmpl` persists the source directory selected during `chezmoi init`; fresh bootstraps explicitly select `~/.dotfiles`.
- `home/.chezmoiroot` is represented by the repository-level `.chezmoiroot`, pointing to `home`.
- Windows-only `.wslconfig` and Linux-only Zsh/Sheldon state are filtered by `home/.chezmoiignore`.
- `~/.gitconfig.local`, `~/.codex/config.toml`, and `~/.codex/rules/default.rules` use chezmoi create-only semantics and are not overwritten after creation.
Expand Down
2 changes: 1 addition & 1 deletion bootstrap.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ for /f "delims=" %%R in ('chezmoi.exe source-path 2^>nul') do set "SOURCE_ROOT=%
if defined SOURCE_ROOT if exist "%SOURCE_ROOT%\.chezmoiroot" goto existing_chezmoi
if defined SOURCE_ROOT for %%P in ("%SOURCE_ROOT%\..") do if exist "%%~fP\.chezmoiroot" goto existing_chezmoi

chezmoi.exe init "%REPO_URL%"
chezmoi.exe --source "%USERPROFILE%\.dotfiles" init "%REPO_URL%"
exit /b %ERRORLEVEL%

:existing_chezmoi
Expand Down
2 changes: 1 addition & 1 deletion bootstrap.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ else
if [[ -f "$SOURCE_ROOT/.chezmoiroot" || -f "$(dirname "$SOURCE_ROOT")/.chezmoiroot" ]]; then
existing_source=true
else
chezmoi init "$REPO_URL"
chezmoi --source "$HOME/.dotfiles" init "$REPO_URL"
fi
fi

Expand Down
1 change: 1 addition & 0 deletions home/.chezmoi.toml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sourceDir = {{ joinPath .chezmoi.homeDir ".dotfiles" | quote }}
5 changes: 5 additions & 0 deletions tests/linux/assert-state.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ printf 'HOME: %s\n' "$HOME"
printf 'chezmoi: %s\n' "$(chezmoi --version)"
printf 'chezmoi source-path: %s\n' "$(chezmoi source-path)"

source_path="$(chezmoi source-path)"
working_tree="$(chezmoi execute-template '{{ .chezmoi.workingTree }}')"
[[ "$working_tree" == "$HOME/.dotfiles" ]] || fail "chezmoi working tree is $working_tree, expected $HOME/.dotfiles"
[[ "$source_path" == "$HOME/.dotfiles/home" ]] || fail "chezmoi source path is $source_path, expected $HOME/.dotfiles/home"

case "$expected_distro" in
debian) [[ -f /etc/debian_version ]] || fail "Debian detection marker is missing" ;;
arch) [[ -f /etc/arch-release ]] || fail "Arch detection marker is missing" ;;
Expand Down
1 change: 1 addition & 0 deletions tests/static/validate-architecture.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def read_text(path: str) -> str:
fail(".chezmoiroot must contain 'home'")

required_paths = (
"home/.chezmoi.toml.tmpl",
"home",
"scripts/linux/packages-debian.txt",
"scripts/linux/cleanup-broken-managed-links.sh",
Expand Down
11 changes: 11 additions & 0 deletions tests/windows/assert-allsigned.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,17 @@ function Assert-CleanChezMoi {

$sourcePath = ((Invoke-Chezmoi @("source-path")) -join "").Trim()
Write-Host "chezmoi source-path: $sourcePath"
$expectedWorkingTree = [IO.Path]::GetFullPath((Join-Path $HOME ".dotfiles")).TrimEnd([IO.Path]::DirectorySeparatorChar)
$workingTree = ((Invoke-Chezmoi @("execute-template", "{{ .chezmoi.workingTree }}")) -join "").Trim()
$actualWorkingTree = [IO.Path]::GetFullPath($workingTree).TrimEnd([IO.Path]::DirectorySeparatorChar)
if (-not $actualWorkingTree.Equals($expectedWorkingTree, [StringComparison]::OrdinalIgnoreCase)) {
Fail "chezmoi working tree is $actualWorkingTree, expected $expectedWorkingTree"
}
$expectedSourcePath = [IO.Path]::GetFullPath((Join-Path $expectedWorkingTree "home")).TrimEnd([IO.Path]::DirectorySeparatorChar)
$actualSourcePath = [IO.Path]::GetFullPath($sourcePath).TrimEnd([IO.Path]::DirectorySeparatorChar)
if (-not $actualSourcePath.Equals($expectedSourcePath, [StringComparison]::OrdinalIgnoreCase)) {
Fail "chezmoi source path is $actualSourcePath, expected $expectedSourcePath"
}
$managedAppsPath = Join-Path $RepoRoot "scripts\windows\managed-apps.csv"
$coreApps = @(Import-Csv -LiteralPath $managedAppsPath | Where-Object Category -eq "core")
foreach ($app in $coreApps) {
Expand Down
12 changes: 12 additions & 0 deletions tests/windows/assert-state.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ $sourcePath = ((Invoke-Chezmoi @("source-path")) -join "").Trim()
Write-Host "chezmoi source-path: $sourcePath"
if (-not (Test-Path -LiteralPath $sourcePath)) { Fail "chezmoi source path does not exist: $sourcePath" }

$expectedWorkingTree = [IO.Path]::GetFullPath((Join-Path $HOME ".dotfiles")).TrimEnd([IO.Path]::DirectorySeparatorChar)
$workingTree = ((Invoke-Chezmoi @("execute-template", "{{ .chezmoi.workingTree }}")) -join "").Trim()
$actualWorkingTree = [IO.Path]::GetFullPath($workingTree).TrimEnd([IO.Path]::DirectorySeparatorChar)
if (-not $actualWorkingTree.Equals($expectedWorkingTree, [StringComparison]::OrdinalIgnoreCase)) {
Fail "chezmoi working tree is $actualWorkingTree, expected $expectedWorkingTree"
}
$expectedSourcePath = [IO.Path]::GetFullPath((Join-Path $expectedWorkingTree "home")).TrimEnd([IO.Path]::DirectorySeparatorChar)
$actualSourcePath = [IO.Path]::GetFullPath($sourcePath).TrimEnd([IO.Path]::DirectorySeparatorChar)
if (-not $actualSourcePath.Equals($expectedSourcePath, [StringComparison]::OrdinalIgnoreCase)) {
Fail "chezmoi source path is $actualSourcePath, expected $expectedSourcePath"
}

$requiredFiles = @(
(Join-Path $HOME ".gitconfig"),
(Join-Path $HOME ".gitconfig.local"),
Expand Down