@logionsh/cli 0.1.0 → 0.1.2
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 +1 -1
- package/dist/bin/logion.js +5 -34
- package/dist/scripts/postinstall.js +12 -51
- package/dist/scripts/uninstall.js +5 -18
- package/package.json +4 -5
- package/dist/bin/lgn.js +0 -74
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ On install, the postinstall hook:
|
|
|
22
22
|
|
|
23
23
|
1. Finds a working Python 3.12+.
|
|
24
24
|
2. Installs `logion-cli==<pinned-version>` from PyPI via `pipx`/`uv`/venv.
|
|
25
|
-
3. Shims the `logion`
|
|
25
|
+
3. Shims the `logion` binary onto your PATH.
|
|
26
26
|
|
|
27
27
|
The pinned PyPI version is baked into the npm tarball at publish
|
|
28
28
|
time, so `npm install -g @logionsh/cli@0.3.0` always installs the
|
package/dist/bin/logion.js
CHANGED
|
@@ -25,43 +25,14 @@ var __toESM = (mod, isNodeMode, target2) => (target2 = mod != null ? __create(__
|
|
|
25
25
|
|
|
26
26
|
// src/bin/logion.ts
|
|
27
27
|
var import_node_child_process = require("child_process");
|
|
28
|
-
|
|
29
|
-
// src/lib/which.ts
|
|
30
28
|
var import_node_fs = __toESM(require("fs"));
|
|
29
|
+
var import_node_os = __toESM(require("os"));
|
|
31
30
|
var import_node_path = __toESM(require("path"));
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
const pathext = (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean);
|
|
37
|
-
if (import_node_path.default.extname(name)) {
|
|
38
|
-
return [name];
|
|
39
|
-
}
|
|
40
|
-
return [name, ...pathext.map((ext) => name + ext.toLowerCase())];
|
|
41
|
-
}
|
|
42
|
-
function which(name) {
|
|
43
|
-
const rawPath = process.env.PATH ?? "";
|
|
44
|
-
const dirs = rawPath.split(import_node_path.default.delimiter).filter(Boolean);
|
|
45
|
-
for (const dir of dirs) {
|
|
46
|
-
for (const candidate of candidatesForName(name)) {
|
|
47
|
-
const full = import_node_path.default.join(dir, candidate);
|
|
48
|
-
try {
|
|
49
|
-
const stat = import_node_fs.default.statSync(full);
|
|
50
|
-
if (stat.isFile()) {
|
|
51
|
-
return full;
|
|
52
|
-
}
|
|
53
|
-
} catch {
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// src/bin/logion.ts
|
|
61
|
-
var target = which("logion");
|
|
62
|
-
if (!target) {
|
|
31
|
+
var managedVenvDir = import_node_path.default.join(import_node_os.default.homedir(), ".logion", "npm-managed-venv");
|
|
32
|
+
var target = process.platform === "win32" ? import_node_path.default.join(managedVenvDir, "Scripts", "logion.exe") : import_node_path.default.join(managedVenvDir, "bin", "logion");
|
|
33
|
+
if (!import_node_fs.default.existsSync(target)) {
|
|
63
34
|
process.stderr.write(
|
|
64
|
-
"logion binary not found. Reinstall with `npm install -g @logionsh/cli` or
|
|
35
|
+
"logion binary not found in the npm-managed environment. Reinstall with `npm install -g @logionsh/cli` or rerun `npx @logionsh/cli`.\n"
|
|
65
36
|
);
|
|
66
37
|
process.exit(127);
|
|
67
38
|
}
|
|
@@ -44,7 +44,10 @@ function candidatesForName(name) {
|
|
|
44
44
|
}
|
|
45
45
|
return [name, ...pathext.map((ext) => name + ext.toLowerCase())];
|
|
46
46
|
}
|
|
47
|
-
function which(name) {
|
|
47
|
+
function which(name, options = {}) {
|
|
48
|
+
const excluded = new Set(
|
|
49
|
+
(options.excludeRealpaths ?? []).map((p) => import_node_fs.default.realpathSync.native(p))
|
|
50
|
+
);
|
|
48
51
|
const rawPath = process.env.PATH ?? "";
|
|
49
52
|
const dirs = rawPath.split(import_node_path.default.delimiter).filter(Boolean);
|
|
50
53
|
for (const dir of dirs) {
|
|
@@ -52,7 +55,7 @@ function which(name) {
|
|
|
52
55
|
const full = import_node_path.default.join(dir, candidate);
|
|
53
56
|
try {
|
|
54
57
|
const stat = import_node_fs.default.statSync(full);
|
|
55
|
-
if (stat.isFile()) {
|
|
58
|
+
if (stat.isFile() && !excluded.has(import_node_fs.default.realpathSync.native(full))) {
|
|
56
59
|
return full;
|
|
57
60
|
}
|
|
58
61
|
} catch {
|
|
@@ -249,7 +252,6 @@ var HOME = import_node_os2.default.homedir();
|
|
|
249
252
|
var LOGION_DIR2 = import_node_path3.default.join(HOME, ".logion");
|
|
250
253
|
var MANAGED_VENV_DIR = import_node_path3.default.join(LOGION_DIR2, "npm-managed-venv");
|
|
251
254
|
var MARKER_PATH = import_node_path3.default.join(LOGION_DIR2, "npm-wrapper-installer.json");
|
|
252
|
-
var LOCAL_BIN = import_node_path3.default.join(HOME, ".local", "bin");
|
|
253
255
|
var PLACEHOLDER_VERSION = "0.0.0-placeholder";
|
|
254
256
|
function log(msg) {
|
|
255
257
|
process.stderr.write(`[logion-postinstall] ${msg}
|
|
@@ -310,48 +312,15 @@ function venvBin(name) {
|
|
|
310
312
|
}
|
|
311
313
|
return import_node_path3.default.join(MANAGED_VENV_DIR, "bin", name);
|
|
312
314
|
}
|
|
313
|
-
function linkOrCopy(src, dest) {
|
|
314
|
-
if (import_node_fs3.default.existsSync(dest)) {
|
|
315
|
-
import_node_fs3.default.unlinkSync(dest);
|
|
316
|
-
}
|
|
317
|
-
try {
|
|
318
|
-
import_node_fs3.default.symlinkSync(src, dest);
|
|
319
|
-
} catch {
|
|
320
|
-
import_node_fs3.default.copyFileSync(src, dest);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
function shimNamesFor(base) {
|
|
324
|
-
return process.platform === "win32" ? [`${base}.exe`] : [base];
|
|
325
|
-
}
|
|
326
315
|
function installViaVenv(version, py) {
|
|
327
316
|
log(`Installing logion-cli==${version} via managed venv...`);
|
|
328
|
-
runChecked(py.cmd, [...py.args, "-m", "venv", MANAGED_VENV_DIR]);
|
|
317
|
+
runChecked(py.cmd, [...py.args, "-m", "venv", "--clear", MANAGED_VENV_DIR]);
|
|
329
318
|
runChecked(venvBin("pip"), ["install", `logion-cli==${version}`]);
|
|
330
|
-
import_node_fs3.default.mkdirSync(LOCAL_BIN, { recursive: true });
|
|
331
|
-
for (const base of ["logion", "lgn"]) {
|
|
332
|
-
const src = venvBin(base);
|
|
333
|
-
if (!import_node_fs3.default.existsSync(src)) {
|
|
334
|
-
continue;
|
|
335
|
-
}
|
|
336
|
-
for (const destName of shimNamesFor(base)) {
|
|
337
|
-
const dest = import_node_path3.default.join(LOCAL_BIN, destName);
|
|
338
|
-
try {
|
|
339
|
-
linkOrCopy(src, dest);
|
|
340
|
-
} catch (error) {
|
|
341
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
342
|
-
log(
|
|
343
|
-
`Warning: could not create shim ${dest}: ${msg}. Add ${LOCAL_BIN} to PATH manually.`
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
319
|
}
|
|
349
|
-
function verifyInstall(version) {
|
|
350
|
-
const target = which("logion");
|
|
351
|
-
if (!target) {
|
|
352
|
-
log(
|
|
353
|
-
"Warning: logion not on PATH yet. Ensure your installer's bin directory is exported."
|
|
354
|
-
);
|
|
320
|
+
function verifyInstall(version, installer) {
|
|
321
|
+
const target = installer === "venv" ? venvBin("logion") : which("logion");
|
|
322
|
+
if (!target || !import_node_fs3.default.existsSync(target)) {
|
|
323
|
+
log("Warning: logion binary was not found after install.");
|
|
355
324
|
return;
|
|
356
325
|
}
|
|
357
326
|
const r = (0, import_node_child_process2.spawnSync)(target, ["--version"], {
|
|
@@ -371,12 +340,6 @@ function pickInstaller(forced) {
|
|
|
371
340
|
if (forced !== void 0 && forced.length > 0) {
|
|
372
341
|
return null;
|
|
373
342
|
}
|
|
374
|
-
if (which("pipx")) {
|
|
375
|
-
return "pipx";
|
|
376
|
-
}
|
|
377
|
-
if (which("uv")) {
|
|
378
|
-
return "uv";
|
|
379
|
-
}
|
|
380
343
|
return "venv";
|
|
381
344
|
}
|
|
382
345
|
function maybePrintOnboardingPointer() {
|
|
@@ -407,9 +370,7 @@ function main() {
|
|
|
407
370
|
"Error: Python 3.12+ not found. Install Python 3.12+ or set LOGION_NPM_PYTHON."
|
|
408
371
|
);
|
|
409
372
|
log("See: https://www.python.org/downloads/");
|
|
410
|
-
log(
|
|
411
|
-
"Or set LOGION_NPM_SKIP_INSTALL=1 and install manually: pipx install logion-cli"
|
|
412
|
-
);
|
|
373
|
+
log("Or set LOGION_NPM_SKIP_INSTALL=1 to skip the Python CLI install.");
|
|
413
374
|
process.exit(1);
|
|
414
375
|
}
|
|
415
376
|
log(`Using Python: ${py.cmd} ${py.args.join(" ")}`.trim());
|
|
@@ -427,7 +388,7 @@ function main() {
|
|
|
427
388
|
installViaVenv(version, py);
|
|
428
389
|
}
|
|
429
390
|
writeMarker(installer, version);
|
|
430
|
-
verifyInstall(version);
|
|
391
|
+
verifyInstall(version, installer);
|
|
431
392
|
maybePrintOnboardingPointer();
|
|
432
393
|
log(`Installed logion-cli ${version} via ${installer}.`);
|
|
433
394
|
}
|
|
@@ -41,7 +41,10 @@ function candidatesForName(name) {
|
|
|
41
41
|
}
|
|
42
42
|
return [name, ...pathext.map((ext) => name + ext.toLowerCase())];
|
|
43
43
|
}
|
|
44
|
-
function which(name) {
|
|
44
|
+
function which(name, options = {}) {
|
|
45
|
+
const excluded = new Set(
|
|
46
|
+
(options.excludeRealpaths ?? []).map((p) => import_node_fs.default.realpathSync.native(p))
|
|
47
|
+
);
|
|
45
48
|
const rawPath = process.env.PATH ?? "";
|
|
46
49
|
const dirs = rawPath.split(import_node_path.default.delimiter).filter(Boolean);
|
|
47
50
|
for (const dir of dirs) {
|
|
@@ -49,7 +52,7 @@ function which(name) {
|
|
|
49
52
|
const full = import_node_path.default.join(dir, candidate);
|
|
50
53
|
try {
|
|
51
54
|
const stat = import_node_fs.default.statSync(full);
|
|
52
|
-
if (stat.isFile()) {
|
|
55
|
+
if (stat.isFile() && !excluded.has(import_node_fs.default.realpathSync.native(full))) {
|
|
53
56
|
return full;
|
|
54
57
|
}
|
|
55
58
|
} catch {
|
|
@@ -64,7 +67,6 @@ var HOME = import_node_os.default.homedir();
|
|
|
64
67
|
var LOGION_DIR = import_node_path2.default.join(HOME, ".logion");
|
|
65
68
|
var MANAGED_VENV_DIR = import_node_path2.default.join(LOGION_DIR, "npm-managed-venv");
|
|
66
69
|
var MARKER_PATH = import_node_path2.default.join(LOGION_DIR, "npm-wrapper-installer.json");
|
|
67
|
-
var LOCAL_BIN = import_node_path2.default.join(HOME, ".local", "bin");
|
|
68
70
|
function log(msg) {
|
|
69
71
|
process.stderr.write(`[logion-uninstall] ${msg}
|
|
70
72
|
`);
|
|
@@ -95,28 +97,13 @@ function removeManagedVenv() {
|
|
|
95
97
|
log(`Warning: could not remove managed venv: ${msg}`);
|
|
96
98
|
}
|
|
97
99
|
}
|
|
98
|
-
function removeShims() {
|
|
99
|
-
const names = process.platform === "win32" ? ["logion.exe", "lgn.exe", "logion.cmd", "lgn.cmd"] : ["logion", "lgn"];
|
|
100
|
-
for (const name of names) {
|
|
101
|
-
const link = import_node_path2.default.join(LOCAL_BIN, name);
|
|
102
|
-
try {
|
|
103
|
-
const stat = import_node_fs2.default.lstatSync(link);
|
|
104
|
-
if (stat.isSymbolicLink() || stat.isFile()) {
|
|
105
|
-
import_node_fs2.default.unlinkSync(link);
|
|
106
|
-
}
|
|
107
|
-
} catch {
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
100
|
function main() {
|
|
112
101
|
const marker = readMarker();
|
|
113
102
|
if (!marker) {
|
|
114
|
-
removeShims();
|
|
115
103
|
return;
|
|
116
104
|
}
|
|
117
105
|
if (marker.installer === "venv") {
|
|
118
106
|
removeManagedVenv();
|
|
119
|
-
removeShims();
|
|
120
107
|
} else if (marker.installer === "pipx" && which("pipx")) {
|
|
121
108
|
log("Uninstalling logion-cli via pipx...");
|
|
122
109
|
tryRun("pipx", ["uninstall", "logion-cli"]);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logionsh/cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Logion CLI — installs and
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Logion CLI — installs and runs the canonical Python logion-cli from a managed environment.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
"agent"
|
|
20
20
|
],
|
|
21
21
|
"bin": {
|
|
22
|
-
"logion": "dist/bin/logion.js"
|
|
23
|
-
"lgn": "dist/bin/lgn.js"
|
|
22
|
+
"logion": "dist/bin/logion.js"
|
|
24
23
|
},
|
|
25
24
|
"scripts": {
|
|
26
25
|
"build": "tsup",
|
|
@@ -66,5 +65,5 @@
|
|
|
66
65
|
"typescript-eslint": "^8.20.0",
|
|
67
66
|
"vitest": "^3.2.0"
|
|
68
67
|
},
|
|
69
|
-
"logionCliVersion": "0.1.
|
|
68
|
+
"logionCliVersion": "0.1.2"
|
|
70
69
|
}
|
package/dist/bin/lgn.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __toESM = (mod, isNodeMode, target2) => (target2 = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target2, "default", { value: mod, enumerable: true }) : target2,
|
|
23
|
-
mod
|
|
24
|
-
));
|
|
25
|
-
|
|
26
|
-
// src/bin/lgn.ts
|
|
27
|
-
var import_node_child_process = require("child_process");
|
|
28
|
-
|
|
29
|
-
// src/lib/which.ts
|
|
30
|
-
var import_node_fs = __toESM(require("fs"));
|
|
31
|
-
var import_node_path = __toESM(require("path"));
|
|
32
|
-
function candidatesForName(name) {
|
|
33
|
-
if (process.platform !== "win32") {
|
|
34
|
-
return [name];
|
|
35
|
-
}
|
|
36
|
-
const pathext = (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean);
|
|
37
|
-
if (import_node_path.default.extname(name)) {
|
|
38
|
-
return [name];
|
|
39
|
-
}
|
|
40
|
-
return [name, ...pathext.map((ext) => name + ext.toLowerCase())];
|
|
41
|
-
}
|
|
42
|
-
function which(name) {
|
|
43
|
-
const rawPath = process.env.PATH ?? "";
|
|
44
|
-
const dirs = rawPath.split(import_node_path.default.delimiter).filter(Boolean);
|
|
45
|
-
for (const dir of dirs) {
|
|
46
|
-
for (const candidate of candidatesForName(name)) {
|
|
47
|
-
const full = import_node_path.default.join(dir, candidate);
|
|
48
|
-
try {
|
|
49
|
-
const stat = import_node_fs.default.statSync(full);
|
|
50
|
-
if (stat.isFile()) {
|
|
51
|
-
return full;
|
|
52
|
-
}
|
|
53
|
-
} catch {
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// src/bin/lgn.ts
|
|
61
|
-
var target = which("lgn") ?? which("logion");
|
|
62
|
-
if (!target) {
|
|
63
|
-
process.stderr.write(
|
|
64
|
-
"lgn/logion binary not found. Reinstall with `npm install -g @logionsh/cli` or install directly via `pipx install logion-cli`.\n"
|
|
65
|
-
);
|
|
66
|
-
process.exit(127);
|
|
67
|
-
}
|
|
68
|
-
var r = (0, import_node_child_process.spawnSync)(target, process.argv.slice(2), { stdio: "inherit" });
|
|
69
|
-
if (r.error) {
|
|
70
|
-
process.stderr.write(`${r.error.message}
|
|
71
|
-
`);
|
|
72
|
-
process.exit(1);
|
|
73
|
-
}
|
|
74
|
-
process.exit(r.status ?? 1);
|