Skip to content

Commit 7290814

Browse files
committed
feat: add inline configuration and config-free mode
- Add inline CLI options for backup and start commands (--source, --local-path, --s3-bucket, --retention-count, etc.) - Enable config-free mode: run without config file by providing required inline options (source + storage destination) - Add comprehensive command documentation in docs/folder - Switch linting from biome to oxlint with configuration - Add 75+ tests for inline configuration functionality - Update README with inline config docs and documentation index
1 parent 9438c84 commit 7290814

71 files changed

Lines changed: 3343 additions & 1098 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
run: bunx tsc --noEmit
2323

2424
- name: Lint
25-
run: bun run check
25+
run: bun run lint
2626

2727
- name: Test
2828
run: bun test

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
run: bunx tsc --noEmit
2626

2727
- name: Lint
28-
run: bun run check
28+
run: bun run lint
2929

3030
- name: Test
3131
run: bun test

.oxfmtrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"ignorePatterns": []
3+
}

.oxlintrc.json

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
{
2+
"plugins": ["unicorn", "typescript", "oxc"],
3+
"categories": {},
4+
"rules": {
5+
"constructor-super": "warn",
6+
"for-direction": "warn",
7+
"no-async-promise-executor": "warn",
8+
"no-caller": "warn",
9+
"no-class-assign": "warn",
10+
"no-compare-neg-zero": "warn",
11+
"no-cond-assign": "warn",
12+
"no-const-assign": "warn",
13+
"no-constant-binary-expression": "warn",
14+
"no-constant-condition": "warn",
15+
"no-control-regex": "warn",
16+
"no-debugger": "warn",
17+
"no-delete-var": "warn",
18+
"no-dupe-class-members": "warn",
19+
"no-dupe-else-if": "warn",
20+
"no-dupe-keys": "warn",
21+
"no-duplicate-case": "warn",
22+
"no-empty-character-class": "warn",
23+
"no-empty-pattern": "warn",
24+
"no-empty-static-block": "warn",
25+
"no-eval": "warn",
26+
"no-ex-assign": "warn",
27+
"no-extra-boolean-cast": "warn",
28+
"no-func-assign": "warn",
29+
"no-global-assign": "warn",
30+
"no-import-assign": "warn",
31+
"no-invalid-regexp": "warn",
32+
"no-irregular-whitespace": "warn",
33+
"no-loss-of-precision": "warn",
34+
"no-new-native-nonconstructor": "warn",
35+
"no-nonoctal-decimal-escape": "warn",
36+
"no-obj-calls": "warn",
37+
"no-self-assign": "warn",
38+
"no-setter-return": "warn",
39+
"no-shadow-restricted-names": "warn",
40+
"no-sparse-arrays": "warn",
41+
"no-this-before-super": "warn",
42+
"no-unassigned-vars": "warn",
43+
"no-unsafe-finally": "warn",
44+
"no-unsafe-negation": "warn",
45+
"no-unsafe-optional-chaining": "warn",
46+
"no-unused-expressions": "warn",
47+
"no-unused-labels": "warn",
48+
"no-unused-private-class-members": "warn",
49+
"no-unused-vars": "warn",
50+
"no-useless-backreference": "warn",
51+
"no-useless-catch": "warn",
52+
"no-useless-escape": "warn",
53+
"no-useless-rename": "warn",
54+
"no-with": "warn",
55+
"require-yield": "warn",
56+
"use-isnan": "warn",
57+
"valid-typeof": "warn",
58+
"oxc/bad-array-method-on-arguments": "warn",
59+
"oxc/bad-char-at-comparison": "warn",
60+
"oxc/bad-comparison-sequence": "warn",
61+
"oxc/bad-min-max-func": "warn",
62+
"oxc/bad-object-literal-comparison": "warn",
63+
"oxc/bad-replace-all-arg": "warn",
64+
"oxc/const-comparisons": "warn",
65+
"oxc/double-comparisons": "warn",
66+
"oxc/erasing-op": "warn",
67+
"oxc/missing-throw": "warn",
68+
"oxc/number-arg-out-of-range": "warn",
69+
"oxc/only-used-in-recursion": "warn",
70+
"oxc/uninvoked-array-callback": "warn",
71+
"typescript/await-thenable": "warn",
72+
"typescript/no-array-delete": "warn",
73+
"typescript/no-base-to-string": "warn",
74+
"typescript/no-duplicate-enum-values": "warn",
75+
"typescript/no-duplicate-type-constituents": "warn",
76+
"typescript/no-extra-non-null-assertion": "warn",
77+
"typescript/no-floating-promises": "warn",
78+
"typescript/no-for-in-array": "warn",
79+
"typescript/no-implied-eval": "warn",
80+
"typescript/no-meaningless-void-operator": "warn",
81+
"typescript/no-misused-new": "warn",
82+
"typescript/no-misused-spread": "warn",
83+
"typescript/no-non-null-asserted-optional-chain": "warn",
84+
"typescript/no-redundant-type-constituents": "warn",
85+
"typescript/no-this-alias": "warn",
86+
"typescript/no-unnecessary-parameter-property-assignment": "warn",
87+
"typescript/no-unsafe-declaration-merging": "warn",
88+
"typescript/no-unsafe-unary-minus": "warn",
89+
"typescript/no-useless-empty-export": "warn",
90+
"typescript/no-wrapper-object-types": "warn",
91+
"typescript/prefer-as-const": "warn",
92+
"typescript/require-array-sort-compare": "warn",
93+
"typescript/restrict-template-expressions": "warn",
94+
"typescript/triple-slash-reference": "warn",
95+
"typescript/unbound-method": "warn",
96+
"unicorn/no-await-in-promise-methods": "warn",
97+
"unicorn/no-empty-file": "warn",
98+
"unicorn/no-invalid-fetch-options": "warn",
99+
"unicorn/no-invalid-remove-event-listener": "warn",
100+
"unicorn/no-new-array": "warn",
101+
"unicorn/no-single-promise-in-promise-methods": "warn",
102+
"unicorn/no-thenable": "warn",
103+
"unicorn/no-unnecessary-await": "warn",
104+
"unicorn/no-useless-fallback-in-spread": "warn",
105+
"unicorn/no-useless-length-check": "warn",
106+
"unicorn/no-useless-spread": "warn",
107+
"unicorn/prefer-set-size": "warn",
108+
"unicorn/prefer-string-starts-ends-with": "warn"
109+
},
110+
"settings": {
111+
"jsx-a11y": {
112+
"polymorphicPropName": null,
113+
"components": {},
114+
"attributes": {}
115+
},
116+
"next": {
117+
"rootDir": []
118+
},
119+
"react": {
120+
"formComponents": [],
121+
"linkComponents": []
122+
},
123+
"jsdoc": {
124+
"ignorePrivate": false,
125+
"ignoreInternal": false,
126+
"ignoreReplacesDocs": true,
127+
"overrideReplacesDocs": true,
128+
"augmentsExtendsReplacesDocs": false,
129+
"implementsReplacesDocs": false,
130+
"exemptDestructuredRootsFromChecks": false,
131+
"tagNamePreference": {}
132+
},
133+
"vitest": {
134+
"typecheck": false
135+
}
136+
},
137+
"env": {
138+
"builtin": true
139+
},
140+
"globals": {},
141+
"ignorePatterns": []
142+
}

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ import { test, expect } from "bun:test";
2828
test("hello world", () => {
2929
expect(1).toBe(1);
3030
});
31-
```
31+
```

