forgemap 0.7.0-dev.117-ac8b2c6 → 0.7.0-dev.118-ba83f2c
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 +47 -19
- package/dist/bin/forgemap.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bin/forgemap.mjs
CHANGED
|
@@ -256,11 +256,15 @@ async function safeStat(path) {
|
|
|
256
256
|
* marker and never descends into a repo, which keeps submodules and nested
|
|
257
257
|
* checkouts out without a special case for either.
|
|
258
258
|
*
|
|
259
|
-
* `segments` is the
|
|
260
|
-
* the
|
|
259
|
+
* `segments` is the path accumulated below the forge dir; the repo takes the
|
|
260
|
+
* last one and the namespace the rest, so a repo needs at least two.
|
|
261
|
+
*
|
|
262
|
+
* The cap counts those segments inclusive of the repo's own — a namespace at
|
|
263
|
+
* exactly MAX_NAMESPACE_DEPTH must still have its repo visited, or the
|
|
264
|
+
* resolver would accept a path the scanner can never find.
|
|
261
265
|
*/
|
|
262
266
|
async function walk(ctx, dirPath, segments) {
|
|
263
|
-
if (segments.length
|
|
267
|
+
if (segments.length > 10) {
|
|
264
268
|
ctx.hints.push({
|
|
265
269
|
path: dirPath,
|
|
266
270
|
reason: "too-deep"
|
|
@@ -803,8 +807,11 @@ var gitlabAdapter = {
|
|
|
803
807
|
* GRAPHQL_CHUNK projects, and each miss — `null` could mean gone *or*
|
|
804
808
|
* renamed — costs a single REST call to tell the two apart.
|
|
805
809
|
*
|
|
806
|
-
*
|
|
807
|
-
*
|
|
810
|
+
* A batch may span several configured GitLab forges, so the inputs are
|
|
811
|
+
* grouped by host before they are chunked: one server must never be asked
|
|
812
|
+
* about another's projects. Where the same full path exists on both — a
|
|
813
|
+
* public mirror of an internal project — the wrong server would otherwise
|
|
814
|
+
* answer `exists` for a project this one does not have.
|
|
808
815
|
*/
|
|
809
816
|
async checkRemotes(inputs) {
|
|
810
817
|
if (inputs.length === 0) return [];
|
|
@@ -812,10 +819,16 @@ var gitlabAdapter = {
|
|
|
812
819
|
state: "unknown",
|
|
813
820
|
reason: "glab not installed"
|
|
814
821
|
}));
|
|
815
|
-
const forge = inputs[0].forge;
|
|
816
822
|
const results = Array.from({ length: inputs.length }, () => null);
|
|
817
|
-
|
|
818
|
-
|
|
823
|
+
const byHost = /* @__PURE__ */ new Map();
|
|
824
|
+
inputs.forEach((input, index) => {
|
|
825
|
+
const indices = byHost.get(input.forge.host);
|
|
826
|
+
if (indices) indices.push(index);
|
|
827
|
+
else byHost.set(input.forge.host, [index]);
|
|
828
|
+
});
|
|
829
|
+
for (const indices of byHost.values()) for (let start = 0; start < indices.length; start += GRAPHQL_CHUNK) {
|
|
830
|
+
const slice = indices.slice(start, start + GRAPHQL_CHUNK);
|
|
831
|
+
const chunk = slice.map((index) => inputs[index]);
|
|
819
832
|
const res = await execCapture("glab", [
|
|
820
833
|
"api",
|
|
821
834
|
"graphql",
|
|
@@ -823,7 +836,7 @@ var gitlabAdapter = {
|
|
|
823
836
|
`query=${buildQuery(chunk)}`
|
|
824
837
|
], {
|
|
825
838
|
timeoutMs: GLAB_TIMEOUT_MS,
|
|
826
|
-
env: glabEnv(forge)
|
|
839
|
+
env: glabEnv(chunk[0].forge)
|
|
827
840
|
});
|
|
828
841
|
let data = null;
|
|
829
842
|
try {
|
|
@@ -835,7 +848,7 @@ var gitlabAdapter = {
|
|
|
835
848
|
for (let i = 0; i < chunk.length; i++) {
|
|
836
849
|
const node = data?.[`r${i}`];
|
|
837
850
|
const canonical = node?.fullPath ? splitFullPath(node.fullPath) : null;
|
|
838
|
-
if (canonical) results[
|
|
851
|
+
if (canonical) results[slice[i]] = {
|
|
839
852
|
state: "exists",
|
|
840
853
|
canonical
|
|
841
854
|
};
|
|
@@ -1203,16 +1216,31 @@ function remoteBlocker(state) {
|
|
|
1203
1216
|
if (state === "exists" || state === "moved") return null;
|
|
1204
1217
|
return state === "gone" ? "remote no longer exists" : "remote unreachable";
|
|
1205
1218
|
}
|
|
1206
|
-
/**
|
|
1219
|
+
/**
|
|
1220
|
+
* Check each candidate's remote, grouped by forge **type and host** so an
|
|
1221
|
+
* adapter can batch.
|
|
1222
|
+
*
|
|
1223
|
+
* The host is half the key, not a detail: two configured forges of one type —
|
|
1224
|
+
* gitlab.com beside a self-hosted instance — are two different servers, and a
|
|
1225
|
+
* batch spanning both would ask one of them about the other's projects. Where
|
|
1226
|
+
* the same path exists on each (a public mirror of an internal project), that
|
|
1227
|
+
* answers `exists` for the wrong server, and `remoteBlocker` reads `exists` as
|
|
1228
|
+
* "safe to delete".
|
|
1229
|
+
*/
|
|
1207
1230
|
async function classifyRemotes(candidates) {
|
|
1208
|
-
const
|
|
1231
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1209
1232
|
for (const c of candidates) {
|
|
1210
|
-
const
|
|
1211
|
-
|
|
1212
|
-
|
|
1233
|
+
const { type, host } = c.repo.forge;
|
|
1234
|
+
const key = `${type}\0${host}`;
|
|
1235
|
+
const group = groups.get(key);
|
|
1236
|
+
if (group) group.items.push(c);
|
|
1237
|
+
else groups.set(key, {
|
|
1238
|
+
type,
|
|
1239
|
+
items: [c]
|
|
1240
|
+
});
|
|
1213
1241
|
}
|
|
1214
1242
|
const results = /* @__PURE__ */ new Map();
|
|
1215
|
-
await Promise.all(Array.from(
|
|
1243
|
+
await Promise.all(Array.from(groups.values(), async ({ type, items }) => {
|
|
1216
1244
|
const inputs = items.map((c) => ({
|
|
1217
1245
|
forge: c.repo.forge,
|
|
1218
1246
|
owner: c.owner,
|
|
@@ -2533,7 +2561,7 @@ async function readEntries(path) {
|
|
|
2533
2561
|
* reason `import` looks at directories a scan would simply skip.
|
|
2534
2562
|
*/
|
|
2535
2563
|
async function discoverBelow(serverDir, dirPath, segments, found) {
|
|
2536
|
-
if (segments.length
|
|
2564
|
+
if (segments.length > 10) return;
|
|
2537
2565
|
const entries = await readEntries(dirPath);
|
|
2538
2566
|
const isLeaf = entries === null || entries.dirs.length === 0;
|
|
2539
2567
|
if (segments.length >= 2 && (entries?.isRepo || isLeaf)) {
|
|
@@ -3215,7 +3243,7 @@ var infoCommand = defineCommand({
|
|
|
3215
3243
|
async run({ args }) {
|
|
3216
3244
|
const binary = resolveBinary(process.argv[1]);
|
|
3217
3245
|
const info = {
|
|
3218
|
-
version: "0.7.0-dev.
|
|
3246
|
+
version: "0.7.0-dev.118-ba83f2c",
|
|
3219
3247
|
build: detectBuild(binary.resolved),
|
|
3220
3248
|
binary,
|
|
3221
3249
|
node: process.version,
|
|
@@ -4415,7 +4443,7 @@ var completionCommand = defineCommand({
|
|
|
4415
4443
|
runMain(defineCommand({
|
|
4416
4444
|
meta: {
|
|
4417
4445
|
name: "forgemap",
|
|
4418
|
-
version: "0.7.0-dev.
|
|
4446
|
+
version: "0.7.0-dev.118-ba83f2c",
|
|
4419
4447
|
description: "Manage a local repo layout of the form <root>/<forge.dir>/<owner>/<repo>"
|
|
4420
4448
|
},
|
|
4421
4449
|
subCommands: {
|