backdot 1.6.1 → 1.7.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/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  ```bash
12
12
  npm install -g backdot
13
- backdot --init
13
+ backdot init
14
14
  ```
15
15
 
16
16
  This creates `~/.backdot.json` with sensible defaults and walks you through setup. Open the config file and set your repository URL and the files you want backed up:
@@ -26,13 +26,13 @@ This creates `~/.backdot.json` with sensible defaults and walks you through setu
26
26
  Run your first backup:
27
27
 
28
28
  ```bash
29
- backdot --backup
29
+ backdot backup
30
30
  ```
31
31
 
32
32
  or configure the backport process to run automatically (daily at 2am)
33
33
 
34
34
  ```bash
35
- backdot --schedule
35
+ backdot schedule
36
36
  ```
37
37
 
38
38
  ## Configuration
@@ -51,17 +51,17 @@ Prefix a pattern with `!` to exclude matching files:
51
51
 
52
52
  ## Commands
53
53
 
54
- | Command | Description |
55
- | -------------------------------- | ---------------------------------------------- |
56
- | `--init` | Set up backdot for the first time |
57
- | `--backup` | Run a backup now |
58
- | `--restore` | Restore latest backup from the configured repo |
59
- | `--restore <url>` | Restore from a specific repo URL |
60
- | `--restore [url] --commit <sha>` | Restore from a specific backup commit |
61
- | `--history [url]` | Browse and restore a previous backup |
62
- | `--schedule` | Schedule automatic daily backup (Mac-only) |
63
- | `--unschedule` | Unschedule the daily backup |
64
- | `--status` | Show schedule and resolved file list |
54
+ | Command | Description |
55
+ | ------------------------------ | ---------------------------------------------- |
56
+ | `init` | Set up backdot for the first time |
57
+ | `backup` | Run a backup now |
58
+ | `restore` | Restore latest backup from the configured repo |
59
+ | `restore <url>` | Restore from a specific repo URL |
60
+ | `restore [url] --commit <sha>` | Restore from a specific backup commit |
61
+ | `history [url]` | Browse and restore a previous backup |
62
+ | `schedule` | Schedule automatic daily backup (Mac-only) |
63
+ | `unschedule` | Unschedule the daily backup |
64
+ | `status` | Show schedule and resolved file list |
65
65
 
66
66
  ## Development
67
67
 
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
- import { parseArgs } from "node:util";
4
+ import cac from "cac";
5
5
  import chalk from "chalk";
6
6
  import { CONFIG_PATH } from "./config.js";
7
7
  import { backup } from "./commands/backup.js";
@@ -23,86 +23,40 @@ function getVersion() {
23
23
  return "unknown";
24
24
  }
25
25
  }
