https://github.com/laoujin/perch
Make yourself at home with Perch. Windows first dotfiles, app settings, packages, registry -- managed in git, symlinked into place.
https://github.com/laoujin/perch
dotfiles dotfiles-windows
Last synced: 4 months ago
JSON representation
Make yourself at home with Perch. Windows first dotfiles, app settings, packages, registry -- managed in git, symlinked into place.
- Host: GitHub
- URL: https://github.com/laoujin/perch
- Owner: Laoujin
- Created: 2026-02-14T16:29:47.000Z (4 months ago)
- Default Branch: master
- Last Pushed: 2026-02-18T05:41:50.000Z (4 months ago)
- Last Synced: 2026-02-18T07:13:44.605Z (4 months ago)
- Topics: dotfiles, dotfiles-windows
- Language: C#
- Homepage:
- Size: 20.7 MB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Perch
Cross-platform dotfiles and application settings manager. Symlink-first -- change a setting in your editor, it's immediately tracked in git.
Perch manages symlinks, registry entries, VS Code extensions, PowerShell modules, global npm packages, and system package installation across Windows, Linux, and macOS.
## Quick Start
```bash
# Prerequisites: .NET 10 SDK
# Build
dotnet build
# Run directly
dotnet run --project src/Perch.Cli -- deploy --config-path /path/to/your/config-repo
# Or install as a global tool
dotnet pack src/Perch.Cli -c Release
dotnet tool install --global --add-source src/Perch.Cli/bin/Release Perch.Cli
perch deploy --config-path /path/to/your/config-repo
```
After the first run, the config path is saved so subsequent commands don't need `--config-path`.
## Commands
### `perch deploy`
Creates symlinks, sets registry values, installs packages, extensions, and modules.
```
perch deploy [--config-path ] [--dry-run] [--interactive] [--output Pretty|Json]
```
| Flag | Description |
|------|-------------|
| `--config-path` | Path to config repo (saved for future runs) |
| `--dry-run` | Preview what would happen without making changes |
| `--interactive`, `-i` | Prompt before each module (apply / skip / abort) |
| `--output` | `Pretty` (default, live table) or `Json` |
Before deploying, Perch creates a snapshot of all target files so you can restore them later.
### `perch status`
Shows drift between your config repo and the current system state.
```
perch status [--config-path ] [--drift-only] [--output Pretty|Json]
```
| Flag | Description |
|------|-------------|
| `--drift-only` | Only show items that are missing, drifted, or errored |
| `--output` | `Pretty` (default, grouped by category) or `Json` |
Checks: symlinks, registry entries, global packages, VS Code extensions, PowerShell modules, and system packages.
### `perch apps`
Shows installed applications and whether they match a known module.
### `perch restore list` / `perch restore apply`
List and restore from pre-deploy snapshots.
### `perch diff start` / `perch diff stop`
Snapshot the filesystem to detect changes made outside of Perch.
### `perch git setup`
Register git clean filters defined in module manifests.
### `perch completion`
Output a shell tab-completion script.
## How It Works
Perch reads a **config repo** -- a folder of modules, each with a `manifest.yaml` and the actual config files. On deploy, it symlinks those files to their expected locations on the system. Edit a config file in its usual location and the change is immediately reflected in the repo.
```
your-config-repo/
git/
manifest.yaml
.gitconfig
.gitignore_global
vscode/
manifest.yaml
settings.json
keybindings.json
snippets/
powershell/
manifest.yaml
profiles/
scripts/
packages.yaml # System packages to install
machines/ # Optional per-machine overrides
base.yaml
DESKTOP-ABC.yaml
```
### Module Discovery
Perch scans `*/manifest.yaml` one level deep in the config repo. Each subfolder with a `manifest.yaml` is a module.
### Manifest Format
```yaml
display-name: Git
enabled: true # Optional, default true
platforms: # Optional, runs on all if omitted
- Windows
- Linux
- MacOS
links:
- source: .gitconfig # Relative to module folder
target: # Platform-specific targets
windows: "%USERPROFILE%\\.gitconfig"
linux: "$HOME/.gitconfig"
macos: "$HOME/.gitconfig"
- source: scripts
target: "%USERPROFILE%\\scripts"
link-type: junction # 'symlink' (default) or 'junction'
registry: # Windows only
- key: HKEY_CURRENT_USER\Software\App
name: SettingName
value: 42
type: dword # dword, string, etc.
global-packages:
manager: npm # npm or bun
packages:
- prettier
- eslint_d
vscode-extensions:
- dbaeumer.vscode-eslint
- esbenp.prettier-vscode
ps-modules:
- Posh-Git
- PSReadLine
hooks:
pre-deploy: setup.ps1 # Run before deploying this module
post-deploy: cleanup.ps1 # Run after deploying this module
```
**Target paths** support environment variables: `%USERPROFILE%`, `%APPDATA%`, `%LOCALAPPDATA%`, `$HOME`, `$XDG_CONFIG_HOME`, etc. Custom variables can be defined in machine profiles.
### System Packages (`packages.yaml`)
Declare system-level packages in a `packages.yaml` at the config repo root:
```yaml
packages:
- name: Git.Git
manager: winget
- name: Mozilla.Firefox
manager: winget
- name: curl
manager: apt
- name: git
manager: brew
```
Supported managers: `winget`, `chocolatey`, `apt`, `brew`. Each is only applied on its matching platform.
On Windows, `winget` is recommended over `chocolatey` -- winget detects all installed software (including apps installed via choco, MSI, or manually) through the Windows ARP registry.
### Machine Profiles
Place YAML files in a `machines/` folder to customize per-machine behavior:
- `machines/base.yaml` -- defaults for all machines
- `machines/HOSTNAME.yaml` -- overrides for a specific machine (matched by `$env:COMPUTERNAME`)
```yaml
include-modules: # Only deploy these modules (whitelist)
- git
- vscode
exclude-modules: # Skip these modules (blacklist)
- cmder
variables: # Custom variables for target path expansion
PROJECTS: "D:\\Projects"
```
Hostname-specific values override base values. Variables are merged (hostname wins on conflict).
## Project Structure
```
src/
Perch.Core/ # Engine: symlinks, registry, packages, status, deploy
Perch.Cli/ # CLI commands (Spectre.Console)
Perch.Desktop/ # Desktop GUI (first-run wizard)
tests/
Perch.Core.Tests/ # Unit + integration tests
```
## Development
```bash
dotnet build # Build (warnings as errors)
dotnet test # Run all tests
```
.NET 10, C# latest, NUnit 4, NSubstitute 5, Roslynator analyzers.