rulesync 36.0.0 → 36.0.1

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.
@@ -1691,7 +1691,8 @@ async function listDirectoryRecursive(params) {
1691
1691
  else if (entry.type === "dir") directories.push(entry);
1692
1692
  else dropped = true;
1693
1693
  if (dropped) onIncompleteDirectory?.(path);
1694
- const subResults = await Promise.all(directories.map((dir) => listDirectoryRecursive({
1694
+ const failures = [];
1695
+ const settled = await Promise.allSettled(directories.map((dir) => listDirectoryRecursive({
1695
1696
  client,
1696
1697
  owner,
1697
1698
  repo,
@@ -1700,7 +1701,12 @@ async function listDirectoryRecursive(params) {
1700
1701
  depth: depth + 1,
1701
1702
  semaphore,
1702
1703
  onIncompleteDirectory
1704
+ }).catch((error) => {
1705
+ failures.push(error);
1706
+ throw error;
1703
1707
  })));
1708
+ if (failures.length > 0) throw failures[0];
1709
+ const subResults = settled.flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
1704
1710
  return [...files, ...subResults.flat()];
1705
1711
  }
1706
1712
  /**
@@ -2411,6 +2417,12 @@ async function resolveAndFetchSources(params) {
2411
2417
  failedSourceCount
2412
2418
  };
2413
2419
  }
2420
+ /**
2421
+ * The claim of a source the prefetch does not list -- a git or npm transport
2422
+ * source -- whose selection is a wildcard: it may take any
2423
+ * name, so later sources download nothing a name decides.
2424
+ */
2425
+ const ANY_NAME = Symbol("any name");
2414
2426
  function createNameClaim() {
2415
2427
  let settle = () => {};
2416
2428
  return {
@@ -2425,7 +2437,12 @@ function createClaimSlot(params) {
2425
2437
  return {
2426
2438
  earlier: async () => {
2427
2439
  const claimed = await Promise.all(earlier.map((claim) => claim.names));
2428
- return /* @__PURE__ */ new Set([...reserved, ...claimed.flat()]);
2440
+ const mayTakeAny = claimed.includes(ANY_NAME);
2441
+ const names = /* @__PURE__ */ new Set([...reserved, ...claimed.flatMap((claim) => claim === ANY_NAME ? [] : claim)]);
2442
+ return {
2443
+ names,
2444
+ has: (name) => mayTakeAny || names.has(name)
2445
+ };
2429
2446
  },
2430
2447
  settle: own.settle
2431
2448
  };
@@ -2450,13 +2467,30 @@ async function prefetchGithubSources(params) {
2450
2467
  ...rest,
2451
2468
  semaphore: new es_toolkit_promise.Semaphore(10)
2452
2469
  };
2453
- const items = sources.filter((sourceEntry) => (sourceEntry.transport ?? "github") === "github" && !hasEmptySelection(sourceEntry)).map((sourceEntry) => ({
2470
+ const items = sources.filter((sourceEntry) => !hasEmptySelection(sourceEntry)).map((sourceEntry) => ({
2454
2471
  sourceEntry,
2472
+ listedThroughApi: isListedThroughGithubApi(sourceEntry),
2455
2473
  skills: createNameClaim(),
2456
2474
  rules: createNameClaim()
2457
2475
  }));
2476
+ for (const item of items.filter((candidate) => !candidate.listedThroughApi)) {
2477
+ if (isGitlabSource(item.sourceEntry)) {
2478
+ item.skills.settle([]);
2479
+ item.rules.settle([]);
2480
+ continue;
2481
+ }
2482
+ const filters = getSourceFilters(item.sourceEntry);
2483
+ item.skills.settle(getSelectionClaim({
2484
+ selection: filters.skills,
2485
+ normalize: (name) => name
2486
+ }));
2487
+ item.rules.settle(getSelectionClaim({
2488
+ selection: filters.rules,
2489
+ normalize: normalizeRuleFilterName
2490
+ }));
2491
+ }
2458
2492
  await require_import.mapWithConcurrency({
2459
- items,
2493
+ items: items.filter((item) => item.listedThroughApi),
2460
2494
  limit: 4,
2461
2495
  mapper: async (item) => {
2462
2496
  const earlier = items.slice(0, items.indexOf(item));
@@ -2485,10 +2519,33 @@ async function prefetchGithubSources(params) {
2485
2519
  }
2486
2520
  });
2487
2521
  }
2522
+ /** Whether the prefetch lists and downloads this source through the GitHub API. */
2523
+ function isListedThroughGithubApi(sourceEntry) {
2524
+ if ((sourceEntry.transport ?? "github") !== "github") return false;
2525
+ try {
2526
+ return parseSource(sourceEntry.source).provider !== "gitlab";
2527
+ } catch {
2528
+ return true;
2529
+ }
2530
+ }
2531
+ /** Whether this is a GitLab source, which the serial pass does not support yet. */
2532
+ function isGitlabSource(sourceEntry) {
2533
+ if ((sourceEntry.transport ?? "github") !== "github") return false;
2534
+ try {
2535
+ return parseSource(sourceEntry.source).provider === "gitlab";
2536
+ } catch {
2537
+ return false;
2538
+ }
2539
+ }
2540
+ /** What a source the prefetch does not list may take, judged by its selection alone. */
2541
+ function getSelectionClaim(params) {
2542
+ const { selection, normalize } = params;
2543
+ if (selection === void 0) return [];
2544
+ return selection.includes("*") ? ANY_NAME : selection.map(normalize);
2545
+ }
2488
2546
  async function prefetchGithubSource(params) {
2489
2547
  const { sourceEntry, lock, context, skillClaim, ruleClaim } = params;
2490
2548
  const parsedFromSource = parseSource(sourceEntry.source);
2491
- if (parsedFromSource.provider === "gitlab") return;
2492
2549
  const parsed = {
2493
2550
  ...parsedFromSource,
2494
2551
  ref: sourceEntry.ref ?? parsedFromSource.ref,
@@ -2624,7 +2681,7 @@ async function prefetchGithubRules(params) {
2624
2681
  sourceEntry,
2625
2682
  lockedRuleNames: getLockedRuleNames(locked),
2626
2683
  localRuleNames: context.localRuleNames,
2627
- alreadyFetchedRuleNames: claimed,
2684
+ alreadyFetchedRuleNames: claimed.names,
2628
2685
  curatedDir: (0, node_path.join)(context.projectRoot, require_import.RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH)
2629
2686
  })) {
2630
2687
  claim.settle(getLockedRuleNames(locked));
@@ -14033,7 +14090,7 @@ function wrapCommand$1({ name, errorCode, handler, getVersion, loggerFactory = c
14033
14090
  }
14034
14091
  //#endregion
14035
14092
  //#region src/cli/program.ts
14036
- const getVersion = () => "36.0.0";
14093
+ const getVersion = () => "36.0.1";
14037
14094
  const FEATURES_HELP = `${require_import.ALL_FEATURES.join(",")}; ignore is deprecated, use permissions`;
14038
14095
  function wrapCommand(name, errorCode, handler) {
14039
14096
  return wrapCommand$1({
package/dist/cli/index.js CHANGED
@@ -1688,7 +1688,8 @@ async function listDirectoryRecursive(params) {
1688
1688
  else if (entry.type === "dir") directories.push(entry);
1689
1689
  else dropped = true;
1690
1690
  if (dropped) onIncompleteDirectory?.(path);
1691
- const subResults = await Promise.all(directories.map((dir) => listDirectoryRecursive({
1691
+ const failures = [];
1692
+ const settled = await Promise.allSettled(directories.map((dir) => listDirectoryRecursive({
1692
1693
  client,
1693
1694
  owner,
1694
1695
  repo,
@@ -1697,7 +1698,12 @@ async function listDirectoryRecursive(params) {
1697
1698
  depth: depth + 1,
1698
1699
  semaphore,
1699
1700
  onIncompleteDirectory
1701
+ }).catch((error) => {
1702
+ failures.push(error);
1703
+ throw error;
1700
1704
  })));
1705
+ if (failures.length > 0) throw failures[0];
1706
+ const subResults = settled.flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
1701
1707
  return [...files, ...subResults.flat()];
1702
1708
  }
1703
1709
  /**
@@ -2408,6 +2414,12 @@ async function resolveAndFetchSources(params) {
2408
2414
  failedSourceCount
2409
2415
  };
2410
2416
  }
2417
+ /**
2418
+ * The claim of a source the prefetch does not list -- a git or npm transport
2419
+ * source -- whose selection is a wildcard: it may take any
2420
+ * name, so later sources download nothing a name decides.
2421
+ */
2422
+ const ANY_NAME = Symbol("any name");
2411
2423
  function createNameClaim() {
2412
2424
  let settle = () => {};
2413
2425
  return {
@@ -2422,7 +2434,12 @@ function createClaimSlot(params) {
2422
2434
  return {
2423
2435
  earlier: async () => {
2424
2436
  const claimed = await Promise.all(earlier.map((claim) => claim.names));
2425
- return /* @__PURE__ */ new Set([...reserved, ...claimed.flat()]);
2437
+ const mayTakeAny = claimed.includes(ANY_NAME);
2438
+ const names = /* @__PURE__ */ new Set([...reserved, ...claimed.flatMap((claim) => claim === ANY_NAME ? [] : claim)]);
2439
+ return {
2440
+ names,
2441
+ has: (name) => mayTakeAny || names.has(name)
2442
+ };
2426
2443
  },
2427
2444
  settle: own.settle
2428
2445
  };
@@ -2447,13 +2464,30 @@ async function prefetchGithubSources(params) {
2447
2464
  ...rest,
2448
2465
  semaphore: new Semaphore(10)
2449
2466
  };
2450
- const items = sources.filter((sourceEntry) => (sourceEntry.transport ?? "github") === "github" && !hasEmptySelection(sourceEntry)).map((sourceEntry) => ({
2467
+ const items = sources.filter((sourceEntry) => !hasEmptySelection(sourceEntry)).map((sourceEntry) => ({
2451
2468
  sourceEntry,
2469
+ listedThroughApi: isListedThroughGithubApi(sourceEntry),
2452
2470
  skills: createNameClaim(),
2453
2471
  rules: createNameClaim()
2454
2472
  }));
2473
+ for (const item of items.filter((candidate) => !candidate.listedThroughApi)) {
2474
+ if (isGitlabSource(item.sourceEntry)) {
2475
+ item.skills.settle([]);
2476
+ item.rules.settle([]);
2477
+ continue;
2478
+ }
2479
+ const filters = getSourceFilters(item.sourceEntry);
2480
+ item.skills.settle(getSelectionClaim({
2481
+ selection: filters.skills,
2482
+ normalize: (name) => name
2483
+ }));
2484
+ item.rules.settle(getSelectionClaim({
2485
+ selection: filters.rules,
2486
+ normalize: normalizeRuleFilterName
2487
+ }));
2488
+ }
2455
2489
  await mapWithConcurrency({
2456
- items,
2490
+ items: items.filter((item) => item.listedThroughApi),
2457
2491
  limit: 4,
2458
2492
  mapper: async (item) => {
2459
2493
  const earlier = items.slice(0, items.indexOf(item));
@@ -2482,10 +2516,33 @@ async function prefetchGithubSources(params) {
2482
2516
  }
2483
2517
  });
2484
2518
  }
2519
+ /** Whether the prefetch lists and downloads this source through the GitHub API. */
2520
+ function isListedThroughGithubApi(sourceEntry) {
2521
+ if ((sourceEntry.transport ?? "github") !== "github") return false;
2522
+ try {
2523
+ return parseSource(sourceEntry.source).provider !== "gitlab";
2524
+ } catch {
2525
+ return true;
2526
+ }
2527
+ }
2528
+ /** Whether this is a GitLab source, which the serial pass does not support yet. */
2529
+ function isGitlabSource(sourceEntry) {
2530
+ if ((sourceEntry.transport ?? "github") !== "github") return false;
2531
+ try {
2532
+ return parseSource(sourceEntry.source).provider === "gitlab";
2533
+ } catch {
2534
+ return false;
2535
+ }
2536
+ }
2537
+ /** What a source the prefetch does not list may take, judged by its selection alone. */
2538
+ function getSelectionClaim(params) {
2539
+ const { selection, normalize } = params;
2540
+ if (selection === void 0) return [];
2541
+ return selection.includes("*") ? ANY_NAME : selection.map(normalize);
2542
+ }
2485
2543
  async function prefetchGithubSource(params) {
2486
2544
  const { sourceEntry, lock, context, skillClaim, ruleClaim } = params;
2487
2545
  const parsedFromSource = parseSource(sourceEntry.source);
2488
- if (parsedFromSource.provider === "gitlab") return;
2489
2546
  const parsed = {
2490
2547
  ...parsedFromSource,
2491
2548
  ref: sourceEntry.ref ?? parsedFromSource.ref,
@@ -2621,7 +2678,7 @@ async function prefetchGithubRules(params) {
2621
2678
  sourceEntry,
2622
2679
  lockedRuleNames: getLockedRuleNames(locked),
2623
2680
  localRuleNames: context.localRuleNames,
2624
- alreadyFetchedRuleNames: claimed,
2681
+ alreadyFetchedRuleNames: claimed.names,
2625
2682
  curatedDir: join(context.projectRoot, RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH)
2626
2683
  })) {
2627
2684
  claim.settle(getLockedRuleNames(locked));
@@ -14030,7 +14087,7 @@ function wrapCommand$1({ name, errorCode, handler, getVersion, loggerFactory = c
14030
14087
  }
14031
14088
  //#endregion
14032
14089
  //#region src/cli/program.ts
14033
- const getVersion = () => "36.0.0";
14090
+ const getVersion = () => "36.0.1";
14034
14091
  const FEATURES_HELP = `${ALL_FEATURES.join(",")}; ignore is deprecated, use permissions`;
14035
14092
  function wrapCommand(name, errorCode, handler) {
14036
14093
  return wrapCommand$1({