gitlo 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +496 -0
- package/dist/backup.js +108 -0
- package/dist/cli.js +346 -0
- package/dist/config-manager.js +79 -0
- package/dist/cron.js +177 -0
- package/dist/github.js +88 -0
- package/dist/index.js +30 -0
- package/dist/types.js +2 -0
- package/package.json +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 gitlo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# šļø gitlo
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/gitlo)
|
|
6
|
+
[](https://www.npmjs.com/package/gitlo)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](https://nodejs.org)
|
|
9
|
+
|
|
10
|
+
**Backup all your GitHub repositories locally with one command.**
|
|
11
|
+
|
|
12
|
+
Never lose your code to account deletions, suspensions, or unexpected issues.
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## ⨠Features
|
|
19
|
+
|
|
20
|
+
- š **Secure** - Token stored locally in `~/.gitlo/config.json`
|
|
21
|
+
- š“ **Fork Support** - Optionally backup forked repositories
|
|
22
|
+
- š **Private Repos** - Backs up private repositories with proper token
|
|
23
|
+
- ā° **Auto-Schedule** - Built-in cron scheduler for automatic backups
|
|
24
|
+
- š **Progress Tracking** - Visual progress with spinners and stats
|
|
25
|
+
- š **Fast** - Only updates changed repos with `--update` flag
|
|
26
|
+
- š **Logging** - Full logs of backup operations
|
|
27
|
+
- šÆ **Dry Run** - Preview what will be backed up without downloading
|
|
28
|
+
|
|
29
|
+
## š¤ Why?
|
|
30
|
+
|
|
31
|
+
GitHub accounts can be deleted, suspended, or compromised. This tool creates a local backup of all your repositories so you always have a copy of your work.
|
|
32
|
+
|
|
33
|
+
## š¦ Installation
|
|
34
|
+
|
|
35
|
+
### Quick Install (npm - Recommended)
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install -g gitlo
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Or with other package managers:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# pnpm
|
|
45
|
+
pnpm add -g gitlo
|
|
46
|
+
|
|
47
|
+
# yarn
|
|
48
|
+
yarn global add gitlo
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Requirements
|
|
52
|
+
|
|
53
|
+
- **Node.js** >= 18.0.0
|
|
54
|
+
- **Git** installed on your system
|
|
55
|
+
|
|
56
|
+
### Alternative: Install from Source
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Clone and build
|
|
60
|
+
git clone https://github.com/dropocol/gitlo.git
|
|
61
|
+
cd gitlo
|
|
62
|
+
pnpm install
|
|
63
|
+
pnpm run build
|
|
64
|
+
|
|
65
|
+
# Link globally
|
|
66
|
+
pnpm link --global
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Getting a GitHub Token
|
|
70
|
+
|
|
71
|
+
1. Go to [https://github.com/settings/tokens](https://github.com/settings/tokens)
|
|
72
|
+
2. Click "Generate new token (classic)"
|
|
73
|
+
3. Select these scopes:
|
|
74
|
+
- `repo` - Full control of private repositories
|
|
75
|
+
- `read:user` - Read user profile data
|
|
76
|
+
4. Generate and copy the token
|
|
77
|
+
|
|
78
|
+
## š Quick Start
|
|
79
|
+
|
|
80
|
+
### 1. Get a GitHub Token
|
|
81
|
+
|
|
82
|
+
1. Go to [GitHub Settings ā Tokens](https://github.com/settings/tokens)
|
|
83
|
+
2. Click "Generate new token (classic)"
|
|
84
|
+
3. Select scopes: āļø `repo` and āļø `read:user`
|
|
85
|
+
4. Generate and copy the token
|
|
86
|
+
|
|
87
|
+
### 2. Configure gitlo (One-time setup)
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Save your token
|
|
91
|
+
gitlo config set token ghp_xxxxxxxxxxxx
|
|
92
|
+
|
|
93
|
+
# Optional: Set backup directory
|
|
94
|
+
gitlo config set output-dir ~/backups/github
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 3. Run Backup
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Backup all your repos
|
|
101
|
+
gitlo
|
|
102
|
+
|
|
103
|
+
# Include forks too
|
|
104
|
+
gitlo --include-forks
|
|
105
|
+
|
|
106
|
+
# Setup automatic daily backups
|
|
107
|
+
gitlo schedule setup --frequency daily
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Commands
|
|
111
|
+
|
|
112
|
+
### `gitlo`
|
|
113
|
+
|
|
114
|
+
Run the backup with configured settings.
|
|
115
|
+
|
|
116
|
+
### `gitlo config`
|
|
117
|
+
|
|
118
|
+
Manage gitlo configuration settings (token, output directory).
|
|
119
|
+
|
|
120
|
+
### `gitlo schedule`
|
|
121
|
+
|
|
122
|
+
Schedule automatic backups with cron (built-in scheduler).
|
|
123
|
+
|
|
124
|
+
## All Commands & Options
|
|
125
|
+
|
|
126
|
+
### Main Backup Command
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
gitlo [options]
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Options:**
|
|
133
|
+
|
|
134
|
+
- `-t, --token <token>` - GitHub personal access token
|
|
135
|
+
- `-o, --output-dir <dir>` - Output directory for backups
|
|
136
|
+
- `-m, --method <method>` - Clone method: https or ssh (default: https)
|
|
137
|
+
- `--include-private` - Include private repositories (default: true)
|
|
138
|
+
- `--exclude-private` - Exclude private repositories
|
|
139
|
+
- `--include-forks` - Include forked repositories (default: false)
|
|
140
|
+
- `--dry-run` - Show what would be backed up without cloning
|
|
141
|
+
- `--update` - Update existing repositories with git pull
|
|
142
|
+
- `-v, --verbose` - Show detailed progress and filtering information
|
|
143
|
+
- `-h, --help` - Display help
|
|
144
|
+
|
|
145
|
+
### ā ļø Important: Forks Are Excluded by Default
|
|
146
|
+
|
|
147
|
+
By default, `gitlo` **does not backup forked repositories**. If you have forks you want to backup, use `--include-forks`:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# Backup everything including forks
|
|
151
|
+
gitlo --include-forks
|
|
152
|
+
|
|
153
|
+
# Backup only your own repos (no forks) - this is the default
|
|
154
|
+
gitlo
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Config Commands
|
|
158
|
+
|
|
159
|
+
#### `gitlo config set`
|
|
160
|
+
|
|
161
|
+
Set a configuration value.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
gitlo config set token <github-token>
|
|
165
|
+
gitlo config set output-dir <path>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Examples:**
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# Set your GitHub token
|
|
172
|
+
gitlo config set token ghp_xxxxxxxxxxxx
|
|
173
|
+
|
|
174
|
+
# Set default backup directory
|
|
175
|
+
gitlo config set output-dir ~/backups/github-repos
|
|
176
|
+
|
|
177
|
+
# Use ~ for home directory (automatically expanded)
|
|
178
|
+
gitlo config set output-dir ~/Documents/GitHub-Backups
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
#### `gitlo config get`
|
|
182
|
+
|
|
183
|
+
View a specific configuration value.
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
gitlo config get token
|
|
187
|
+
gitlo config get output-dir
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Output:**
|
|
191
|
+
|
|
192
|
+
- Token is masked for security (shows: `ghp_****xxxx`)
|
|
193
|
+
- Output-dir shows the full path
|
|
194
|
+
|
|
195
|
+
#### `gitlo config list`
|
|
196
|
+
|
|
197
|
+
List all configuration values.
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
gitlo config list
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Output:**
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
š gitlo Configuration
|
|
207
|
+
|
|
208
|
+
token: ghp_****xxxx
|
|
209
|
+
output-dir: /Users/username/backups/github-repos
|
|
210
|
+
|
|
211
|
+
Config file: /Users/username/.gitlo/config.json
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
#### `gitlo config remove`
|
|
215
|
+
|
|
216
|
+
Remove a configuration value.
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
gitlo config remove token
|
|
220
|
+
gitlo config remove output-dir
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Schedule Commands
|
|
224
|
+
|
|
225
|
+
#### `gitlo schedule setup`
|
|
226
|
+
|
|
227
|
+
Schedule automatic backups with cron.
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Weekly on Sunday at 2 AM (default)
|
|
231
|
+
gitlo schedule setup
|
|
232
|
+
|
|
233
|
+
# Daily at 3 AM
|
|
234
|
+
gitlo schedule setup --frequency daily --time 03:00
|
|
235
|
+
|
|
236
|
+
# Weekly on Monday at 2 AM
|
|
237
|
+
gitlo schedule setup --frequency weekly --day 1
|
|
238
|
+
|
|
239
|
+
# Monthly on the 1st at 2 AM
|
|
240
|
+
gitlo schedule setup --frequency monthly
|
|
241
|
+
|
|
242
|
+
# Hourly (only updates existing repos)
|
|
243
|
+
gitlo schedule setup --frequency hourly --update
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
#### `gitlo schedule list`
|
|
247
|
+
|
|
248
|
+
View scheduled backup jobs.
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
gitlo schedule list
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
#### `gitlo schedule remove`
|
|
255
|
+
|
|
256
|
+
Remove automatic backup schedule.
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
gitlo schedule remove
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Configuration Priority
|
|
263
|
+
|
|
264
|
+
### Token Priority (first found wins):
|
|
265
|
+
|
|
266
|
+
1. CLI argument: `gitlo -t TOKEN`
|
|
267
|
+
2. Environment variable: `GITHUB_TOKEN`
|
|
268
|
+
3. Config file: `gitlo config set token TOKEN`
|
|
269
|
+
|
|
270
|
+
### Output Directory Priority:
|
|
271
|
+
|
|
272
|
+
1. CLI argument: `gitlo -o ~/my-backups`
|
|
273
|
+
2. Config file: `gitlo config set output-dir ~/backups`
|
|
274
|
+
3. Default: your GitHub username as folder name
|
|
275
|
+
|
|
276
|
+
## Usage Examples
|
|
277
|
+
|
|
278
|
+
### One-Time Setup (Recommended)
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
# Step 1: Save your token
|
|
282
|
+
gitlo config set token ghp_your_token_here
|
|
283
|
+
|
|
284
|
+
# Step 2: Set default backup location (optional)
|
|
285
|
+
gitlo config set output-dir ~/backups/github
|
|
286
|
+
|
|
287
|
+
# Step 3: Run backup anytime
|
|
288
|
+
gitlo
|
|
289
|
+
|
|
290
|
+
# Update existing backups
|
|
291
|
+
gitlo --update
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Without Config (One-Time Use)
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
# Using environment variable
|
|
298
|
+
export GITHUB_TOKEN=your_token_here
|
|
299
|
+
gitlo
|
|
300
|
+
|
|
301
|
+
# Using CLI argument
|
|
302
|
+
gitlo -t your_token_here
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Common Workflows
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
# Dry run to preview what will be backed up
|
|
309
|
+
gitlo --dry-run
|
|
310
|
+
|
|
311
|
+
# Backup to specific directory (overrides config)
|
|
312
|
+
gitlo -o ~/backups/my-github-repos
|
|
313
|
+
|
|
314
|
+
# Use SSH for cloning (requires SSH key setup)
|
|
315
|
+
gitlo -m ssh
|
|
316
|
+
|
|
317
|
+
# Only public repos, no forks
|
|
318
|
+
gitlo --exclude-private
|
|
319
|
+
|
|
320
|
+
# Include forks
|
|
321
|
+
gitlo --include-forks
|
|
322
|
+
|
|
323
|
+
# Weekly update of all existing backups
|
|
324
|
+
gitlo --update
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Development
|
|
328
|
+
|
|
329
|
+
If you want to contribute or modify the code:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
# Install all dependencies (including dev)
|
|
333
|
+
pnpm install
|
|
334
|
+
|
|
335
|
+
# Build TypeScript to JavaScript
|
|
336
|
+
pnpm run build
|
|
337
|
+
|
|
338
|
+
# Run in development mode
|
|
339
|
+
pnpm run dev
|
|
340
|
+
|
|
341
|
+
# Clean build artifacts
|
|
342
|
+
pnpm run clean
|
|
343
|
+
|
|
344
|
+
# Test local changes globally
|
|
345
|
+
pnpm link --global
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Publishing
|
|
349
|
+
|
|
350
|
+
When you're ready to publish to npm:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
# The prepublishOnly script automatically builds before publishing
|
|
354
|
+
pnpm publish
|
|
355
|
+
|
|
356
|
+
# Or publish to npm
|
|
357
|
+
npm publish
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## What Gets Backed Up?
|
|
361
|
+
|
|
362
|
+
- ā
All your repositories (public by default)
|
|
363
|
+
- ā
Private repositories (if `--include-private`)
|
|
364
|
+
- ā
Forks (if `--include-forks`)
|
|
365
|
+
- ā
Full git history and all branches
|
|
366
|
+
- ā ļø Issues, PRs, and wiki pages are NOT included (only git repos)
|
|
367
|
+
|
|
368
|
+
## Output Structure
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
your-backup-directory/
|
|
372
|
+
āāā repo-1/
|
|
373
|
+
ā āāā .git/
|
|
374
|
+
āāā repo-2/
|
|
375
|
+
ā āāā .git/
|
|
376
|
+
āāā repo-3/
|
|
377
|
+
āāā .git/
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## Automation
|
|
381
|
+
|
|
382
|
+
### Automatic Backups with Cron (Built-in)
|
|
383
|
+
|
|
384
|
+
`gitlo` has a built-in scheduler to automatically backup your repos:
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
# Setup weekly backups (default: Sundays at 2 AM)
|
|
388
|
+
gitlo schedule setup
|
|
389
|
+
|
|
390
|
+
# Setup daily backups at 3 AM
|
|
391
|
+
gitlo schedule setup --frequency daily --time 03:00
|
|
392
|
+
|
|
393
|
+
# Setup weekly on Mondays at 2 AM
|
|
394
|
+
gitlo schedule setup --frequency weekly --day 1 --time 02:00
|
|
395
|
+
|
|
396
|
+
# Only update existing repos (faster)
|
|
397
|
+
gitlo schedule setup --update
|
|
398
|
+
|
|
399
|
+
# View scheduled jobs
|
|
400
|
+
gitlo schedule list
|
|
401
|
+
|
|
402
|
+
# Remove scheduled backups
|
|
403
|
+
gitlo schedule remove
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
#### Schedule Options
|
|
407
|
+
|
|
408
|
+
- `-f, --frequency <freq>` - hourly, daily, weekly, monthly (default: weekly)
|
|
409
|
+
- `-t, --time <time>` - Time in HH:MM format (default: 02:00)
|
|
410
|
+
- `-d, --day <day>` - Day of week 0-6 for weekly (0=Sunday, default: 0)
|
|
411
|
+
- `-u, --update` - Only update existing repos, don't clone new ones
|
|
412
|
+
- `-l, --log <path>` - Log file path (default: ~/.gitlo/backup.log)
|
|
413
|
+
|
|
414
|
+
### Manual Cron Setup (Advanced)
|
|
415
|
+
|
|
416
|
+
If you prefer manual setup:
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
# Edit crontab
|
|
420
|
+
crontab -e
|
|
421
|
+
|
|
422
|
+
# Add line to backup weekly (Sundays at 2 AM)
|
|
423
|
+
0 2 * * 0 /usr/local/bin/gitlo --update >> /var/log/gitlo.log 2>&1
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Quick Install (npm)
|
|
427
|
+
|
|
428
|
+
```bash
|
|
429
|
+
npm install -g gitlo && gitlo config set token YOUR_TOKEN && gitlo
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### One-liner for Development Setup
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
cd ~ && git clone https://github.com/dropocol/gitlo.git && cd gitlo && pnpm install && pnpm run build && pnpm link --global && echo "Setup complete. Run: gitlo config set token YOUR_TOKEN"
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
## Security Notes
|
|
439
|
+
|
|
440
|
+
- Your GitHub token is stored in `~/.gitlo/config.json` on your local machine
|
|
441
|
+
- The token is masked when displayed (shows: `ghp_****xxxx`)
|
|
442
|
+
- Keep your config file secure - it contains your GitHub token!
|
|
443
|
+
- Use file permissions to protect the config: `chmod 600 ~/.gitlo/config.json`
|
|
444
|
+
|
|
445
|
+
## Troubleshooting
|
|
446
|
+
|
|
447
|
+
### "Not all repositories were backed up"
|
|
448
|
+
|
|
449
|
+
If `gitlo` reports fewer repositories than you have on GitHub, it's likely due to filtering:
|
|
450
|
+
|
|
451
|
+
**1. Forks are excluded by default**
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
# Check if you have forks being skipped
|
|
455
|
+
gitlo --dry-run
|
|
456
|
+
|
|
457
|
+
# Include forks in backup
|
|
458
|
+
gitlo --include-forks
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
**2. Private repos might be excluded**
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
# By default, private repos ARE included
|
|
465
|
+
# But if you used --exclude-private:
|
|
466
|
+
gitlo --include-private
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
**3. Use verbose mode to see what's being filtered**
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
# See detailed information about fetching and filtering
|
|
473
|
+
gitlo -v
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### "Bad credentials" Error
|
|
477
|
+
|
|
478
|
+
Your token is invalid or expired. Generate a new one at [https://github.com/settings/tokens](https://github.com/settings/tokens)
|
|
479
|
+
|
|
480
|
+
### SSH Cloning Fails
|
|
481
|
+
|
|
482
|
+
Make sure you have SSH keys set up:
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
ssh-keygen -t ed25519 -C "your@email.com"
|
|
486
|
+
ssh-add ~/.ssh/id_ed25519
|
|
487
|
+
# Add public key to GitHub: https://github.com/settings/keys
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Rate Limiting
|
|
491
|
+
|
|
492
|
+
The tool handles pagination automatically. If you have 1000+ repos, it may take a while.
|
|
493
|
+
|
|
494
|
+
## License
|
|
495
|
+
|
|
496
|
+
MIT
|
package/dist/backup.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.cloneOrUpdateRepo = cloneOrUpdateRepo;
|
|
40
|
+
exports.displayRepoList = displayRepoList;
|
|
41
|
+
exports.displaySummary = displaySummary;
|
|
42
|
+
exports.ensureDirectory = ensureDirectory;
|
|
43
|
+
const simple_git_1 = __importDefault(require("simple-git"));
|
|
44
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
45
|
+
const ora_1 = __importDefault(require("ora"));
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
async function cloneOrUpdateRepo(repo, repoPath, options, progress, index, total) {
|
|
49
|
+
const repoSpinner = (0, ora_1.default)(`${progress} Processing ${repo.name}...`).start();
|
|
50
|
+
try {
|
|
51
|
+
if (fs.existsSync(repoPath)) {
|
|
52
|
+
if (options.updateExisting) {
|
|
53
|
+
repoSpinner.text = `${progress} Updating ${repo.name}...`;
|
|
54
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
55
|
+
await git.pull('origin', 'main').catch(async () => {
|
|
56
|
+
// Try master if main fails
|
|
57
|
+
await git.pull('origin', 'master');
|
|
58
|
+
});
|
|
59
|
+
repoSpinner.succeed(`${progress} ${chalk_1.default.green('ā')} Updated ${chalk_1.default.white(repo.name)}`);
|
|
60
|
+
return { status: 'updated' };
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
repoSpinner.warn(`${progress} ${chalk_1.default.yellow('ā ')} ${repo.name} already exists (use --update to pull changes)`);
|
|
64
|
+
return { status: 'skipped' };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
repoSpinner.text = `${progress} Cloning ${repo.name}...`;
|
|
69
|
+
const cloneUrl = options.method === 'ssh' ? repo.sshUrl : repo.cloneUrl;
|
|
70
|
+
const parentDir = path.dirname(repoPath);
|
|
71
|
+
await (0, simple_git_1.default)(parentDir).clone(cloneUrl, repoPath);
|
|
72
|
+
repoSpinner.succeed(`${progress} ${chalk_1.default.green('ā')} Cloned ${chalk_1.default.white(repo.name)}`);
|
|
73
|
+
return { status: 'cloned' };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
repoSpinner.fail(`${progress} ${chalk_1.default.red('ā')} Failed to process ${repo.name}`);
|
|
78
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
79
|
+
console.error(chalk_1.default.red(` Error: ${errorMessage}`));
|
|
80
|
+
return { status: 'error', error: errorMessage };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function displayRepoList(repos) {
|
|
84
|
+
console.log(chalk_1.default.bold('\nš Repositories to backup:\n'));
|
|
85
|
+
repos.forEach((repo, i) => {
|
|
86
|
+
const privacy = repo.isPrivate ? chalk_1.default.red('š') : chalk_1.default.green('š');
|
|
87
|
+
console.log(` ${i + 1}. ${privacy} ${chalk_1.default.white(repo.name)}`);
|
|
88
|
+
if (repo.description) {
|
|
89
|
+
console.log(` ${chalk_1.default.gray(repo.description)}`);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function displaySummary(stats, updateExisting, backupPath) {
|
|
94
|
+
console.log(chalk_1.default.bold('\nš Backup Summary\n'));
|
|
95
|
+
console.log(` ${chalk_1.default.green('ā')} Successfully cloned: ${stats.successCount}`);
|
|
96
|
+
if (updateExisting) {
|
|
97
|
+
console.log(` ${chalk_1.default.blue('ā»')} Updated: ${stats.updateCount}`);
|
|
98
|
+
}
|
|
99
|
+
if (stats.errorCount > 0) {
|
|
100
|
+
console.log(` ${chalk_1.default.red('ā')} Failed: ${stats.errorCount}`);
|
|
101
|
+
}
|
|
102
|
+
console.log(`\n ${chalk_1.default.bold('Location:')} ${chalk_1.default.cyan(backupPath)}\n`);
|
|
103
|
+
}
|
|
104
|
+
function ensureDirectory(dirPath) {
|
|
105
|
+
if (!fs.existsSync(dirPath)) {
|
|
106
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
107
|
+
}
|
|
108
|
+
}
|