README.md

Lines changed: 142 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ docker pull ghcr.io/climactic/backitup:latest
7373

7474
## ⚡ Quick Start
7575

76-
**1.** Create `backitup.config.yaml` ([full reference](docs/configuration.md)):
76+
**1.** Create `backitup.config.yaml` ([configuration reference](docs/configuration.md)):
7777

7878
```yaml
7979
version: "1.0"
@@ -123,25 +123,130 @@ backitup verify --all # Verify integrity
123123

124124
## 📖 Commands
125125

126-
| Command | Description |
127-
| --------------------------- | ------------------------------------------------ |
128-
| `backitup start` | 🚀 Start scheduler daemon |
129-
| `backitup backup` | 💾 Create manual backup |
130-
| `backitup backup -s hourly` | ⏰ Use specific schedule settings |
131-
| `backitup backup --dry-run` | 👀 Preview without creating |
132-
| `backitup cleanup` | 🧹 Clean old backups per retention policy |
133-
| `backitup list` | 📋 List backups (`-s`, `-n`, `--format json/csv`) |
134-
| `backitup verify --all` | ✅ Verify all backup checksums |
135-
136-
### Docker Volume Commands
137-
138-
| Command | Description |
139-
| ------------------------------ | ---------------------------------------- |
140-
| `backitup backup` | Backup both files and Docker volumes |
141-
| `backitup backup --volumes-only` | Only backup Docker volumes |
142-
| `backitup backup --skip-volumes` | Only backup files, skip volumes |
143-
| `backitup backup --volume mydb` | Backup specific volume(s) |
144-
| `backitup list --type volume` | List only volume backups |
126+
All commands support `-c, --config <path>` to specify a config file and `-h, --help` for detailed usage.
127+
128+
| Command | Description | Docs |
129+
| ------------------ | ----------------------- | -------------------------------------- |
130+
| `backitup backup` | Create a backup | [backup.md](docs/commands/backup.md) |
131+
| `backitup start` | Start scheduler daemon | [start.md](docs/commands/start.md) |
132+
| `backitup list` | List existing backups | [list.md](docs/commands/list.md) |
133+
| `backitup cleanup` | Clean old backups | [cleanup.md](docs/commands/cleanup.md) |
134+
| `backitup verify` | Verify backup integrity | [verify.md](docs/commands/verify.md) |
135+
136+
```bash
137+
backitup start # Start scheduler daemon
138+
backitup start -c /etc/backup.yaml
139+
140+
backitup backup # Create backup (interactive)
141+
backitup backup -s daily # Create backup with schedule tag
142+
backitup backup --dry-run # Preview what would be backed up
143+
backitup backup --local-only # Skip S3 upload
144+
backitup backup --volumes-only # Only backup Docker volumes
145+
146+
backitup cleanup # Clean old backups (with confirmation)
147+
backitup cleanup -s daily # Clean only "daily" tagged backups
148+
backitup cleanup --dry-run # Preview deletions
149+
backitup cleanup --force # Skip confirmation
150+
151+
backitup list # List all backups
152+
backitup list -s daily -n 10 # Filter by schedule, limit results
153+
backitup list --format json # Output as JSON or CSV
154+
155+
backitup verify --all # Verify all backup checksums
156+
backitup verify <backup-id> # Verify specific backup
157+
backitup verify --all --fix # Update DB for missing files
158+
```
159+
160+
---
161+
162+
## ⚙️ Inline Configuration
163+
164+
Override config file settings directly from the command line. Useful for quick backups, scripts, or CI/CD pipelines. See [full inline config documentation](docs/inline-config.md).
165+
166+
### Available Options
167+
168+
| Category | Option | Description |
169+
| ----------------- | ------------------------------ | -------------------------------------------- |
170+
| **Database** | `--database <path>` | Database file path |
171+
| **Sources** | `--source <path>` | Source path to backup (can be repeated) |
172+
| | `--pattern <glob>` | Glob pattern for filtering (can be repeated) |
173+
| **Local Storage** | `--local-path <path>` | Local storage path |
174+
| | `--no-local` | Disable local storage |
175+
| **S3 Storage** | `--s3-bucket <name>` | S3 bucket name |
176+
| | `--s3-prefix <prefix>` | S3 key prefix |
177+
| | `--s3-region <region>` | S3 region |
178+
| | `--s3-endpoint <url>` | S3-compatible endpoint URL |
179+
| | `--s3-access-key-id <key>` | S3 access key ID |
180+
| | `--s3-secret-access-key <key>` | S3 secret access key |
181+
| | `--no-s3` | Disable S3 storage |
182+
| **Retention** | `--retention-count <n>` | Maximum backups to keep |
183+
| | `--retention-days <n>` | Maximum days to retain backups |
184+
| **Archive** | `--archive-prefix <str>` | Archive filename prefix |
185+
| | `--compression <0-9>` | Compression level (default: 6) |
186+
| **Safety** | `--verify-before-delete` | Verify checksums before cleanup |
187+
| | `--no-verify-before-delete` | Skip checksum verification |
188+
| **Docker** | `--docker` | Enable Docker volume backups |
189+
| | `--no-docker` | Disable Docker volume backups |
190+
| | `--docker-volume <name>` | Docker volume to backup (can be repeated) |
191+
192+
### Examples
193+
194+
```bash
195+
# Quick backup with inline sources
196+
backitup backup -s manual --source /var/www/app --local-path /backups
197+
198+
# Multiple sources with glob patterns
199+
backitup backup -s manual --source /data --source /logs --pattern "**/*.log" --local-path /backups
200+
201+
# Backup directly to S3
202+
backitup backup -s manual --source /app --s3-bucket my-backups --s3-region us-west-2 --no-local
203+
204+
# Backup with S3 credentials inline
205+
backitup backup -s manual --source /data --s3-bucket my-bucket \
206+
--s3-access-key-id AKIAIOSFODNN7EXAMPLE \
207+
--s3-secret-access-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
208+
209+
# Start scheduler with inline overrides
210+
backitup start --source /data --local-path /backups --s3-bucket my-bucket
211+
212+
# Override retention and compression
213+
backitup backup -s manual --source /db --retention-count 5 --retention-days 7 --compression 9
214+
215+
# Backup Docker volumes inline
216+
backitup backup -s manual --docker-volume postgres_data --docker-volume redis_data --local-path /backups
217+
```
218+
219+
Inline options are merged with your config file. This allows you to use a base config and override specific settings as needed.
220+
221+
### Config-Free Mode
222+
223+
You can run backitup without a config file by providing the required inline options:
224+
225+
**Required options:**
226+
227+
- At least one source: `--source` or `--docker-volume`
228+
- At least one storage: `--local-path` or `--s3-bucket`
229+
230+
```bash
231+
# Minimal backup without config file
232+
backitup backup -s manual --source /data --local-path /backups
233+
234+
# Backup to S3 without config file
235+
backitup backup -s manual --source /app --s3-bucket my-backups --s3-region us-west-2
236+
237+
# Docker volume backup without config file
238+
backitup backup -s manual --docker-volume postgres_data --local-path /backups
239+
240+
# Full example with multiple options
241+
backitup backup -s manual \
242+
--source /var/www/app \
243+
--pattern "**/*.js" --pattern "!**/node_modules/**" \
244+
--local-path /backups \
245+
--retention-count 5 \
246+
--compression 9
247+
```
248+
249+
If you run without a config file and don't provide sufficient options, backitup will tell you what's missing.
145250

146251
---
147252

@@ -274,6 +379,21 @@ WantedBy=multi-user.target
274379

275380
---
276381

382+
## 📚 Documentation
383+
384+
| Document | Description |
385+
| ------------------------------------------------ | -------------------------------- |
386+
| [Configuration Reference](docs/configuration.md) | Complete config file reference |
387+
| [Inline Configuration](docs/inline-config.md) | CLI options and config-free mode |
388+
| **Commands** | |
389+
| [backup](docs/commands/backup.md) | Create backups |
390+
| [start](docs/commands/start.md) | Run scheduler daemon |
391+
| [list](docs/commands/list.md) | List existing backups |
392+
| [cleanup](docs/commands/cleanup.md) | Remove old backups |
393+
| [verify](docs/commands/verify.md) | Verify backup integrity |
394+
395+
---
396+
277397
## 🛠️ Development
278398

279399
```bash
@@ -308,4 +428,5 @@ Title sponsors get their logo showcased here and in the project documentation. [
308428
---
309429

310430
## 📜 License
311-
[![License](https://img.shields.io/github/license/climactic/backitup?style=for-the-badge)](LICENSE)
431+
432+
[![License](https://img.shields.io/github/license/climactic/backitup?style=for-the-badge)](LICENSE)

0 commit comments

Comments
 (0)