git-drive 0.1.1 → 0.1.3

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.
@@ -1,16 +1,42 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.init = init;
4
7
  const fs_1 = require("fs");
5
8
  const path_1 = require("path");
9
+ const prompts_1 = __importDefault(require("prompts"));
6
10
  const config_js_1 = require("../config.js");
11
+ const git_js_1 = require("../git.js");
7
12
  const errors_js_1 = require("../errors.js");
8
- function init(args) {
13
+ async function init(args) {
14
+ let drivePath;
9
15
  const rawPath = args[0];
10
16
  if (!rawPath) {
11
- throw new errors_js_1.GitDriveError("Usage: git drive init <path>");
17
+ // No argument provided - prompt user to select a drive
18
+ const drives = await (0, git_js_1.listDrives)();
19
+ if (drives.length === 0) {
20
+ throw new errors_js_1.GitDriveError("No external drives found. Please connect a drive and try again.");
21
+ }
22
+ const { selectedDrive } = await (0, prompts_1.default)({
23
+ type: "select",
24
+ name: "selectedDrive",
25
+ message: "Select a drive to initialize git-drive:",
26
+ choices: drives.map((d) => ({
27
+ title: `${d.filesystem} (${d.mounted}) - ${Math.round((d.available / d.blocks) * 100)}% free`,
28
+ value: d.mounted,
29
+ })),
30
+ });
31
+ if (!selectedDrive) {
32
+ console.log("Operation cancelled.");
33
+ return;
34
+ }
35
+ drivePath = (0, path_1.resolve)(selectedDrive);
36
+ }
37
+ else {
38
+ drivePath = (0, path_1.resolve)(rawPath);
12
39
  }
13
- const drivePath = (0, path_1.resolve)(rawPath);
14
40
  if (!(0, fs_1.existsSync)(drivePath)) {
15
41
  throw new errors_js_1.GitDriveError(`Path not found: ${drivePath}\nIs the drive mounted?`);
16
42
  }
@@ -23,5 +49,7 @@ function init(args) {
23
49
  (0, fs_1.mkdirSync)(storePath, { recursive: true });
24
50
  }
25
51
  (0, config_js_1.saveConfig)({ drivePath });
26
- console.log(`Drive configured: ${storePath}`);
52
+ console.log(`\n✅ Git Drive initialized!`);
53
+ console.log(` Drive: ${drivePath}`);
54
+ console.log(` Store: ${storePath}`);
27
55
  }
package/dist/config.js CHANGED
@@ -36,7 +36,7 @@ function assertDriveMounted(drivePath) {
36
36
  }
37
37
  }
38
38
  function getDriveStorePath(drivePath) {
39
- return (0, path_1.join)(drivePath, "git-drive");
39
+ return (0, path_1.join)(drivePath, ".git-drive");
40
40
  }
41
41
  const LINKS_FILE = (0, path_1.join)(CONFIG_DIR, "links.json");
