Work in progress. Core config management is done; Google Drive sync is under active development.
A lightweight Go CLI that periodically backs up local files and folders to cloud storage. You define source-to-destination mappings once, and cloudmirror handles the rest. Google Drive is the first supported backend, with more planned.
cloudmirror works around the concept of mappings — a source glob pattern pointing to files or directories on your machine, paired with a destination path in your cloud storage of choice.
/home/user/documents/**/*.pdf → gdrive:/Backups/PDFs
/home/user/projects/notes/ → gdrive:/Backups/Notes
Once mappings are registered, cloudmirror will resolve the globs, walk the matching paths, and upload everything to the specified destination.
| Area | Status |
|---|---|
| CLI scaffolding (Cobra) | Done |
| Config store (add/delete) | Done |
| Config validation | Done |
| Google Drive OAuth2 auth | WIP |
| Google Drive file listing | Not started |
| Google Drive file upload | Not started |
| Sync command | Not started |
| Periodic / scheduled sync | Not started |
| Additional cloud backends | Not started |
Requires Go 1.24+.
git clone https://github.com/Gooner91/cloudmirror.git
cd cloudmirror
go build -o cloudmirror .Optionally move the binary somewhere on your $PATH:
mv cloudmirror /usr/local/bin/cloudmirror uses OAuth2 to authenticate with Google Drive. You need a credentials.json file from a Google Cloud project before running any Drive-related commands.
- Go to the Google Cloud Console.
- Create a project (or select an existing one).
- Enable the Google Drive API for that project.
- Under APIs & Services → Credentials, create an OAuth 2.0 Client ID (Desktop app type).
- Download the credentials and save the file as
credentials.jsonin the directory where you runcloudmirror.
On first use, cloudmirror will open an authorization URL in your terminal. Visit the URL, grant access, paste the authorization code back into the terminal, and a token.json will be saved locally for future runs.
credentials.jsonandtoken.jsonare excluded from version control via.gitignore. Never commit these files.
cloudmirror [command]
Commands:
config Manage backup mappings
help Help about any command
Add a mapping
Register a source glob and a destination path in the config:
cloudmirror config add --srcGlob "/home/user/docs/*.pdf" --dest "Backups/PDFs"| Flag | Required | Description |
|---|---|---|
--srcGlob |
Yes | Glob pattern matching the local files/dirs to back up |
--dest |
Yes | Destination folder path in the target cloud storage |
Delete a mapping
Remove a previously registered mapping (both --srcGlob and --dest must match exactly):
cloudmirror config delete --srcGlob "/home/user/docs/*.pdf" --dest "Backups/PDFs"Mappings are persisted as JSON at:
| Platform | Path |
|---|---|
| Linux / macOS | $XDG_CONFIG_HOME/cloudmirror/config.json |
| Fallback | /etc/cloudmirror/config.json |
On most Linux systems $XDG_CONFIG_HOME defaults to ~/.config, so the effective path is ~/.config/cloudmirror/config.json.
Example file after adding two mappings:
[
{
"SrcGlob": "/home/user/documents/*.pdf",
"Dest": "Backups/PDFs"
},
{
"SrcGlob": "/home/user/projects/notes",
"Dest": "Backups/Notes"
}
]The config file is created automatically on first config add. Its permissions are set to 0600 (owner read/write only).
Validation rules
SrcGlobmust be non-empty and a valid Go filepath glob pattern.Destmust be non-empty.- Duplicate mappings (same
SrcGlob+Destpair) are rejected.
# Run tests
go test ./...
# Build with live-reload (requires air)
airProject layout
cloudmirror/
├── cmd/ # Cobra CLI commands
│ ├── root.go # Root command
│ ├── config.go # `config` subcommand group
│ ├── add.go # `config add`
│ └── delete.go # `config delete`
├── internal/
│ ├── config/
│ │ ├── types.go # Config and ConfigList types
│ │ ├── store.go # Save, Delete, validate, persist
│ │ └── store_test.go # Unit tests for config store
│ └── google_drive/
│ ├── auth.go # OAuth2 client setup
│ ├── service.go # Drive API service constructor
│ └── client.go # Drive API operations (ListFiles, ...)
└── main.go
-
cloudmirror sync— resolve mappings and upload matching files to Google Drive - Progress output and dry-run mode
- Periodic sync via cron or a built-in scheduler
-
config listcommand to display current mappings - Support for additional backends (S3, Dropbox, etc.)
- Incremental sync (skip unchanged files)