<div align="center">
<br>
<img src="logo.png" alt="Shelf Logo" width="120" height="120"/>
# Shelf
### A stupidly simple backup tool
**Single file • Zero dependencies • Auditable • Reliable**
[](https://pypi.org/project/shelf-backup/)
[](https://pypi.org/project/shelf-backup/)
[](https://pypi.org/project/shelf-backup/)
[](https://github.com/rdyv/shelf/blob/main/LICENSE)
[Install](#installation) • [Quick Start](#quick-start) • [Features](#features) • [Documentation](#documentation)
</div>
---
Shelf is a backup tool that is configurable and extensible. It backs up your dotfiles, config files, scripts, random directories etc to a git repository that you can upload to Github private remote.
**One auditable Python file** ([shelf.py](shelf.py)) contains all the logic for backup and restore. It auto-detects OS (macOS/Linux) and uses correct template ([macos.json](macos.json) or [linux.json](linux.json)) for configuration. Each backup session creates detailed structured NDJSON logging for auditability. The following is an example of sources that are enabled for backup:
- **Dotfiles**: `.zshrc`, `.gitconfig`, `.ssh/config`, etc.
- **App Configs**: VSCode, Vim, tmux, git settings
- **System Prefs**: macOS dock, finder, terminal settings
- **Package Managers**: Homebrew formulas and casks
- **Custom Fonts**: Your installed font collection
## Quick Start
```bash
# Install
pip install shelf-backup
# Initialize profile
shelf init
# Backup to specific directory
shelf backup ~/my-backups
# Optional: customize what gets backed up
vim ~/.config/shelf/macos.json
# Restore from backup
shelf restore
```
## Documentation
<details>
<strong>Advanced Commands</strong>
```bash
# Restore from specific commit
shelf restore abc1234
# Restore from different location
shelf restore ~/different-backup
# Show backup history at specific path
shelf list ~/my-backups
# Check system status
shelf status
```
</details>
<details>
<strong>File Locations</strong>
```
~/.config/shelf/ # Configuration files (JSON)
~/.local/share/shelf/ # Backup data (git repositories)
```
</details>
<details>
<strong>Requirements</strong>
- Python 3.8+
- `git` command (for versioning)
- `brew` command (for Homebrew backups on macOS)
No pip packages, no external libraries.
</details>
## Configuration
Shelf uses a single JSON config file per machine at `~/.config/shelf/{os}.json`. The config is automatically created from templates (`macos.json` or `linux.json`) but can be customized to your needs.
### Config Structure
```json
{
"name": "macos",
"description": "macOS system backup profile",
"backup_path": "~/my-backups",
"files": {
"enabled": true,
"files": [".zshrc", ".gitconfig", ".ssh/config"],
"directories": [
".config/nvim",
".config/tmux",
"Library/Preferences/com.apple.dock.plist"
],
"exclude_patterns": ["**/.git/**", "**/node_modules/**", "**/*.log"]
},
"homebrew": {
"enabled": true
},
"fonts": {
"enabled": true
}
}
```
### Configuration Options
1. **backup_path**: Where backups are stored (supports `~` expansion)
1. **files.files**: Individual files to backup (relative to home directory)
1. **files.directories**: Entire directories to backup (relative to home directory)
1. **files.exclude_patterns**: Glob patterns to skip during backup
1. **homebrew.enabled**: Backup Homebrew packages and Brewfile (macOS only)
1. **fonts.enabled**: List installed custom fonts
### Backup Logs and History
Each backup session creates detailed NDJSON structured logs with metadata, timing, and results:
```bash
# View backup history
shelf list ~/my-backups
# Example output:
# 20250122_143052 - backup - 2025-01-22 14:30:52
# 20250121_091234 - backup - 2025-01-21 09:12:34
# 20250120_160845 - backup - 2025-01-20 16:08:45
```
**Log files contain:**
- Session metadata (timestamp, platform, hostname)
- File and directory backup results
- Error details and warnings
- Git commit information
- Provider statistics (files copied, sizes, etc.)
**Log location:** `{backup_path}/backup_YYYYMMDD_HHMMSS.ndjson`
Each log entry is a complete JSON object on its own line, making them easy to parse with tools like `jq` or analyze programmatically.
---
<div align="center">
**[Install Now](https://pypi.org/project/shelf-backup/)** • **[Report Issues](https://github.com/rdyv/shelf/issues)**
_Made for developers who value simplicity_
</div>
Raw data
{
"_id": null,
"home_page": null,
"name": "shelf-backup",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "backup, restore, dotfiles, git, homebrew, simple",
"author": "Radhe",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/52/ce/a152d10bcbd8e22290cacffaf137d0760a4d9114be4819a2b295c1e271b6/shelf_backup-0.0.1.tar.gz",
"platform": null,
"description": "<div align=\"center\">\n\n<br>\n\n<img src=\"logo.png\" alt=\"Shelf Logo\" width=\"120\" height=\"120\"/>\n\n# Shelf\n\n### A stupidly simple backup tool\n\n**Single file \u2022 Zero dependencies \u2022 Auditable \u2022 Reliable**\n\n[](https://pypi.org/project/shelf-backup/)\n[](https://pypi.org/project/shelf-backup/)\n[](https://pypi.org/project/shelf-backup/)\n[](https://github.com/rdyv/shelf/blob/main/LICENSE)\n\n[Install](#installation) \u2022 [Quick Start](#quick-start) \u2022 [Features](#features) \u2022 [Documentation](#documentation)\n\n</div>\n\n---\n\nShelf is a backup tool that is configurable and extensible. It backs up your dotfiles, config files, scripts, random directories etc to a git repository that you can upload to Github private remote.\n\n**One auditable Python file** ([shelf.py](shelf.py)) contains all the logic for backup and restore. It auto-detects OS (macOS/Linux) and uses correct template ([macos.json](macos.json) or [linux.json](linux.json)) for configuration. Each backup session creates detailed structured NDJSON logging for auditability. The following is an example of sources that are enabled for backup:\n\n- **Dotfiles**: `.zshrc`, `.gitconfig`, `.ssh/config`, etc.\n- **App Configs**: VSCode, Vim, tmux, git settings\n- **System Prefs**: macOS dock, finder, terminal settings\n- **Package Managers**: Homebrew formulas and casks\n- **Custom Fonts**: Your installed font collection\n\n## Quick Start\n\n```bash\n# Install\npip install shelf-backup\n\n# Initialize profile\nshelf init\n\n# Backup to specific directory\nshelf backup ~/my-backups\n\n# Optional: customize what gets backed up\nvim ~/.config/shelf/macos.json\n\n# Restore from backup\nshelf restore\n```\n\n## Documentation\n\n<details>\n<strong>Advanced Commands</strong>\n\n```bash\n# Restore from specific commit\nshelf restore abc1234\n\n# Restore from different location\nshelf restore ~/different-backup\n\n# Show backup history at specific path\nshelf list ~/my-backups\n\n# Check system status\nshelf status\n```\n\n</details>\n\n<details>\n<strong>File Locations</strong>\n\n```\n~/.config/shelf/ # Configuration files (JSON)\n~/.local/share/shelf/ # Backup data (git repositories)\n```\n\n</details>\n\n<details>\n<strong>Requirements</strong>\n\n- Python 3.8+\n- `git` command (for versioning)\n- `brew` command (for Homebrew backups on macOS)\n\nNo pip packages, no external libraries.\n\n</details>\n\n## Configuration\n\nShelf uses a single JSON config file per machine at `~/.config/shelf/{os}.json`. The config is automatically created from templates (`macos.json` or `linux.json`) but can be customized to your needs.\n\n### Config Structure\n\n```json\n{\n\t\"name\": \"macos\",\n\t\"description\": \"macOS system backup profile\",\n\t\"backup_path\": \"~/my-backups\",\n\t\"files\": {\n\t\t\"enabled\": true,\n\t\t\"files\": [\".zshrc\", \".gitconfig\", \".ssh/config\"],\n\t\t\"directories\": [\n\t\t\t\".config/nvim\",\n\t\t\t\".config/tmux\",\n\t\t\t\"Library/Preferences/com.apple.dock.plist\"\n\t\t],\n\t\t\"exclude_patterns\": [\"**/.git/**\", \"**/node_modules/**\", \"**/*.log\"]\n\t},\n\t\"homebrew\": {\n\t\t\"enabled\": true\n\t},\n\t\"fonts\": {\n\t\t\"enabled\": true\n\t}\n}\n```\n\n### Configuration Options\n\n1. **backup_path**: Where backups are stored (supports `~` expansion)\n1. **files.files**: Individual files to backup (relative to home directory)\n1. **files.directories**: Entire directories to backup (relative to home directory)\n1. **files.exclude_patterns**: Glob patterns to skip during backup\n1. **homebrew.enabled**: Backup Homebrew packages and Brewfile (macOS only)\n1. **fonts.enabled**: List installed custom fonts\n\n### Backup Logs and History\n\nEach backup session creates detailed NDJSON structured logs with metadata, timing, and results:\n\n```bash\n# View backup history\nshelf list ~/my-backups\n\n# Example output:\n# 20250122_143052 - backup - 2025-01-22 14:30:52\n# 20250121_091234 - backup - 2025-01-21 09:12:34\n# 20250120_160845 - backup - 2025-01-20 16:08:45\n```\n\n**Log files contain:**\n\n- Session metadata (timestamp, platform, hostname)\n- File and directory backup results\n- Error details and warnings\n- Git commit information\n- Provider statistics (files copied, sizes, etc.)\n\n**Log location:** `{backup_path}/backup_YYYYMMDD_HHMMSS.ndjson`\n\nEach log entry is a complete JSON object on its own line, making them easy to parse with tools like `jq` or analyze programmatically.\n\n---\n\n<div align=\"center\">\n\n**[Install Now](https://pypi.org/project/shelf-backup/)** \u2022 **[Report Issues](https://github.com/rdyv/shelf/issues)**\n\n_Made for developers who value simplicity_\n\n</div>\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A stupidly simple backup tool: single file with zero dependencies",
"version": "0.0.1",
"project_urls": {
"Homepage": "https://github.com/rdyv/shelf",
"Issues": "https://github.com/rdyv/shelf/issues",
"Repository": "https://github.com/rdyv/shelf"
},
"split_keywords": [
"backup",
" restore",
" dotfiles",
" git",
" homebrew",
" simple"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "af40b85d13ccdb030ead836aba0aa26e041873a800542484b6bcf857625f8053",
"md5": "3be3fe655842c30dbc87067c289fb423",
"sha256": "44e80d5218fa2d21308448f7d712385a7a519e6b51833e4dab4e0671a4739078"
},
"downloads": -1,
"filename": "shelf_backup-0.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3be3fe655842c30dbc87067c289fb423",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 12333,
"upload_time": "2025-08-22T23:37:28",
"upload_time_iso_8601": "2025-08-22T23:37:28.207484Z",
"url": "https://files.pythonhosted.org/packages/af/40/b85d13ccdb030ead836aba0aa26e041873a800542484b6bcf857625f8053/shelf_backup-0.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "52cea152d10bcbd8e22290cacffaf137d0760a4d9114be4819a2b295c1e271b6",
"md5": "d03d07c022f40b9a8dded271e6e69a76",
"sha256": "2edc89920e506d86731e516304aa7932b96cdffa92551bfc27a96a82050b5e6b"
},
"downloads": -1,
"filename": "shelf_backup-0.0.1.tar.gz",
"has_sig": false,
"md5_digest": "d03d07c022f40b9a8dded271e6e69a76",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 14419,
"upload_time": "2025-08-22T23:37:29",
"upload_time_iso_8601": "2025-08-22T23:37:29.338211Z",
"url": "https://files.pythonhosted.org/packages/52/ce/a152d10bcbd8e22290cacffaf137d0760a4d9114be4819a2b295c1e271b6/shelf_backup-0.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-22 23:37:29",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "rdyv",
"github_project": "shelf",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "shelf-backup"
}