aboutsummaryrefslogtreecommitdiffstats

sourcewatch

A file synchronization tool that watches a Windows source directory and syncs changes to a Docker container via Unix socket IPC. Respects .gitignore rules.

Architecture

Windows Host                          Docker Container
┌─────────────────────┐              ┌─────────────────────────┐
│ sourcewatch.exe          TCP       sourcewatch (linux)     │
│   watches C:\src    │◄────────────►│   - receives manifest   │
│   ReadDirectory       connect        - syncs changed files │
│     ChangesW          :5151          - listens for events  │
└─────────────────────┘              └─────────────────────────┘
  1. Container starts and listens on TCP port 5151
  2. Windows binary connects to container, scans source directory (fast native NTFS), sends file metadata
  3. Container compares with local state, copies only changed files
  4. Windows binary watches for changes, sends events over TCP
  5. Container receives events and syncs in real-time

Building

Windows binary (sourcewatch.exe)

# From Windows (Git Bash, PowerShell, or cmd)
go build -o sourcewatch.exe .

# Cross-compile from Linux/Mac
GOOS=windows GOARCH=amd64 go build -o sourcewatch.exe .

Requires Go 1.24+ and github.com/fsnotify/fsnotify (automatically downloaded).

Docker/Podman image (linux container)

# Build image
docker build -t sourcewatch .

# Or with Podman
podman build -t sourcewatch .

Usage

Step 1: Build the Windows binary

GOOS=windows GOARCH=amd64 go build -o sourcewatch.exe .

Step 2: Start the container

docker run -d -p 5151:5151 \
  -v C:\myproject:/host:ro \
  -v project-data:/data \
  sourcewatch

Or with Podman:

podman run -d -p 5151:5151 \
  -v C:\myproject:/host:ro \
  -v project-data:/data \
  sourcewatch

Step 3: Start the Windows watcher

# PowerShell
.\sourcewatch.exe -dir C:\myproject -connect localhost:5151

# Git Bash
./sourcewatch.exe -dir /c/myproject -connect localhost:5151

Standalone mode (no Windows watcher)

If you don't need real-time watching, run with -listen "":

docker run -v /path/to/source:/host:ro -v data:/data sourcewatch -listen ""

Flags

Windows binary (sourcewatch.exe)

-dir string       Source directory to watch (required)
-connect string   TCP address of the container (default "localhost:5151")
-log-level string Log level: debug, info, warn, error, none (default "info")
-verbose          Enable verbose logging (shorthand for -log-level debug)

Container (sourcewatch)

-host string       Host source directory (default "/host")
-data string       Data destination directory (default "/data")
-listen string     TCP address to listen on (default ":5151")
-verbose           Enable verbose logging (shorthand for -log-level debug)
-log-level string  Log level: debug, info, warn, error, none (default "info")
-dry-run           Preview what would be synced without copying

Protocol

Communication uses newline-delimited JSON over TCP:

{"type":"manifest","files":{"path":{"size":1234,"modtime":"2024-01-01T00:00:00Z","mode":"0644"}}}
{"type":"manifest_done"}
{"type":"event_create","path":"new/file.go"}
{"type":"event_write","path":"modified/file.go"}
{"type":"event_remove","path":"deleted/file.go"}

.gitignore support

  • Full gitignore spec: *, **, [], ! negation
  • Nested .gitignore files (child patterns override parents)
  • Patterns scoped to their directory
  • .git directory always skipped

Example .gitignore:

*.log
build/
!important.log

Limitations

  • One-way sync only (/host/data)
  • /host must be read-only
  • ? single-character wildcard not supported (go-gitignore limitation)
  • Windows binary requires Go 1.21+ to build

License

MIT