26
- function printHelp() {
27
- console.log();
28
- console.log(" Usage: backdot <command>");
29
- console.log();
30
- console.log(" Commands:");
31
- console.log();
32
- console.log(" --init Set up backdot for the first time");
33
- console.log(" --backup Run a backup now");
34
- console.log(" --restore [url] Restore files from the backup repo");
35
- console.log(" --restore [url] --commit <sha> Restore from a specific backup commit");
36
- console.log(" --restore [url] --yes (-y) Accept defaults without prompting");
37
- console.log(" --history [url] Browse and restore a previous backup");
38
- console.log(" --schedule Install daily backup schedule (macOS launchd)");
39
- console.log(" --unschedule Remove the daily backup schedule");
40
- console.log(" --status Show schedule and resolved files");
41
- console.log(" --version Show version");
42
- console.log();
43
- }
44
- async function main() {
45
- let values;
46
- let positionals;
47
- try {
48
- ({ values, positionals } = parseArgs({
49
- args: process.argv.slice(2),
50
- options: {
51
- init: { type: "boolean" },
52
- backup: { type: "boolean" },
53
- restore: { type: "boolean" },
54
- history: { type: "boolean" },
55
- schedule: { type: "boolean" },
56
- unschedule: { type: "boolean" },
57
- status: { type: "boolean" },
58
- version: { type: "boolean" },
59
- help: { type: "boolean" },
60
- commit: { type: "string" },
61
- yes: { type: "boolean", short: "y" },
62
- },
63
- allowPositionals: true,
64
- strict: true,
65
- }));
66
- }
67
- catch (err) {
68
- console.error(`\n Error: ${errorMessage(err)}\n`);
69
- printHelp();
70
- process.exit(1);
26
+ const cli = cac("backdot");
27
+ cli.command("init", "Set up backdot for the first time").action(() => init());
28
+ cli.command("backup", "Run a backup now").action(async () => {
29
+ await backup();
30
+ });
31
+ cli
32
+ .command("restore [url]", "Restore files")
33
+ .option("--commit <sha>", "Restore from a specific backup commit")
34
+ .option("-y, --yes", "Accept defaults without prompting")
35
+ .action(async (url, options) => {
36
+ await restore({ repoUrl: url, commit: options.commit, yes: !!options.yes });
37
+ });
38
+ cli
39
+ .command("history [url]", "List and restore a previous backup")
40
+ .action(async (url) => {
41
+ await history(url);
42
+ });
43
+ cli.command("schedule", "Schedule daily backup").action(() => schedule());
44
+ cli.command("unschedule", "Unschedule the daily backup").action(() => unschedule());
45
+ cli.command("status", "Show the status of the backup").action(async () => {
46
+ await status();
47
+ });
48
+ cli.command("", "").action(() => {
49
+ cli.outputHelp();
50
+ if (!fs.existsSync(CONFIG_PATH)) {
51
+ console.log(` No config found. Run ${chalk.bold("backdot init")} to get started.\n`);
71
52
  }
53
+ });
54
+ cli.help();
55
+ cli.version(getVersion());
56
+ async function main() {
72
57
  try {
73
- if (values.init) {
74
- init();
75
- }
76
- else if (values.backup) {
77
- await backup();
78
- }
79
- else if (values.schedule) {
80
- schedule();
81
- }
82
- else if (values.unschedule) {
83
- unschedule();
84
- }
85
- else if (values.status) {
86
- await status();
87
- }
88
- else if (values.restore) {
89
- await restore(positionals[0], values.commit, {
90
- yes: !!values.yes,
91
- });
92
- }
93
- else if (values.history) {
94
- await history(positionals[0]);
95
- }
96
- else if (values.version) {
97
- console.log(getVersion());
98
- }
99
- else {
100
- printHelp();
101
- if (!fs.existsSync(CONFIG_PATH)) {
102
- console.log(` No config found. Run ${chalk.bold("backdot --init")} to get started.`);
103
- console.log();
104
- }
105
- }
58
+ cli.parse(process.argv, { run: false });
59
+ await cli.runMatchedCommand();
106
60
  }
107
61
  catch (err) {
108
62
  const msg = errorMessage(err);
@@ -22,7 +22,7 @@ export async function history(repoUrl) {
22
22
  console.log("\n No backup history found.\n");
23
23
  return;
24
24
  }
25
- const selected = await select({
25
+ const selectedCommit = await select({
26
26
  message: "Select a backup to restore from:",
27
27
  loop: false,
28
28
  choices: commits.map((c) => ({
@@ -31,5 +31,5 @@ export async function history(repoUrl) {
31
31
  })),
32
32
  });
33
33
  console.log();
34
- await restore(repoUrl, selected);
34
+ await restore({ repoUrl, commit: selectedCommit });
35
35
  }
@@ -50,8 +50,8 @@ export function init() {
50
50
  // Step 3
51
51
  console.log(chalk.bold(" Step 3 — Run your first backup"));
52
52
  console.log();
53
- console.log(` ${chalk.bold("backdot --backup")} Run a one-time backup`);
54
- console.log(` ${chalk.bold("backdot --schedule")} Schedule daily backups (macOS)`);
55
- console.log(` ${chalk.bold("backdot --status")} Check which files will be backed up`);
53
+ console.log(` ${chalk.bold("backdot backup")} Run a one-time backup`);
54
+ console.log(` ${chalk.bold("backdot schedule")} Schedule daily backups (macOS)`);
55
+ console.log(` ${chalk.bold("backdot status")} Check which files will be backed up`);
56
56
  console.log();
57
57
  }
@@ -1,5 +1,5 @@
1
- interface RestoreOptions {
1
+ export declare function restore({ repoUrl, commit, yes, }?: {
2
+ repoUrl?: string;
3
+ commit?: string;
2
4
  yes?: boolean;
3
- }
4
- export declare function restore(repoUrl?: string, commit?: string, options?: RestoreOptions): Promise<void>;
5
- export {};
5
+ }): Promise<void>;
@@ -58,7 +58,7 @@ async function resolveRepoAndMachine(repoUrl, commit) {
58
58
  }
59
59
  return { repository: repoUrl, machine };
60
60
  }
61
- export async function restore(repoUrl, commit, options = {}) {
61
+ export async function restore({ repoUrl, commit, yes, } = {}) {
62
62
  logger.info("Starting restore");
63
63
  const { repository, machine } = await resolveRepoAndMachine(repoUrl, commit);
64
64
  const spinner = ora("Fetching latest backup").start();
@@ -102,7 +102,7 @@ export async function restore(repoUrl, commit, options = {}) {
102
102
  spinner.stop();
103
103
  console.log();
104
104
  let toRestore;
105
- if (options.yes) {
105
+ if (yes) {
106
106
  toRestore = fresh;
107
107
  if (existing.length > 0) {
108
108
  console.log(` Skipped ${pluralize(existing.length, "existing file")}. Run without --yes to select them.`);
@@ -13,7 +13,7 @@ function tildePath(filePath) {
13
13
  export async function status() {
14
14
  const scheduled = isScheduled();
15
15
  console.log();
16
- console.log(` Schedule: ${scheduled ? "active (daily at 02:00)" : `not active (run ${chalk.bold("backdot --schedule")} to enable)`}`);
16
+ console.log(` Schedule: ${scheduled ? "active (daily at 02:00)" : `not active (run ${chalk.bold("backdot schedule")} to enable)`}`);
17
17
  const config = loadConfig();
18
18
  console.log(` Repo: ${config.repository}`);
19
19
  console.log(` Machine: ${config.machine}`);
@@ -59,7 +59,7 @@ export async function status() {
59
59
  }
60
60
  console.log();
61
61
  }
62
- console.log(` Run ${chalk.bold("backdot --backup")} to back up all changes.`);
62
+ console.log(` Run ${chalk.bold("backdot backup")} to back up all changes.`);
63
63
  }
64
64
  }
65
65
  catch (err) {
package/dist/config.js CHANGED
@@ -21,7 +21,7 @@ const ConfigSchema = z.object({
21
21
  });
22
22
  export function loadConfig() {
23
23
  if (!fs.existsSync(CONFIG_PATH)) {
24
- throw new Error(`Config file not found: ${CONFIG_PATH}\n Run "backdot --init" to create it.`);
24
+ throw new Error(`Config file not found: ${CONFIG_PATH}\n Run "backdot init" to create it.`);
25
25
  }
26
26
  let raw;
27
27
  try {
package/dist/launchd.js CHANGED
@@ -33,7 +33,7 @@ function buildPlist() {
33
33
  <array>
34
34
  <string>${escapeXml(nodePath)}</string>
35
35
  <string>${escapeXml(scriptPath)}</string>
36
- <string>--backup</string>
36
+ <string>backup</string>
37
37
  </array>
38
38
  <key>WorkingDirectory</key>
39
39
  <string>${escapeXml(workingDir)}</string>
package/dist/staging.js CHANGED
@@ -47,7 +47,7 @@ export async function compareFiles(files, machine, repository) {
47
47
  return { backedUp: [], modified: [], notBackedUp: [] };
48
48
  }
49
49
  if (!fs.existsSync(STAGING_GIT_DIR)) {
50
- return failedComparisonResult(new Error("Backup repository not found. Run backdot --backup first."));
50
+ return failedComparisonResult(new Error('Backup repository not found. Run "backdot backup" first.'));
51
51
  }
52
52
  const git = simpleGit(STAGING_DIR);
53
53
  try {
@@ -113,7 +113,7 @@ This repository contains files backed up automatically using [backdot](https://g
113
113
  ## Restore
114
114
 
115
115
  \`\`\`bash
116
- npx backdot --restore ${repository}
116
+ npx backdot restore ${repository}
117
117
  \`\`\`
118
118
 
119
119
  For full documentation, configuration options, and scheduling, see the [official README](https://github.com/sorenlouv/backdot).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backdot",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "description": "Lightweight CLI to backup dotfiles and gitignored files to a Git repo on a daily schedule",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -41,6 +41,7 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@inquirer/prompts": "^8.3.0",
44
+ "cac": "^7.0.0",
44
45
  "chalk": "^5.6.2",
45
46
  "fast-glob": "^3.3.3",
46
47
  "ora": "^9.3.0",