42
42
  function loadLinks() {
package/dist/index.js CHANGED
@@ -2,12 +2,17 @@
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const child_process_1 = require("child_process");
5
+ const fs_1 = require("fs");
5
6
  const push_js_1 = require("./commands/push.js");
6
7
  const list_js_1 = require("./commands/list.js");
7
8
  const status_js_1 = require("./commands/status.js");
8
9
  const link_js_1 = require("./commands/link.js");
10
+ const init_js_1 = require("./commands/init.js");
9
11
  const errors_js_1 = require("./errors.js");
12
+ const server_js_1 = require("./server.js");
13
+ const { version: VERSION } = JSON.parse((0, fs_1.readFileSync)(__dirname + '/../package.json', 'utf-8'));
10
14
  const commands = {
15
+ init: init_js_1.init,
11
16
  push: push_js_1.push,
12
17
  list: list_js_1.list,
13
18
  status: status_js_1.status,
@@ -16,6 +21,8 @@ const commands = {
16
21
  start: startServer,
17
22
  ui: startServer,
18
23
  };
24
+ // Commands that don't need the server running
25
+ const NO_SERVER_COMMANDS = ['server', 'start', 'ui'];
19
26
  function printUsage() {
20
27
  console.log(`
21
28
  git-drive - Turn any external drive into a git remote backup for your code
@@ -24,6 +31,7 @@ Usage:
24
31
  git-drive <command> [options]
25
32
 
26
33
  Commands:
34
+ init Initialize git-drive on an external drive
27
35
  link Link current repo to a drive
28
36
  push Push current repo to drive
29
37
  list Show connected drives and their status
@@ -31,9 +39,11 @@ Commands:
31
39
  server, start, ui Start the git-drive web UI server
32
40
 
33
41
  Options:
42
+ -v, -V, --version Show version number
34
43
  -h, --help Show this help message
35
44
 
36
45
  Examples:
46
+ git-drive init /Volumes/MyDrive Initialize git-drive on a drive
37
47
  git-drive link Link current repo to a drive
38
48
  git-drive push Push current repo to drive
39
49
  git-drive list List connected drives
@@ -74,12 +84,21 @@ const [command, ...args] = process.argv.slice(2);
74
84
  printUsage();
75
85
  process.exit(0);
76
86
  }
87
+ // Handle version flags
88
+ if (command === "--version" || command === "-v" || command === "-V" || command === "version") {
89
+ console.log(`git-drive v${VERSION}`);
90
+ process.exit(0);
91
+ }
77
92
  const handler = commands[command];
78
93
  if (!handler) {
79
94
  console.error(`Unknown command: ${command}\n`);
80
95
  printUsage();
81
96
  process.exit(1);
82
97
  }
98
+ // Ensure server is running for commands that need it
99
+ if (!NO_SERVER_COMMANDS.includes(command)) {
100
+ await (0, server_js_1.ensureServerRunning)();
101
+ }
83
102
  await handler(args);
84
103
  }
85
104
  catch (err) {
package/dist/server.js CHANGED
@@ -1,16 +1,18 @@
1
- #!/usr/bin/env node
2
1
  "use strict";
3
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
4
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
4
  };
6
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getServerPort = getServerPort;
7
+ exports.isServerRunning = isServerRunning;
8
+ exports.ensureServerRunning = ensureServerRunning;
7
9
  const express_1 = __importDefault(require("express"));
10
+ const child_process_1 = require("child_process");
8
11
  const path_1 = __importDefault(require("path"));
9
12
  const fs_1 = require("fs");
10
- const child_process_1 = require("child_process");
13
+ const child_process_2 = require("child_process");
11
14
  const node_disk_info_1 = require("node-disk-info");
12
15
  const os_1 = require("os");
13
- const __dirname = path_1.default.dirname(__filename);
14
16
  const app = (0, express_1.default)();
15
17
  const port = process.env.GIT_DRIVE_PORT || 4483;
16
18
  app.use(express_1.default.json());
@@ -19,7 +21,7 @@ const uiPath = path_1.default.join(__dirname, '..', 'ui');
19
21
  app.use(express_1.default.static(uiPath));
20
22
  // ── Helpers ──────────────────────────────────────────────────────────
21
23
  function git(args, cwd) {
22
- return (0, child_process_1.execSync)(`git ${args}`, {
24
+ return (0, child_process_2.execSync)(`git ${args}`, {
23
25
  cwd,
24
26
  encoding: 'utf-8',
25
27
  stdio: ['pipe', 'pipe', 'pipe'],
@@ -70,7 +72,57 @@ function loadLinks() {
70
72
  return {};
71
73
  }
72
74
  }
75
+ // ── Server Health Check Utilities ────────────────────────────────────────────
76
+ const DEFAULT_PORT = 4483;
77
+ function getServerPort() {
78
+ return parseInt(process.env.GIT_DRIVE_PORT || String(DEFAULT_PORT), 10);
79
+ }
80
+ async function isServerRunning(port) {
81
+ const serverPort = port || getServerPort();
82
+ try {
83
+ const response = await fetch(`http://localhost:${serverPort}/api/drives`, {
84
+ method: 'HEAD',
85
+ signal: AbortSignal.timeout(1000),
86
+ });
87
+ return response.ok;
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ }
93
+ async function ensureServerRunning() {
94
+ const port = getServerPort();
95
+ const running = await isServerRunning(port);
96
+ if (!running) {
97
+ console.log('\n 🚀 Starting Git Drive server...\n');
98
+ // Start server in detached/background mode
99
+ const serverPath = require.resolve('./server.js');
100
+ const child = (0, child_process_1.spawn)(process.execPath, [serverPath], {
101
+ detached: true,
102
+ stdio: 'ignore',
103
+ env: process.env,
104
+ });
105
+ // Allow the parent process to exit independently
106
+ child.unref();
107
+ // Wait a moment for server to start
108
+ let retries = 10;
109
+ while (retries > 0) {
110
+ await new Promise(resolve => setTimeout(resolve, 300));
111
+ if (await isServerRunning(port)) {
112
+ break;
113
+ }
114
+ retries--;
115
+ }
116
+ if (retries === 0) {
117
+ throw new Error('Failed to start Git Drive server. Please run "git-drive server" manually.');
118
+ }
119
+ }
120
+ }
73
121
  // ── API Routes ───────────────────────────────────────────────────────
122
+ // Health check endpoint
123
+ app.get('/api/health', (_req, res) => {
124
+ res.json({ status: 'ok', timestamp: new Date().toISOString() });
125
+ });
74
126
  // List all connected drives
75
127
  app.get('/api/drives', async (_req, res) => {
76
128
  try {
@@ -194,10 +246,10 @@ app.delete('/api/drives/:mountpoint/repos/:repoName', (req, res) => {
194
246
  res.status(404).json({ error: 'Repository not found' });
195
247
  return;
196
248
  }
197
- (0, child_process_1.execSync)(`rm -rf "${altPath}"`);
249
+ (0, child_process_2.execSync)(`rm -rf "${altPath}"`);
198
250
  }
199
251
  else {
200
- (0, child_process_1.execSync)(`rm -rf "${repoPath}"`);
252
+ (0, child_process_2.execSync)(`rm -rf "${repoPath}"`);
201
253
  }
202
254
  res.json({ message: `Repository '${repoName}' deleted` });
203
255
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-drive",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Turn any external drive into a git remote backup for your code - CLI, server, and web UI",
5
5
  "keywords": [
6
6
  "git",
@@ -24,8 +24,7 @@
24
24
  "homepage": "https://github.com/josmanvis/git-drive#readme",
25
25
  "type": "commonjs",
26
26
  "bin": {
27
- "git-drive": "./dist/index.js",
28
- "git-drive-server": "./dist/server.js"
27
+ "git-drive": "dist/index.js"
29
28
  },
30
29
  "main": "./dist/index.js",
31
30
  "files": [
@@ -54,4 +53,4 @@
54
53
  "engines": {
55
54
  "node": ">=18"
56
55
  }
57
- }
56
+ }