git-drive 0.1.6 → 0.1.7
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/.github/workflows/ci.yml +77 -0
- package/.planning/codebase/ARCHITECTURE.md +151 -0
- package/.planning/codebase/CONCERNS.md +191 -0
- package/.planning/codebase/CONVENTIONS.md +169 -0
- package/.planning/codebase/INTEGRATIONS.md +94 -0
- package/.planning/codebase/STACK.md +77 -0
- package/.planning/codebase/STRUCTURE.md +157 -0
- package/.planning/codebase/TESTING.md +156 -0
- package/Dockerfile.cli +30 -0
- package/Dockerfile.server +32 -0
- package/README.md +157 -0
- package/docker-compose.yml +48 -0
- package/package.json +20 -55
- package/packages/cli/Dockerfile +26 -0
- package/packages/cli/jest.config.js +26 -0
- package/packages/cli/package.json +65 -0
- package/packages/cli/src/__tests__/commands/companion.test.ts +152 -0
- package/packages/cli/src/__tests__/commands/init.test.ts +154 -0
- package/packages/cli/src/__tests__/commands/list.test.ts +122 -0
- package/packages/cli/src/__tests__/commands/push.test.ts +155 -0
- package/packages/cli/src/__tests__/commands/restore.test.ts +135 -0
- package/packages/cli/src/__tests__/commands/status.test.ts +199 -0
- package/packages/cli/src/__tests__/config.test.ts +198 -0
- package/packages/cli/src/__tests__/e2e.test.ts +125 -0
- package/packages/cli/src/__tests__/errors.test.ts +66 -0
- package/packages/cli/src/__tests__/git.test.ts +250 -0
- package/packages/cli/src/__tests__/server.test.ts +371 -0
- package/packages/cli/src/commands/archive.ts +39 -0
- package/packages/cli/src/commands/companion.ts +205 -0
- package/packages/cli/src/commands/init.ts +130 -0
- package/packages/cli/src/commands/link.ts +151 -0
- package/packages/cli/src/commands/list.ts +94 -0
- package/packages/cli/src/commands/push.ts +77 -0
- package/packages/cli/src/commands/restore.ts +36 -0
- package/packages/cli/src/commands/status.ts +127 -0
- package/packages/cli/src/config.ts +73 -0
- package/packages/cli/src/errors.ts +23 -0
- package/packages/cli/src/git.ts +60 -0
- package/packages/cli/src/index.ts +129 -0
- package/packages/cli/src/server.ts +700 -0
- package/packages/cli/tsconfig.json +13 -0
- package/packages/git-drive-docker/package.json +15 -0
- package/packages/server/package.json +44 -0
- package/packages/server/src/index.ts +569 -0
- package/packages/server/tsconfig.json +9 -0
- package/packages/ui/README.md +73 -0
- package/packages/ui/eslint.config.js +23 -0
- package/packages/ui/index.html +13 -0
- package/packages/ui/package.json +52 -0
- package/packages/ui/postcss.config.js +6 -0
- package/packages/ui/public/vite.svg +1 -0
- package/packages/ui/src/App.css +23 -0
- package/packages/ui/src/App.test.tsx +248 -0
- package/packages/ui/src/App.tsx +803 -0
- package/packages/ui/src/assets/react.svg +8 -0
- package/packages/ui/src/assets/vite.svg +3 -0
- package/packages/ui/src/index.css +37 -0
- package/packages/ui/src/main.tsx +14 -0
- package/packages/ui/src/test/setup.ts +1 -0
- package/packages/ui/tailwind.config.js +11 -0
- package/packages/ui/tsconfig.app.json +28 -0
- package/packages/ui/tsconfig.json +26 -0
- package/packages/ui/tsconfig.node.json +12 -0
- package/packages/ui/vite.config.ts +7 -0
- package/packages/ui/vitest.config.ts +20 -0
- package/pnpm-workspace.yaml +4 -0
- package/rewrite_app.js +731 -0
- package/tsconfig.json +14 -0
- package/dist/__tests__/commands/init.test.js +0 -123
- package/dist/__tests__/commands/list.test.js +0 -91
- package/dist/__tests__/commands/push.test.js +0 -128
- package/dist/__tests__/commands/restore.test.js +0 -99
- package/dist/__tests__/commands/status.test.js +0 -151
- package/dist/__tests__/config.test.js +0 -150
- package/dist/__tests__/e2e.test.js +0 -107
- package/dist/__tests__/errors.test.js +0 -56
- package/dist/__tests__/git.test.js +0 -184
- package/dist/__tests__/server.test.js +0 -310
- package/dist/commands/archive.js +0 -32
- package/dist/commands/init.js +0 -55
- package/dist/commands/link.js +0 -175
- package/dist/commands/list.js +0 -83
- package/dist/commands/push.js +0 -112
- package/dist/commands/restore.js +0 -30
- package/dist/commands/status.js +0 -116
- package/dist/config.js +0 -62
- package/dist/errors.js +0 -30
- package/dist/git.js +0 -67
- package/dist/index.js +0 -108
- package/dist/server.js +0 -535
- /package/{ui → packages/cli/ui}/assets/index-Br8xQbJz.js +0 -0
- /package/{ui → packages/cli/ui}/assets/index-Cc2q1t5k.js +0 -0
- /package/{ui → packages/cli/ui}/assets/index-DrL7ojPA.css +0 -0
- /package/{ui → packages/cli/ui}/index.html +0 -0
- /package/{ui → packages/cli/ui}/vite.svg +0 -0
package/dist/commands/push.js
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
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.push = push;
|
|
40
|
-
const git_js_1 = require("../git.js");
|
|
41
|
-
const errors_js_1 = require("../errors.js");
|
|
42
|
-
const prompts_1 = __importDefault(require("prompts"));
|
|
43
|
-
const fs = __importStar(require("fs"));
|
|
44
|
-
const path = __importStar(require("path"));
|
|
45
|
-
const os = __importStar(require("os"));
|
|
46
|
-
async function push(args) {
|
|
47
|
-
if (!(0, git_js_1.isGitRepo)()) {
|
|
48
|
-
throw new errors_js_1.GitDriveError("Not in a git repository.");
|
|
49
|
-
}
|
|
50
|
-
const existingUrl = (0, git_js_1.getRemoteUrl)("gd");
|
|
51
|
-
if (!existingUrl) {
|
|
52
|
-
throw new errors_js_1.GitDriveError("No git-drive linked for this project. Please run 'git-drive link' first.");
|
|
53
|
-
}
|
|
54
|
-
try {
|
|
55
|
-
const currentBranch = (0, git_js_1.git)("branch --show-current") || "HEAD";
|
|
56
|
-
// Check for --all or --current flags for non-interactive mode
|
|
57
|
-
const pushAll = args.includes("--all");
|
|
58
|
-
const pushCurrent = args.includes("--current");
|
|
59
|
-
let pushMode = null;
|
|
60
|
-
if (pushAll) {
|
|
61
|
-
pushMode = "all";
|
|
62
|
-
}
|
|
63
|
-
else if (pushCurrent) {
|
|
64
|
-
pushMode = "current";
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
const result = await (0, prompts_1.default)({
|
|
68
|
-
type: "select",
|
|
69
|
-
name: "pushMode",
|
|
70
|
-
message: `Pushing to ${existingUrl}\nSelect what to branch to push:`,
|
|
71
|
-
choices: [
|
|
72
|
-
{ title: `Current branch only (${currentBranch})`, value: "current" },
|
|
73
|
-
{ title: "All branches & tags", value: "all" }
|
|
74
|
-
]
|
|
75
|
-
});
|
|
76
|
-
pushMode = result.pushMode;
|
|
77
|
-
}
|
|
78
|
-
if (!pushMode)
|
|
79
|
-
return;
|
|
80
|
-
if (pushMode === "current") {
|
|
81
|
-
console.log(`\nPushing ${currentBranch}...`);
|
|
82
|
-
(0, git_js_1.git)(`push gd ${currentBranch}`);
|
|
83
|
-
console.log(`✅ Successfully pushed ${currentBranch} to git-drive.`);
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
console.log("\nPushing all branches and tags...");
|
|
87
|
-
(0, git_js_1.git)("push gd --all");
|
|
88
|
-
(0, git_js_1.git)("push gd --tags");
|
|
89
|
-
console.log(`✅ Successfully pushed all branches and tags to git-drive.`);
|
|
90
|
-
}
|
|
91
|
-
// Write context to a central pushlog safely inside the git-drive repo folder
|
|
92
|
-
try {
|
|
93
|
-
if (fs.existsSync(existingUrl)) {
|
|
94
|
-
const payload = {
|
|
95
|
-
date: new Date().toISOString(),
|
|
96
|
-
computer: os.hostname(),
|
|
97
|
-
user: os.userInfo().username,
|
|
98
|
-
localDir: process.cwd(),
|
|
99
|
-
mode: pushMode,
|
|
100
|
-
};
|
|
101
|
-
const logFile = path.join(existingUrl, "git-drive-pushlog.json");
|
|
102
|
-
fs.appendFileSync(logFile, JSON.stringify(payload) + "\n", "utf-8");
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
catch {
|
|
106
|
-
// Intentionally swallow telemetry tracking errors
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
catch (err) {
|
|
110
|
-
throw new errors_js_1.GitDriveError(`Failed to push to drive. Make sure the drive is connected.\n${err.message}`);
|
|
111
|
-
}
|
|
112
|
-
}
|
package/dist/commands/restore.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.restore = restore;
|
|
4
|
-
const fs_1 = require("fs");
|
|
5
|
-
const path_1 = require("path");
|
|
6
|
-
const config_js_1 = require("../config.js");
|
|
7
|
-
const git_js_1 = require("../git.js");
|
|
8
|
-
const errors_js_1 = require("../errors.js");
|
|
9
|
-
function restore(args) {
|
|
10
|
-
const projectName = args[0];
|
|
11
|
-
const targetDir = args[1] || projectName;
|
|
12
|
-
if (!projectName) {
|
|
13
|
-
throw new errors_js_1.GitDriveError("Usage: git drive restore <project-name> [target-dir]");
|
|
14
|
-
}
|
|
15
|
-
const config = (0, config_js_1.requireConfig)();
|
|
16
|
-
(0, config_js_1.assertDriveMounted)(config.drivePath);
|
|
17
|
-
const storePath = (0, config_js_1.getDriveStorePath)(config.drivePath);
|
|
18
|
-
const bareRepoPath = (0, path_1.join)(storePath, `${projectName}.git`);
|
|
19
|
-
if (!(0, fs_1.existsSync)(bareRepoPath)) {
|
|
20
|
-
throw new errors_js_1.GitDriveError(`Project '${projectName}' not found on drive.`);
|
|
21
|
-
}
|
|
22
|
-
const targetPath = (0, path_1.resolve)(targetDir);
|
|
23
|
-
if ((0, fs_1.existsSync)(targetPath)) {
|
|
24
|
-
throw new errors_js_1.GitDriveError(`Directory already exists: ${targetPath}`);
|
|
25
|
-
}
|
|
26
|
-
(0, git_js_1.git)(`clone ${bareRepoPath} ${targetPath}`);
|
|
27
|
-
// Rename origin to drive so the remote stays consistent
|
|
28
|
-
(0, git_js_1.git)("remote rename origin drive", targetPath);
|
|
29
|
-
console.log(`Restored ${projectName} into ${targetPath}`);
|
|
30
|
-
}
|
package/dist/commands/status.js
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.status = status;
|
|
4
|
-
const fs_1 = require("fs");
|
|
5
|
-
const path_1 = require("path");
|
|
6
|
-
const os_1 = require("os");
|
|
7
|
-
const node_disk_info_1 = require("node-disk-info");
|
|
8
|
-
const git_js_1 = require("../git.js");
|
|
9
|
-
function loadLinks() {
|
|
10
|
-
const linksFile = (0, path_1.join)((0, os_1.homedir)(), ".config", "git-drive", "links.json");
|
|
11
|
-
if (!(0, fs_1.existsSync)(linksFile))
|
|
12
|
-
return {};
|
|
13
|
-
try {
|
|
14
|
-
return JSON.parse((0, fs_1.readFileSync)(linksFile, "utf-8"));
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
return {};
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
function getGitDrivePath(mountpoint) {
|
|
21
|
-
return (0, path_1.join)(mountpoint, ".git-drive");
|
|
22
|
-
}
|
|
23
|
-
async function status(_args) {
|
|
24
|
-
console.log("Git Drive Status\n");
|
|
25
|
-
// Get all connected drives
|
|
26
|
-
let drives = [];
|
|
27
|
-
try {
|
|
28
|
-
drives = await (0, node_disk_info_1.getDiskInfo)();
|
|
29
|
-
}
|
|
30
|
-
catch (err) {
|
|
31
|
-
console.error("Error detecting drives:", err);
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
// Filter to external/removable drives
|
|
35
|
-
const externalDrives = drives.filter((d) => {
|
|
36
|
-
const mp = d.mounted;
|
|
37
|
-
if (!mp)
|
|
38
|
-
return false;
|
|
39
|
-
if (mp === "/" || mp === "100%")
|
|
40
|
-
return false;
|
|
41
|
-
if (process.platform === "darwin") {
|
|
42
|
-
return mp.startsWith("/Volumes/") && !mp.startsWith("/Volumes/Recovery");
|
|
43
|
-
}
|
|
44
|
-
if (mp.startsWith("/sys") || mp.startsWith("/proc") || mp.startsWith("/run") || mp.startsWith("/snap") || mp.startsWith("/boot"))
|
|
45
|
-
return false;
|
|
46
|
-
if (d.filesystem === "tmpfs" || d.filesystem === "devtmpfs" || d.filesystem === "udev" || d.filesystem === "overlay")
|
|
47
|
-
return false;
|
|
48
|
-
return true;
|
|
49
|
-
});
|
|
50
|
-
// Load links
|
|
51
|
-
const links = loadLinks();
|
|
52
|
-
const linkEntries = Object.entries(links);
|
|
53
|
-
// Show connected drives with git-drive
|
|
54
|
-
console.log("=== Connected Drives ===\n");
|
|
55
|
-
if (externalDrives.length === 0) {
|
|
56
|
-
console.log("No external drives connected.\n");
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
for (const drive of externalDrives) {
|
|
60
|
-
const mp = drive.mounted;
|
|
61
|
-
const gitDrivePath = getGitDrivePath(mp);
|
|
62
|
-
const hasGitDrive = (0, fs_1.existsSync)(gitDrivePath);
|
|
63
|
-
if (hasGitDrive) {
|
|
64
|
-
const entries = (0, fs_1.readdirSync)(gitDrivePath).filter(n => n.endsWith(".git") || (0, fs_1.existsSync)((0, path_1.join)(gitDrivePath, n, "HEAD")));
|
|
65
|
-
console.log(`✓ ${mp}`);
|
|
66
|
-
console.log(` ${entries.length} repo${entries.length === 1 ? "" : "s"} backed up`);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
console.log(`○ ${mp} (not initialized)`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
console.log();
|
|
73
|
-
}
|
|
74
|
-
// Show registered drives (from links)
|
|
75
|
-
console.log("=== Registered Repositories ===\n");
|
|
76
|
-
if (linkEntries.length === 0) {
|
|
77
|
-
console.log("No repositories linked to drives yet.");
|
|
78
|
-
console.log("Run 'git-drive link' to link a repository.\n");
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
for (const [localPath, link] of linkEntries) {
|
|
82
|
-
const stillConnected = (0, fs_1.existsSync)(link.mountpoint);
|
|
83
|
-
const localExists = (0, fs_1.existsSync)(localPath);
|
|
84
|
-
console.log(`${localPath}`);
|
|
85
|
-
console.log(` → ${link.mountpoint} (${link.repoName})`);
|
|
86
|
-
console.log(` Drive: ${stillConnected ? "connected" : "NOT CONNECTED"}`);
|
|
87
|
-
console.log(` Local: ${localExists ? "exists" : "NOT FOUND"}`);
|
|
88
|
-
console.log();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
// Show current repo status if in a git repo
|
|
92
|
-
if ((0, git_js_1.isGitRepo)()) {
|
|
93
|
-
console.log("=== Current Repository ===\n");
|
|
94
|
-
const name = (0, git_js_1.getProjectName)();
|
|
95
|
-
const remoteUrl = (0, git_js_1.getRemoteUrl)("gd");
|
|
96
|
-
console.log(`Repository: ${name}`);
|
|
97
|
-
if (remoteUrl) {
|
|
98
|
-
console.log(`Remote 'gd': ${remoteUrl}`);
|
|
99
|
-
// Check if this repo is linked
|
|
100
|
-
const cwd = process.cwd();
|
|
101
|
-
const link = links[cwd];
|
|
102
|
-
if (link) {
|
|
103
|
-
console.log(`Linked to: ${link.mountpoint}`);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
console.log(`No 'gd' remote configured.`);
|
|
108
|
-
console.log("Run 'git-drive link' to set up backup.");
|
|
109
|
-
}
|
|
110
|
-
console.log();
|
|
111
|
-
}
|
|
112
|
-
// Server status hint
|
|
113
|
-
console.log("=== Server ===\n");
|
|
114
|
-
console.log("Web UI: http://localhost:4483");
|
|
115
|
-
console.log("Run 'git-drive server' to start the web interface.\n");
|
|
116
|
-
}
|
package/dist/config.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loadConfig = loadConfig;
|
|
4
|
-
exports.saveConfig = saveConfig;
|
|
5
|
-
exports.requireConfig = requireConfig;
|
|
6
|
-
exports.assertDriveMounted = assertDriveMounted;
|
|
7
|
-
exports.getDriveStorePath = getDriveStorePath;
|
|
8
|
-
exports.loadLinks = loadLinks;
|
|
9
|
-
exports.saveLink = saveLink;
|
|
10
|
-
const os_1 = require("os");
|
|
11
|
-
const path_1 = require("path");
|
|
12
|
-
const fs_1 = require("fs");
|
|
13
|
-
const errors_js_1 = require("./errors.js");
|
|
14
|
-
const CONFIG_DIR = (0, path_1.join)((0, os_1.homedir)(), ".config", "git-drive");
|
|
15
|
-
const CONFIG_FILE = (0, path_1.join)(CONFIG_DIR, "config.json");
|
|
16
|
-
function loadConfig() {
|
|
17
|
-
if (!(0, fs_1.existsSync)(CONFIG_FILE))
|
|
18
|
-
return null;
|
|
19
|
-
const raw = (0, fs_1.readFileSync)(CONFIG_FILE, "utf-8");
|
|
20
|
-
return JSON.parse(raw);
|
|
21
|
-
}
|
|
22
|
-
function saveConfig(config) {
|
|
23
|
-
(0, fs_1.mkdirSync)(CONFIG_DIR, { recursive: true });
|
|
24
|
-
(0, fs_1.writeFileSync)(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n");
|
|
25
|
-
}
|
|
26
|
-
function requireConfig() {
|
|
27
|
-
const config = loadConfig();
|
|
28
|
-
if (!config) {
|
|
29
|
-
throw new errors_js_1.GitDriveError("No drive configured. Run: git drive init <path>");
|
|
30
|
-
}
|
|
31
|
-
return config;
|
|
32
|
-
}
|
|
33
|
-
function assertDriveMounted(drivePath) {
|
|
34
|
-
if (!(0, fs_1.existsSync)(drivePath)) {
|
|
35
|
-
throw new errors_js_1.GitDriveError(`Drive not found at ${drivePath}. Is it connected?`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
function getDriveStorePath(drivePath) {
|
|
39
|
-
return (0, path_1.join)(drivePath, ".git-drive");
|
|
40
|
-
}
|
|
41
|
-
const LINKS_FILE = (0, path_1.join)(CONFIG_DIR, "links.json");
|
|
42
|
-
function loadLinks() {
|
|
43
|
-
if (!(0, fs_1.existsSync)(LINKS_FILE))
|
|
44
|
-
return {};
|
|
45
|
-
try {
|
|
46
|
-
const raw = (0, fs_1.readFileSync)(LINKS_FILE, "utf-8");
|
|
47
|
-
return JSON.parse(raw);
|
|
48
|
-
}
|
|
49
|
-
catch {
|
|
50
|
-
return {};
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
function saveLink(localPath, mountpoint, repoName) {
|
|
54
|
-
(0, fs_1.mkdirSync)(CONFIG_DIR, { recursive: true });
|
|
55
|
-
const links = loadLinks();
|
|
56
|
-
links[localPath] = {
|
|
57
|
-
mountpoint,
|
|
58
|
-
repoName,
|
|
59
|
-
linkedAt: new Date().toISOString(),
|
|
60
|
-
};
|
|
61
|
-
(0, fs_1.writeFileSync)(LINKS_FILE, JSON.stringify(links, null, 2) + "\n");
|
|
62
|
-
}
|
package/dist/errors.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GitDriveError = void 0;
|
|
4
|
-
exports.handleError = handleError;
|
|
5
|
-
class GitDriveError extends Error {
|
|
6
|
-
constructor(message) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.name = "GitDriveError";
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
exports.GitDriveError = GitDriveError;
|
|
12
|
-
function handleError(err) {
|
|
13
|
-
if (err instanceof GitDriveError) {
|
|
14
|
-
console.error(`error: ${err.message}`);
|
|
15
|
-
}
|
|
16
|
-
else if (err instanceof Error) {
|
|
17
|
-
const msg = err.message;
|
|
18
|
-
// execSync errors include stderr in the message
|
|
19
|
-
const stderrMatch = msg.match(/stderr:\s*([\s\S]*)/);
|
|
20
|
-
if (stderrMatch) {
|
|
21
|
-
console.error(`error: ${stderrMatch[1].trim()}`);
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
console.error(`error: ${msg}`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
console.error("An unexpected error occurred.");
|
|
29
|
-
}
|
|
30
|
-
}
|
package/dist/git.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.git = git;
|
|
4
|
-
exports.listDrives = listDrives;
|
|
5
|
-
exports.getRepoRoot = getRepoRoot;
|
|
6
|
-
exports.getProjectName = getProjectName;
|
|
7
|
-
exports.getRemoteUrl = getRemoteUrl;
|
|
8
|
-
exports.isGitRepo = isGitRepo;
|
|
9
|
-
const child_process_1 = require("child_process");
|
|
10
|
-
const path_1 = require("path");
|
|
11
|
-
const node_disk_info_1 = require("node-disk-info");
|
|
12
|
-
function git(args, cwd) {
|
|
13
|
-
return (0, child_process_1.execSync)(`git ${args}`, {
|
|
14
|
-
cwd,
|
|
15
|
-
encoding: "utf-8",
|
|
16
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
17
|
-
}).trim();
|
|
18
|
-
}
|
|
19
|
-
async function listDrives() {
|
|
20
|
-
const drives = await (0, node_disk_info_1.getDiskInfo)();
|
|
21
|
-
return drives.filter((d) => {
|
|
22
|
-
const mp = d.mounted;
|
|
23
|
-
if (!mp)
|
|
24
|
-
return false;
|
|
25
|
-
if (mp === "/" || mp === "100%")
|
|
26
|
-
return false;
|
|
27
|
-
// Exclude temporary and system paths on all platforms
|
|
28
|
-
if (mp.startsWith("/var/") || mp.startsWith("/private/var/") || mp.startsWith("/tmp") || mp.startsWith("/private/tmp"))
|
|
29
|
-
return false;
|
|
30
|
-
if (mp.includes("TemporaryItems") || mp.includes("NSIRD_"))
|
|
31
|
-
return false;
|
|
32
|
-
if (mp.startsWith("/System/") || mp.startsWith("/Library/"))
|
|
33
|
-
return false;
|
|
34
|
-
if (process.platform === "darwin") {
|
|
35
|
-
return mp.startsWith("/Volumes/") && !mp.startsWith("/Volumes/Recovery");
|
|
36
|
-
}
|
|
37
|
-
if (mp.startsWith("/sys") || mp.startsWith("/proc") || mp.startsWith("/run") || mp.startsWith("/snap") || mp.startsWith("/boot"))
|
|
38
|
-
return false;
|
|
39
|
-
if (d.filesystem === "tmpfs" || d.filesystem === "devtmpfs" || d.filesystem === "udev" || d.filesystem === "overlay")
|
|
40
|
-
return false;
|
|
41
|
-
return true;
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
function getRepoRoot() {
|
|
45
|
-
return git("rev-parse --show-toplevel");
|
|
46
|
-
}
|
|
47
|
-
function getProjectName() {
|
|
48
|
-
const root = getRepoRoot();
|
|
49
|
-
return (0, path_1.basename)(root);
|
|
50
|
-
}
|
|
51
|
-
function getRemoteUrl(remoteName) {
|
|
52
|
-
try {
|
|
53
|
-
return git(`remote get-url ${remoteName}`);
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
function isGitRepo() {
|
|
60
|
-
try {
|
|
61
|
-
git("rev-parse --is-inside-work-tree");
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
}
|
package/dist/index.js
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
const child_process_1 = require("child_process");
|
|
5
|
-
const fs_1 = require("fs");
|
|
6
|
-
const push_js_1 = require("./commands/push.js");
|
|
7
|
-
const list_js_1 = require("./commands/list.js");
|
|
8
|
-
const status_js_1 = require("./commands/status.js");
|
|
9
|
-
const link_js_1 = require("./commands/link.js");
|
|
10
|
-
const init_js_1 = require("./commands/init.js");
|
|
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'));
|
|
14
|
-
const commands = {
|
|
15
|
-
init: init_js_1.init,
|
|
16
|
-
push: push_js_1.push,
|
|
17
|
-
list: list_js_1.list,
|
|
18
|
-
status: status_js_1.status,
|
|
19
|
-
link: link_js_1.link,
|
|
20
|
-
server: startServer,
|
|
21
|
-
start: startServer,
|
|
22
|
-
ui: startServer,
|
|
23
|
-
};
|
|
24
|
-
// Commands that don't need the server running
|
|
25
|
-
const NO_SERVER_COMMANDS = ['server', 'start', 'ui'];
|
|
26
|
-
function printUsage() {
|
|
27
|
-
console.log(`
|
|
28
|
-
git-drive - Turn any external drive into a git remote backup for your code
|
|
29
|
-
|
|
30
|
-
Usage:
|
|
31
|
-
git-drive <command> [options]
|
|
32
|
-
|
|
33
|
-
Commands:
|
|
34
|
-
init Initialize git-drive on an external drive
|
|
35
|
-
link Link current repo to a drive
|
|
36
|
-
push Push current repo to drive
|
|
37
|
-
list Show connected drives and their status
|
|
38
|
-
status Show detailed status of drives and repos
|
|
39
|
-
server, start, ui Start the git-drive web UI server
|
|
40
|
-
|
|
41
|
-
Options:
|
|
42
|
-
-v, -V, --version Show version number
|
|
43
|
-
-h, --help Show this help message
|
|
44
|
-
|
|
45
|
-
Examples:
|
|
46
|
-
git-drive init /Volumes/MyDrive Initialize git-drive on a drive
|
|
47
|
-
git-drive link Link current repo to a drive
|
|
48
|
-
git-drive push Push current repo to drive
|
|
49
|
-
git-drive list List connected drives
|
|
50
|
-
git-drive status Show detailed status
|
|
51
|
-
git-drive server Start the web UI at http://localhost:4483
|
|
52
|
-
|
|
53
|
-
Environment Variables:
|
|
54
|
-
GIT_DRIVE_PORT Port for the web server (default: 4483)
|
|
55
|
-
|
|
56
|
-
Docker:
|
|
57
|
-
docker run -it --rm -v /Volumes:/Volumes -p 4483:4483 git-drive
|
|
58
|
-
|
|
59
|
-
Documentation:
|
|
60
|
-
https://github.com/josmanvis/git-drive
|
|
61
|
-
`);
|
|
62
|
-
}
|
|
63
|
-
function startServer(_args) {
|
|
64
|
-
console.log('\n 🚀 Starting Git Drive server...\n');
|
|
65
|
-
console.log(' Web UI: http://localhost:4483\n');
|
|
66
|
-
console.log(' Press Ctrl+C to stop\n');
|
|
67
|
-
const serverPath = require.resolve('./server.js');
|
|
68
|
-
const child = (0, child_process_1.spawn)(process.execPath, [serverPath], {
|
|
69
|
-
stdio: 'inherit',
|
|
70
|
-
env: process.env
|
|
71
|
-
});
|
|
72
|
-
child.on('error', (err) => {
|
|
73
|
-
console.error('Failed to start server:', err.message);
|
|
74
|
-
process.exit(1);
|
|
75
|
-
});
|
|
76
|
-
child.on('exit', (code) => {
|
|
77
|
-
process.exit(code || 0);
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
const [command, ...args] = process.argv.slice(2);
|
|
81
|
-
(async () => {
|
|
82
|
-
try {
|
|
83
|
-
if (!command || command === "--help" || command === "-h") {
|
|
84
|
-
printUsage();
|
|
85
|
-
process.exit(0);
|
|
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
|
-
}
|
|
92
|
-
const handler = commands[command];
|
|
93
|
-
if (!handler) {
|
|
94
|
-
console.error(`Unknown command: ${command}\n`);
|
|
95
|
-
printUsage();
|
|
96
|
-
process.exit(1);
|
|
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
|
-
}
|
|
102
|
-
await handler(args);
|
|
103
|
-
}
|
|
104
|
-
catch (err) {
|
|
105
|
-
(0, errors_js_1.handleError)(err);
|
|
106
|
-
process.exit(1);
|
|
107
|
-
}
|
|
108
|
-
})();
|