@cj-ways/orgclone 0.2.0 → 0.3.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.
Files changed (2) hide show
  1. package/install.js +33 -38
  2. package/package.json +2 -2
package/install.js CHANGED
@@ -1,47 +1,39 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Postinstall script: downloads the correct orgclone binary from GitHub Releases.
3
+ * Postinstall script: downloads the orgclone binary from GitHub Releases.
4
+ * Caches by version in ~/.orgclone/ so reinstalls are instant.
4
5
  */
5
6
 
6
7
  const https = require("https");
7
8
  const fs = require("fs");
8
9
  const path = require("path");
9
- const { execSync } = require("child_process");
10
- const zlib = require("zlib");
10
+ const os = require("os");
11
11
 
12
12
  const REPO = "cj-ways/orgclone";
13
13
  const VERSION = require("./package.json").binaryVersion;
14
- const BIN_DIR = path.join(__dirname, "bin");
15
- const BIN_PATH = path.join(BIN_DIR, process.platform === "win32" ? "orgclone.exe" : "orgclone");
14
+ const IS_WIN = process.platform === "win32";
15
+ const BIN_NAME = IS_WIN ? "orgclone.exe" : "orgclone";
16
16
 
17
- function getPlatformTarget() {
18
- const platform = process.platform;
19
- const arch = process.arch;
20
-
21
- const platformMap = { win32: "windows", darwin: "darwin", linux: "linux" };
22
- const archMap = { x64: "amd64", arm64: "arm64" };
17
+ // Package bin dir (where npm looks for the executable)
18
+ const PKG_BIN = path.join(__dirname, "bin", BIN_NAME);
23
19
 
24
- const p = platformMap[platform];
25
- const a = archMap[arch];
20
+ // Persistent cache dir — survives npm reinstalls
21
+ const CACHE_DIR = path.join(os.homedir(), ".orgclone", "bin");
22
+ const CACHED_BIN = path.join(CACHE_DIR, `orgclone-${VERSION}${IS_WIN ? ".exe" : ""}`);
26
23
 
27
- if (!p || !a) throw new Error(`Unsupported platform: ${platform}/${arch}`);
28
-
29
- const ext = platform === "win32" ? ".exe" : "";
30
- return `orgclone_${p}_${a}${ext}`;
24
+ function getPlatformTarget() {
25
+ const p = { win32: "windows", darwin: "darwin", linux: "linux" }[process.platform];
26
+ const a = { x64: "amd64", arm64: "arm64" }[process.arch];
27
+ if (!p || !a) throw new Error(`Unsupported platform: ${process.platform}/${process.arch}`);
28
+ return `orgclone_${p}_${a}${IS_WIN ? ".exe" : ""}`;
31
29
  }
32
30
 
33
31
  function download(url, dest) {
34
32
  return new Promise((resolve, reject) => {
35
33
  const follow = (u) => {
36
34
  https.get(u, { headers: { "User-Agent": "orgclone-installer" } }, (res) => {
37
- if (res.statusCode === 301 || res.statusCode === 302) {
38
- follow(res.headers.location);
39
- return;
40
- }
41
- if (res.statusCode !== 200) {
42
- reject(new Error(`HTTP ${res.statusCode} for ${u}`));
43
- return;
44
- }
35
+ if (res.statusCode === 301 || res.statusCode === 302) return follow(res.headers.location);
36
+ if (res.statusCode !== 200) return reject(new Error(`HTTP ${res.statusCode}`));
45
37
  const file = fs.createWriteStream(dest);
46
38
  res.pipe(file);
47
39
  file.on("finish", () => file.close(resolve));
@@ -53,27 +45,30 @@ function download(url, dest) {
53
45
  }
54
46
 
55
47
  async function main() {
56
- if (fs.existsSync(BIN_PATH)) {
57
- console.log("orgclone binary already installed.");
48
+ fs.mkdirSync(CACHE_DIR, { recursive: true });
49
+ fs.mkdirSync(path.join(__dirname, "bin"), { recursive: true });
50
+
51
+ // If this version is already cached, just copy it — no download needed
52
+ if (fs.existsSync(CACHED_BIN)) {
53
+ fs.copyFileSync(CACHED_BIN, PKG_BIN);
54
+ if (!IS_WIN) fs.chmodSync(PKG_BIN, 0o755);
55
+ console.log(`orgclone ${VERSION} ready.`);
58
56
  return;
59
57
  }
60
58
 
61
- fs.mkdirSync(BIN_DIR, { recursive: true });
62
-
63
- const target = getPlatformTarget();
64
- const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${target}`;
65
-
66
- console.log(`Downloading orgclone ${VERSION} for ${process.platform}/${process.arch}...`);
59
+ // Download and cache
60
+ const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${getPlatformTarget()}`;
61
+ console.log(`Downloading orgclone ${VERSION}...`);
67
62
 
68
63
  try {
69
- await download(url, BIN_PATH);
70
- if (process.platform !== "win32") {
71
- fs.chmodSync(BIN_PATH, 0o755);
72
- }
64
+ await download(url, CACHED_BIN);
65
+ if (!IS_WIN) fs.chmodSync(CACHED_BIN, 0o755);
66
+ fs.copyFileSync(CACHED_BIN, PKG_BIN);
67
+ if (!IS_WIN) fs.chmodSync(PKG_BIN, 0o755);
73
68
  console.log("orgclone installed successfully.");
74
69
  } catch (err) {
75
70
  console.error(`Failed to download binary: ${err.message}`);
76
- console.error(`You can manually download from: https://github.com/${REPO}/releases`);
71
+ console.error(`Download manually from: https://github.com/${REPO}/releases`);
77
72
  process.exit(1);
78
73
  }
79
74
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cj-ways/orgclone",
3
- "version": "0.2.0",
4
- "binaryVersion": "0.2.0",
3
+ "version": "0.3.0",
4
+ "binaryVersion": "0.3.0",
5
5
  "description": "Clone entire GitHub organizations or GitLab groups with one command. Supports public and private repos, SSH, token auth, and config files.",
6
6
  "license": "MIT",
7
7
  "author": "cj-ways",