How to safely test dotbak without risking your real dotfiles or system.
dotbak touches real files on your system:
add --symlinkreplaces your original file with a symlinkinstall.shwrites to/usr/local/binand shell completion directoriesdotbak updateoverwrites the installed binaryDOTBAK_DIRenv var, if set in your shell, can leak into tests and hit real directories
The bats test suite handles this by overriding HOME to a temp directory. But when you're manually testing commands, building, or running install/update — you need your own sandbox.
The fastest way to get an isolated environment. Open a new terminal and run:
# Create a disposable sandbox
SANDBOX=$(mktemp -d /tmp/dotbak-sandbox.XXXXXX)
export HOME="$SANDBOX/home"
mkdir -p "$HOME"
unset DOTBAK_DIR
echo "Sandbox active: HOME=$HOME"
echo "Your real home is untouched."Now you can safely run any dotbak command:
# Everything happens inside the sandbox
cd /path/to/dotbak
./dotbak-dev init
echo "test config" > "$HOME/.zshrc"
./dotbak-dev add --symlink "$HOME/.zshrc"
./dotbak-dev status
./dotbak-dev remove "$HOME/.zshrc"
# Build and install to a temp location
./build.sh
mkdir -p "$SANDBOX/bin"
cp dotbak "$SANDBOX/bin/"
"$SANDBOX/bin/dotbak" --versionWhen you're done:
rm -rf "$SANDBOX"
# Or just close the terminal — it's in /tmpWhat you can test here: All dotbak commands (init, add, remove, status, snapshot, symlink-sync, deploy, archive), build.sh, and manual install to a custom path.
What you can't test here: dotbak update (needs a real GitHub release), system-level install paths (/usr/local/bin), shell completions loading.
Three dedicated containers in sandbox/ for different scenarios. Examples use podman — replace with docker if that's what you have.
All commands run from the project root (not from sandbox/):
cd /path/to/dotbakWhy
localhost/? Podman doesn't have a default registry. Without the prefix, it prompts you to pick one.localhost/tells it to use the locally built image.
Runs the full bats test suite:
podman build -f sandbox/Dockerfile.test -t dotbak-test .
podman run --rm localhost/dotbak-testRun specific tests:
podman run --rm localhost/dotbak-test ./test.sh unit
podman run --rm localhost/dotbak-test ./test.sh test/integration/test_add.batspodman build -f sandbox/Dockerfile.install -t dotbak-install .Automated checks (pass/fail):
podman run --rm localhost/dotbak-install # full cycle
podman run --rm localhost/dotbak-install ./sandbox/test-install.sh install # install only
podman run --rm localhost/dotbak-install ./sandbox/test-install.sh update # reinstall only
podman run --rm localhost/dotbak-install ./sandbox/test-install.sh uninstall # uninstall onlySee real output (as a user would see it):
podman run --rm localhost/dotbak-install ./sandbox/demo.sh # full cycle
podman run --rm localhost/dotbak-install ./sandbox/demo.sh install # install output
podman run --rm localhost/dotbak-install ./sandbox/demo.sh update # reinstall output
podman run --rm localhost/dotbak-install ./sandbox/demo.sh uninstall # uninstall outputBoth scripts refuse to run outside a container for safety.
Explore manually:
podman run --rm -it localhost/dotbak-install bashFull dev environment with your source bind-mounted. Edit on your host, test inside the container:
podman build -f sandbox/Dockerfile.dev -t dotbak-dev-env .
podman run --rm -it -v "$(pwd):/dotbak:Z" localhost/dotbak-dev-envNote: The
:Zsuffix is for SELinux (Fedora/RHEL). Drop it on Ubuntu/macOS.
Inside you can run ./dotbak-dev, ./build.sh, ./test.sh, shellcheck, etc. Changes to source files on your host are reflected immediately.
- test / install: Rebuild after changing source (they COPY the project in)
- dev: Rarely — source is mounted live. Only rebuild if system deps change
- No macOS testing — containers run Linux only. For macOS, use a VM (see below).
- No
dotbak update— needs a real GitHub release with published artifacts.
For the full sandbox reference, see sandbox/README.md.
When you need real multi-platform testing — especially macOS, or testing shell integration (login shells, completions, PATH setup).
| Platform | Recommended |
|---|---|
| Linux host | QEMU/libvirt (virt-manager), VirtualBox |
| macOS host | UTM (Apple Silicon), VirtualBox (Intel) |
| Any host | Vagrant (automates VM provisioning) |
# Inside the VM
git clone --recurse-submodules https://github.com/darshithedpara/dotbak
cd dotbak
# Install dependencies
# Ubuntu/Debian:
sudo apt install bash gcc shc zip unzip curl git
# Fedora:
sudo dnf install bash gcc shc zip unzip curl git
# macOS:
brew install bash shc zip
# Full test cycle
./test.sh
./build.sh
./install.sh
dotbak init
dotbak --version- Testing macOS native builds (shc produces Mach-O binaries)
- Testing shell completion loading in real login shells
- Testing install/uninstall with real system paths
- Reproducing CI failures on a specific OS version
GitHub Actions CI already provides isolated testing on every push and PR:
- Ephemeral runners — each run starts clean, no cleanup needed
- Multi-platform — Ubuntu + macOS matrix
- Full pipeline — ShellCheck, build, test suite, version verification
Push to a branch or open a PR against main. CI runs automatically.
Run GitHub Actions workflows locally using act:
# Install act
# Fedora: sudo dnf install act
# macOS: brew install act
# Others: https://github.com/nektos/act#installation
# Run the CI workflow locally
act push
# Run a specific job
act push -j test
act push -j shellcheckact uses a container runtime under the hood. It works with both Docker and podman (export DOCKER_HOST=... for podman socket).
After dotbak init, you can version-control your entire ~/.dotbak directory with git. This gives you full history of your dotfile changes, and you can push to a private repo for cross-machine sync.
# Initialize git inside your dotbak directory
cd ~/.dotbak
git init
git add -A
git commit -m "initial dotbak backup"
# Optional: push to a private repo
git remote add origin git@github.com:youruser/dotfiles-backup.git
git push -u origin main# After making changes to your dotfiles:
dotbak snapshot # create a dotbak snapshot
cd ~/.dotbak
git add -A
git commit -m "update zshrc and nvim config"
git push# Clone your dotfiles backup
git clone git@github.com:youruser/dotfiles-backup.git ~/.dotbak
# Deploy everything
dotbak deploy --allThis pairs well with the sandbox approach — test the full init -> add -> snapshot -> git push -> clone -> deploy cycle inside a sandbox or Docker container before doing it for real.
Before running dotbak commands outside the test suite, verify:
-
echo $HOME— is it a temp/sandbox directory? -
echo $DOTBAK_DIR— is it unset or pointing to a sandbox path? - Using
dotbak-dev? — not the system-installeddotbak - Install testing? — using a temp prefix, not
/usr/local/bin - Symlink testing? — files you're adding are dummy files in the sandbox, not real configs
If you have export DOTBAK_DIR=... in your shell profile, it overrides $HOME/.dotbak in all contexts — including tests. The bats test suite does not unset this variable. Before running tests:
unset DOTBAK_DIR
./test.sh| Method | Isolation | Setup time | Can test install? | macOS? |
|---|---|---|---|---|
| Quick sandbox | HOME override | 10 seconds | Partial (custom path) | Yes |
| Container (podman/docker) | Full container | 1 minute | Yes | No |
| VM | Full OS | 10-30 minutes | Yes | Yes |
| CI (GitHub Actions) | Ephemeral runner | Push and wait | Yes | Yes |
act (local CI) |
Container-based | 2 minutes | Yes | No |