forgemap 0.4.1-dev.79-818a2fa → 0.4.1-dev.80-662a8e8
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/dist/bin/forgemap.mjs +201 -9
- package/dist/bin/forgemap.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bin/forgemap.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { access, mkdir, readFile, readdir, rename, rm, rmdir, stat, writeFile }
|
|
|
5
5
|
import { colors, formatTree } from "consola/utils";
|
|
6
6
|
import { dirname, isAbsolute, join, resolve } from "pathe";
|
|
7
7
|
import { homedir } from "node:os";
|
|
8
|
-
import { existsSync } from "node:fs";
|
|
8
|
+
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
9
9
|
import { loadConfig } from "c12";
|
|
10
10
|
import { createHash } from "node:crypto";
|
|
11
11
|
import { spawn } from "node:child_process";
|
|
@@ -93,7 +93,30 @@ var DEFAULT_CONFIG$1 = {
|
|
|
93
93
|
async function loadForgeMapConfig(options = {}) {
|
|
94
94
|
const envConfig = process.env.FORGEMAP_CONFIG;
|
|
95
95
|
const startDir = options.cwd ?? process.cwd();
|
|
96
|
-
|
|
96
|
+
let explicit;
|
|
97
|
+
let source;
|
|
98
|
+
if (options.configFile) {
|
|
99
|
+
explicit = options.configFile;
|
|
100
|
+
source = "flag";
|
|
101
|
+
} else if (envConfig) {
|
|
102
|
+
explicit = envConfig;
|
|
103
|
+
source = "env";
|
|
104
|
+
} else {
|
|
105
|
+
const walkedUp = findConfigUp(startDir);
|
|
106
|
+
if (walkedUp) {
|
|
107
|
+
explicit = walkedUp;
|
|
108
|
+
source = "walk-up";
|
|
109
|
+
} else {
|
|
110
|
+
const global = findGlobalConfig();
|
|
111
|
+
if (global) {
|
|
112
|
+
explicit = global;
|
|
113
|
+
source = "global";
|
|
114
|
+
} else {
|
|
115
|
+
explicit = void 0;
|
|
116
|
+
source = "default";
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
97
120
|
const cwd = explicit ? dirname(explicit) : startDir;
|
|
98
121
|
const { config, configFile } = await loadConfig({
|
|
99
122
|
name: "forgemap",
|
|
@@ -103,14 +126,17 @@ async function loadForgeMapConfig(options = {}) {
|
|
|
103
126
|
globalRc: false,
|
|
104
127
|
dotenv: false
|
|
105
128
|
});
|
|
129
|
+
const merged = {
|
|
130
|
+
root: config.root ?? DEFAULT_CONFIG$1.root,
|
|
131
|
+
defaultForge: config.defaultForge ?? DEFAULT_CONFIG$1.defaultForge,
|
|
132
|
+
forges: config.forges && Object.keys(config.forges).length > 0 ? config.forges : DEFAULT_CONFIG$1.forges
|
|
133
|
+
};
|
|
134
|
+
const resolvedFile = source === "default" ? void 0 : configFile || void 0;
|
|
106
135
|
return {
|
|
107
|
-
config:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
},
|
|
112
|
-
configFile: configFile || void 0,
|
|
113
|
-
cwd
|
|
136
|
+
config: merged,
|
|
137
|
+
configFile: resolvedFile,
|
|
138
|
+
cwd,
|
|
139
|
+
source: resolvedFile ? source : "default"
|
|
114
140
|
};
|
|
115
141
|
}
|
|
116
142
|
//#endregion
|
|
@@ -2243,6 +2269,170 @@ var importCommand = defineCommand({
|
|
|
2243
2269
|
}
|
|
2244
2270
|
});
|
|
2245
2271
|
//#endregion
|
|
2272
|
+
//#region src/commands/info.ts
|
|
2273
|
+
/** Resolve the real executed file behind any shim or symlink. */
|
|
2274
|
+
function resolveBinary(entry) {
|
|
2275
|
+
if (!entry) return {
|
|
2276
|
+
invoked: null,
|
|
2277
|
+
resolved: null
|
|
2278
|
+
};
|
|
2279
|
+
try {
|
|
2280
|
+
return {
|
|
2281
|
+
invoked: entry,
|
|
2282
|
+
resolved: realpathSync(entry)
|
|
2283
|
+
};
|
|
2284
|
+
} catch {
|
|
2285
|
+
return {
|
|
2286
|
+
invoked: entry,
|
|
2287
|
+
resolved: entry
|
|
2288
|
+
};
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
/** Walk up from `start` to the nearest package.json, returning its dir + name. */
|
|
2292
|
+
function findPackageRoot(start) {
|
|
2293
|
+
let dir = resolve(start);
|
|
2294
|
+
for (;;) {
|
|
2295
|
+
const pkgPath = join(dir, "package.json");
|
|
2296
|
+
if (existsSync(pkgPath)) try {
|
|
2297
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
2298
|
+
return {
|
|
2299
|
+
dir,
|
|
2300
|
+
name: pkg.name
|
|
2301
|
+
};
|
|
2302
|
+
} catch {
|
|
2303
|
+
return {
|
|
2304
|
+
dir,
|
|
2305
|
+
name: void 0
|
|
2306
|
+
};
|
|
2307
|
+
}
|
|
2308
|
+
const parent = dirname(dir);
|
|
2309
|
+
if (parent === dir) return null;
|
|
2310
|
+
dir = parent;
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
/**
|
|
2314
|
+
* Distinguish a linked/dev build from an installed release: the resolved binary
|
|
2315
|
+
* lives inside a git work tree whose package.json is named `forgemap`. An
|
|
2316
|
+
* installed package has the same package.json but no `.git` beside it. When the
|
|
2317
|
+
* binary or a `forgemap` package.json cannot be located, report `unknown`
|
|
2318
|
+
* rather than guessing.
|
|
2319
|
+
*/
|
|
2320
|
+
function detectBuild(resolved) {
|
|
2321
|
+
if (!resolved) return {
|
|
2322
|
+
kind: "unknown",
|
|
2323
|
+
packageRoot: null,
|
|
2324
|
+
reason: "binary path could not be resolved"
|
|
2325
|
+
};
|
|
2326
|
+
const pkg = findPackageRoot(dirname(resolved));
|
|
2327
|
+
if (!pkg) return {
|
|
2328
|
+
kind: "unknown",
|
|
2329
|
+
packageRoot: null,
|
|
2330
|
+
reason: "no package.json found above the binary"
|
|
2331
|
+
};
|
|
2332
|
+
if (pkg.name !== "forgemap") return {
|
|
2333
|
+
kind: "unknown",
|
|
2334
|
+
packageRoot: pkg.dir,
|
|
2335
|
+
reason: `nearest package.json is "${pkg.name ?? "unnamed"}", not forgemap`
|
|
2336
|
+
};
|
|
2337
|
+
const inGitTree = existsSync(join(pkg.dir, ".git"));
|
|
2338
|
+
return {
|
|
2339
|
+
kind: inGitTree ? "linked" : "release",
|
|
2340
|
+
packageRoot: pkg.dir,
|
|
2341
|
+
reason: inGitTree ? "runs from a git work tree named forgemap" : "installed forgemap package (no git work tree beside it)"
|
|
2342
|
+
};
|
|
2343
|
+
}
|
|
2344
|
+
async function gatherConfig(configFile) {
|
|
2345
|
+
try {
|
|
2346
|
+
const loaded = await loadForgeMapConfig({ configFile });
|
|
2347
|
+
const configDir = loaded.configFile ? dirname(loaded.configFile) : loaded.cwd;
|
|
2348
|
+
return {
|
|
2349
|
+
source: loaded.source,
|
|
2350
|
+
file: loaded.configFile ?? null,
|
|
2351
|
+
root: resolveRoot(loaded.config.root, configDir),
|
|
2352
|
+
forges: Object.entries(loaded.config.forges).map(([name, forge]) => ({
|
|
2353
|
+
name,
|
|
2354
|
+
type: forge.type,
|
|
2355
|
+
dir: forge.dir
|
|
2356
|
+
})),
|
|
2357
|
+
error: null
|
|
2358
|
+
};
|
|
2359
|
+
} catch (error) {
|
|
2360
|
+
return {
|
|
2361
|
+
source: "error",
|
|
2362
|
+
file: null,
|
|
2363
|
+
root: null,
|
|
2364
|
+
forges: [],
|
|
2365
|
+
error: error.message
|
|
2366
|
+
};
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
var SOURCE_LABELS = {
|
|
2370
|
+
flag: "--config flag",
|
|
2371
|
+
env: "FORGEMAP_CONFIG env",
|
|
2372
|
+
"walk-up": "walk-up from cwd",
|
|
2373
|
+
global: "global ($XDG_CONFIG_HOME/forgemap)",
|
|
2374
|
+
default: "built-in defaults (no config file found)",
|
|
2375
|
+
error: "failed to load"
|
|
2376
|
+
};
|
|
2377
|
+
var BUILD_LABELS = {
|
|
2378
|
+
linked: "linked / dev build",
|
|
2379
|
+
release: "installed release",
|
|
2380
|
+
unknown: "unknown"
|
|
2381
|
+
};
|
|
2382
|
+
function row(label, value) {
|
|
2383
|
+
return ` ${colors.dim(label.padEnd(9))} ${value}\n`;
|
|
2384
|
+
}
|
|
2385
|
+
function renderPretty(info) {
|
|
2386
|
+
let out = `${colors.bold("forgemap")} ${colors.cyan(`v${info.version}`)} ${colors.dim(`(${BUILD_LABELS[info.build.kind]})`)}\n`;
|
|
2387
|
+
out += row("build", colors.dim(info.build.reason));
|
|
2388
|
+
out += row("binary", info.binary.resolved ?? colors.dim("unknown"));
|
|
2389
|
+
if (info.binary.invoked && info.binary.invoked !== info.binary.resolved) out += row("", colors.dim(`via ${info.binary.invoked}`));
|
|
2390
|
+
out += row("node", info.node);
|
|
2391
|
+
out += `\n${colors.bold("config")}\n`;
|
|
2392
|
+
out += row("source", SOURCE_LABELS[info.config.source]);
|
|
2393
|
+
if (info.config.error) out += row("error", colors.red(info.config.error));
|
|
2394
|
+
else {
|
|
2395
|
+
out += row("file", info.config.file ?? colors.dim("none"));
|
|
2396
|
+
out += row("root", info.config.root ?? colors.dim("unknown"));
|
|
2397
|
+
}
|
|
2398
|
+
out += `\n${colors.bold("forges")}\n`;
|
|
2399
|
+
if (info.config.forges.length === 0) out += ` ${colors.dim("none")}\n`;
|
|
2400
|
+
else for (const forge of info.config.forges) out += ` ${colors.cyan(forge.name.padEnd(12))} ${forge.type} ${colors.dim("→")} ${forge.dir}\n`;
|
|
2401
|
+
return out;
|
|
2402
|
+
}
|
|
2403
|
+
var infoCommand = defineCommand({
|
|
2404
|
+
meta: {
|
|
2405
|
+
name: "info",
|
|
2406
|
+
description: "Describe this installation: version, binary path, node, and resolved config"
|
|
2407
|
+
},
|
|
2408
|
+
args: {
|
|
2409
|
+
json: {
|
|
2410
|
+
type: "boolean",
|
|
2411
|
+
description: "Emit a machine-readable JSON report",
|
|
2412
|
+
default: false
|
|
2413
|
+
},
|
|
2414
|
+
config: {
|
|
2415
|
+
type: "string",
|
|
2416
|
+
description: "Path to forgemap.config.ts (overrides walk-up discovery)"
|
|
2417
|
+
}
|
|
2418
|
+
},
|
|
2419
|
+
async run({ args }) {
|
|
2420
|
+
const binary = resolveBinary(process.argv[1]);
|
|
2421
|
+
const info = {
|
|
2422
|
+
version: "0.4.1-dev.80-662a8e8",
|
|
2423
|
+
build: detectBuild(binary.resolved),
|
|
2424
|
+
binary,
|
|
2425
|
+
node: process.version,
|
|
2426
|
+
config: await gatherConfig(args.config)
|
|
2427
|
+
};
|
|
2428
|
+
if (args.json) {
|
|
2429
|
+
process.stdout.write(`${JSON.stringify(info, null, 2)}\n`);
|
|
2430
|
+
return;
|
|
2431
|
+
}
|
|
2432
|
+
process.stdout.write(renderPretty(info));
|
|
2433
|
+
}
|
|
2434
|
+
});
|
|
2435
|
+
//#endregion
|
|
2246
2436
|
//#region src/repos/match.ts
|
|
2247
2437
|
/**
|
|
2248
2438
|
* The one Fuse configuration every fuzzy lookup shares — `search`, `pick`
|
|
@@ -3141,6 +3331,7 @@ function severitySymbol(severity) {
|
|
|
3141
3331
|
runMain(defineCommand({
|
|
3142
3332
|
meta: {
|
|
3143
3333
|
name: "forgemap",
|
|
3334
|
+
version: "0.4.1-dev.80-662a8e8",
|
|
3144
3335
|
description: "Manage a local repo layout of the form <root>/<forge.dir>/<owner>/<repo>"
|
|
3145
3336
|
},
|
|
3146
3337
|
subCommands: {
|
|
@@ -3191,6 +3382,7 @@ runMain(defineCommand({
|
|
|
3191
3382
|
if (!loaded.configFile) consola.warn("No forgemap.config.ts found — using built-in defaults. Run `forgemap config init` to materialize one.");
|
|
3192
3383
|
}
|
|
3193
3384
|
}),
|
|
3385
|
+
info: infoCommand,
|
|
3194
3386
|
completion: completionCommand,
|
|
3195
3387
|
"shell-init": shellInitCommand,
|
|
3196
3388
|
config: configCommand
|