@package-pal/core 0.0.12 → 0.0.14

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 (35) hide show
  1. package/index.d.ts +4 -0
  2. package/index.d.ts.map +1 -1
  3. package/index.js +351 -129
  4. package/index.js.map +14 -13
  5. package/lib/configuration/functions/get-ignore-globs.d.ts +7 -0
  6. package/lib/configuration/functions/get-ignore-globs.d.ts.map +1 -0
  7. package/lib/configuration/functions/load-config.d.ts.map +1 -1
  8. package/lib/configuration/functions/parse-config.d.ts +14 -0
  9. package/lib/configuration/functions/parse-config.d.ts.map +1 -1
  10. package/lib/configuration/schemas/config.d.ts +21 -0
  11. package/lib/configuration/schemas/config.d.ts.map +1 -1
  12. package/lib/configuration/types/activated-config.d.ts +1 -0
  13. package/lib/configuration/types/activated-config.d.ts.map +1 -1
  14. package/lib/configuration/types/bump-package-callback-props.d.ts +42 -0
  15. package/lib/configuration/types/bump-package-callback-props.d.ts.map +1 -0
  16. package/lib/configuration/types/bump-packages-ready-callback-props.d.ts +14 -0
  17. package/lib/configuration/types/bump-packages-ready-callback-props.d.ts.map +1 -0
  18. package/lib/configuration/types/config.d.ts +16 -0
  19. package/lib/configuration/types/config.d.ts.map +1 -1
  20. package/lib/configuration/types/packages-ready-callback-props.d.ts +11 -0
  21. package/lib/configuration/types/packages-ready-callback-props.d.ts.map +1 -1
  22. package/lib/configuration/types/process-package-callback-props.d.ts +18 -0
  23. package/lib/configuration/types/process-package-callback-props.d.ts.map +1 -1
  24. package/lib/graph/functions/dfs-traverse-graph.d.ts +4 -1
  25. package/lib/graph/functions/dfs-traverse-graph.d.ts.map +1 -1
  26. package/lib/package/functions/bump-package-version.d.ts.map +1 -1
  27. package/lib/package/functions/load-packages.d.ts.map +1 -1
  28. package/lib/package/functions/scan-glob-pattern-paths.d.ts.map +1 -1
  29. package/lib/types/bump-package-version-options.d.ts +1 -0
  30. package/lib/types/bump-package-version-options.d.ts.map +1 -1
  31. package/lib/types/bump-version-type.d.ts +4 -4
  32. package/lib/watch/functions/dedupe-shared-paths.d.ts.map +1 -1
  33. package/lib/watch/functions/filter-files-modified-since.d.ts.map +1 -1
  34. package/lib/watch/functions/watch-package-changes.d.ts.map +1 -1
  35. package/package.json +3 -3
package/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  // @bun
2
2
  // packages/core/src/lib/types/bump-version-type.ts
3
3
  var BumpVersionType = {
4
- Major: "major",
5
- Minor: "minor",
6
4
  Patch: "patch",
7
- Premajor: "premajor",
8
- Preminor: "preminor",
5
+ Minor: "minor",
6
+ Major: "major",
9
7
  Prepatch: "prepatch",
8
+ Preminor: "preminor",
9
+ Premajor: "premajor",
10
10
  Prerelease: "prerelease"
11
11
  };
12
12
  // packages/core/src/lib/package/types/package-adapter.ts
@@ -95,6 +95,18 @@ var Config = z3.object({
95
95
  preId: z3.optional(z3.string()),
96
96
  exact: z3.optional(z3.boolean())
97
97
  })),
98
+ bump: z3.optional(zLooseObjectWithoutIndexSignature({
99
+ ignore: z3.optional(z3.union([z3.string(), z3.array(z3.string())])),
100
+ hooks: z3.optional(z3.object({
101
+ onBeforeProcessPackage: z3.optional(zLooseFunction()),
102
+ onProcessPackage: z3.optional(zLooseFunction()),
103
+ onAfterProcessPackage: z3.optional(zLooseFunction()),
104
+ onBeforePackagesReady: z3.optional(zLooseFunction()),
105
+ onPackagesReady: z3.optional(zLooseFunction()),
106
+ onAfterPackagesReady: z3.optional(zLooseFunction())
107
+ })),
108
+ subprocess: z3.optional(z3.object({ concurrency: z3.nullish(z3.number()) }))
109
+ })),
98
110
  watch: z3.optional(zLooseObjectWithoutIndexSignature({
99
111
  debounceMs: z3.optional(z3.number()),
100
112
  ignore: z3.optional(z3.union([z3.string(), z3.array(z3.string())])),
@@ -221,6 +233,18 @@ var defaultConfig = {
221
233
  preId: "",
222
234
  exact: false
223
235
  },
236
+ bump: {
237
+ ignore: "",
238
+ hooks: {
239
+ onBeforeProcessPackage: noOp2,
240
+ onProcessPackage: noOp2,
241
+ onAfterProcessPackage: noOp2,
242
+ onBeforePackagesReady: noOp2,
243
+ onPackagesReady: noOp2,
244
+ onAfterPackagesReady: noOp2
245
+ },
246
+ subprocess: { concurrency: null }
247
+ },
224
248
  watch: {
225
249
  debounceMs: 500,
226
250
  ignore: "",
@@ -388,7 +412,7 @@ import { assertDefined as assertDefined5 } from "@package-pal/util";
388
412
 
389
413
  // packages/core/src/lib/graph/functions/dfs-traverse-graph.ts
390
414
  import { assertDefined as assertDefined4 } from "@package-pal/util";
391
- var dfsTraverseGraph = function* (graph, traverseFromPackages) {
415
+ var dfsTraverseGraph = function* (graph, traverseFromPackages, options) {
392
416
  const visited = new Set;
393
417
  const stack = Array.isArray(traverseFromPackages) ? traverseFromPackages.slice() : [traverseFromPackages];
394
418
  while (stack.length) {
@@ -404,6 +428,9 @@ var dfsTraverseGraph = function* (graph, traverseFromPackages) {
404
428
  yield node.packageData;
405
429
  for (const dep of node.pointsToPackages) {
406
430
  if (!visited.has(dep)) {
431
+ if (options?.shouldTraverse && !options.shouldTraverse(dep)) {
432
+ continue;
433
+ }
407
434
  stack.push(dep);
408
435
  }
409
436
  }
@@ -572,76 +599,25 @@ var generateTopologicalSortedGroups = (packageGraph, logger) => {
572
599
  };
573
600
 
574
601
  // packages/core/src/lib/package/functions/bump-package-version.ts
575
- import { styleText as styleText5 } from "util";
576
- import { isDefined as isDefined2 } from "@package-pal/util";
577
- import { inc } from "semver";
578
- var bumpPackageVersion = async (options) => {
579
- const exact = isDefined2(options.exact) ? options.exact : options.config.version.exact;
580
- const preId = isDefined2(options.preId) ? options.preId : options.config.version.preId;
581
- const {
582
- packageName,
583
- type,
584
- packageGraphs,
585
- adapter,
586
- config: { logger }
587
- } = options;
588
- logger.debug(styleText5("dim", `Bumping package '${packageName}'...`));
589
- const packageNode = packageGraphs.dependencies.get(packageName);
590
- if (!packageNode) {
591
- throw new Error(`Package '${packageName}' not found.`);
592
- }
593
- const currentVersion = packageNode.packageData.version ?? "1.0.0";
594
- const bumpedVersion = inc(currentVersion, type, undefined, preId);
595
- if (!bumpedVersion) {
596
- throw new Error(`Package '${packageName}' version '${currentVersion}' is invalid.`);
597
- }
598
- logger.info(`Updating '${packageName}' version: ${currentVersion} \u2192 ${bumpedVersion}.`);
599
- await adapter.bumpOwnVersion(packageNode.packageData, bumpedVersion, logger);
600
- const dependentWrites = [];
601
- for (const dependent of dfsTraverseGraph(packageGraphs.dependents, packageName)) {
602
- dependentWrites.push((async () => {
603
- const updated = await adapter.bumpDependencyVersion(dependent, packageName, bumpedVersion, exact, logger);
604
- if (updated) {
605
- logger.debug(styleText5("dim", `Updated dependency '${packageName}' in '${dependent.name}'.`));
606
- }
607
- })());
608
- }
609
- await Promise.all(dependentWrites);
610
- };
611
-
612
- // packages/core/src/lib/package/functions/load-packages.ts
613
- import { styleText as styleText6 } from "util";
614
- var loadPackages = async (rootDir, packagePatterns, adapter, logger) => {
615
- let resolvedPatterns = packagePatterns;
616
- if (packagePatterns.length === 1 && packagePatterns[0] === "packages/*") {
617
- resolvedPatterns = adapter.defaultPatterns;
618
- }
619
- const patternContent = resolvedPatterns.map((pattern) => `'${pattern}'`).join(", ");
620
- logger.debug(styleText6("dim", `Loading packages matching pattern/s ${patternContent}...${rootDir ? ` from ${rootDir}` : ""}`));
621
- const packages = [];
622
- const seen = new Set;
623
- for await (const packageData of adapter.scanPackages(Array.from(new Set(resolvedPatterns)), logger, rootDir)) {
624
- if (seen.has(packageData.name)) {
625
- continue;
626
- }
627
- seen.add(packageData.name);
628
- packages.push(packageData);
629
- }
630
- if (!packages.length) {
631
- throw new Error(`No packages found for pattern/s ${patternContent}.`);
632
- }
633
- return packages;
634
- };
635
-
636
- // packages/core/src/lib/package/functions/run-for-each-package.ts
637
602
  import { dirname as dirname4 } from "path";
603
+ import { styleText as styleText6 } from "util";
638
604
  import {
639
- assertDefined as assertDefined8,
605
+ isDefined as isDefined2,
606
+ normalisePath,
640
607
  runAsync
641
608
  } from "@package-pal/util";
609
+ import { inc } from "semver";
610
+
611
+ // packages/core/src/lib/configuration/functions/get-ignore-globs.ts
612
+ var {Glob } = globalThis.Bun;
613
+ var getIgnoreGlobs = (ignore) => {
614
+ const patterns = Array.isArray(ignore) ? ignore : [ignore];
615
+ const filtered = patterns.filter((pattern) => pattern.length > 0);
616
+ return filtered.length === 0 ? undefined : filtered.map((pattern) => new Glob(pattern));
617
+ };
642
618
 
643
619
  // packages/core/src/lib/process/functions/run-subprocess.ts
644
- import { styleText as styleText7 } from "util";
620
+ import { styleText as styleText5 } from "util";
645
621
 
646
622
  // packages/core/src/lib/process/types/exit-state.ts
647
623
  var ExitState = {
@@ -937,7 +913,7 @@ var cancelCodes = new Set([
937
913
  ]);
938
914
  var runSubprocess = async (opts) => {
939
915
  if (opts.signal?.aborted) {
940
- opts.logger?.debug(styleText7("dim", `Skipped '${opts.debugName}' subprocess command; signal already cancelled.`));
916
+ opts.logger?.debug(styleText5("dim", `Skipped '${opts.debugName}' subprocess command; signal already cancelled.`));
941
917
  return ExitState.Cancelled;
942
918
  }
943
919
  const {
@@ -964,11 +940,11 @@ var runSubprocess = async (opts) => {
964
940
  const [readStdout, readStderr] = [{
965
941
  source: subprocess.stdout,
966
942
  type: StdType.Out,
967
- writer: getLineBufferedWriter(styleText7("dim", `[O-${pid}]`.padEnd(minPrefixLen, " ")))
943
+ writer: getLineBufferedWriter(styleText5("dim", `[O-${pid}]`.padEnd(minPrefixLen, " ")))
968
944
  }, {
969
945
  source: subprocess.stderr,
970
946
  type: StdType.Err,
971
- writer: getLineBufferedWriter(styleText7("yellow", styleText7("dim", `[E-${pid}]`.padEnd(minPrefixLen, " "))), undefined, process.stderr.write.bind(process.stderr))
947
+ writer: getLineBufferedWriter(styleText5("yellow", styleText5("dim", `[E-${pid}]`.padEnd(minPrefixLen, " "))), undefined, process.stderr.write.bind(process.stderr))
972
948
  }].map(async ({
973
949
  source,
974
950
  type,
@@ -987,7 +963,7 @@ var runSubprocess = async (opts) => {
987
963
  writer.flush();
988
964
  });
989
965
  const executedCommand = commands.join(" ");
990
- opts.logger?.debug(styleText7("dim", `Started '${opts.debugName}' subprocess command '${opts.shellCommand}' (${executedCommand}) with PID ${pid}.`));
966
+ opts.logger?.debug(styleText5("dim", `Started '${opts.debugName}' subprocess command '${opts.shellCommand}' (${executedCommand}) with PID ${pid}.`));
991
967
  const [
992
968
  ,
993
969
  ,
@@ -997,21 +973,267 @@ var runSubprocess = async (opts) => {
997
973
  readStderr,
998
974
  subprocess.exited.then((exitCode) => {
999
975
  if (cancelCodes.has(exitCode)) {
1000
- opts.logger?.debug(styleText7("dim", `Cancelled '${opts.debugName}' subprocess command; PID ${pid} exited.`));
976
+ opts.logger?.debug(styleText5("dim", `Cancelled '${opts.debugName}' subprocess command; PID ${pid} exited.`));
1001
977
  return ExitState.Cancelled;
1002
978
  }
1003
979
  if (exitCode !== 0) {
1004
- opts.logger?.error(styleText7("red", `'${opts.debugName}' command '${opts.shellCommand}' (${executedCommand}) with PID ${pid} failed with exit code ${exitCode.toString()}.`));
980
+ opts.logger?.error(styleText5("red", `'${opts.debugName}' command '${opts.shellCommand}' (${executedCommand}) with PID ${pid} failed with exit code ${exitCode.toString()}.`));
1005
981
  return ExitState.Errored;
1006
982
  }
1007
- opts.logger?.debug(styleText7("dim", `Completed '${opts.debugName}' subprocess command; PID ${pid} exited.`));
983
+ opts.logger?.debug(styleText5("dim", `Completed '${opts.debugName}' subprocess command; PID ${pid} exited.`));
1008
984
  return ExitState.Completed;
1009
985
  })
1010
986
  ]);
1011
987
  return exitState;
1012
988
  };
1013
989
 
990
+ // packages/core/src/lib/package/functions/bump-package-version.ts
991
+ var dependentWriteConcurrency = 20;
992
+ var runBumpHookCommand = async (debugName, shellCommand, options) => {
993
+ if (!shellCommand) {
994
+ return;
995
+ }
996
+ const exitState = await runSubprocess({
997
+ ...options,
998
+ debugName,
999
+ shellCommand
1000
+ });
1001
+ if (exitState === ExitState.Errored) {
1002
+ throw new Error(`Bump hook '${debugName}' failed.`);
1003
+ }
1004
+ };
1005
+ var toShellCommand = (value) => {
1006
+ return typeof value === "string" ? value : undefined;
1007
+ };
1008
+ var isIgnoredPackage = (packageData, ignoreGlobs) => {
1009
+ const normalisedPath = normalisePath(packageData.path);
1010
+ const normalisedDir = normalisePath(packageData.dir);
1011
+ return ignoreGlobs.some((glob) => glob.match(normalisedPath) || glob.match(normalisedDir));
1012
+ };
1013
+ var getBumpHookProps = (bumpGroups) => {
1014
+ return {
1015
+ totalBumps: new Map(bumpGroups.flat().map((bump) => [bump.name, bump])),
1016
+ totalBumpOrder: bumpGroups.map((group) => group.map((bump) => bump.name))
1017
+ };
1018
+ };
1019
+ var runBumpPackageHooks = async (bumpConfig, bumpGroup, allBumpGroups, logger) => {
1020
+ const {
1021
+ totalBumps,
1022
+ totalBumpOrder
1023
+ } = getBumpHookProps(allBumpGroups);
1024
+ await runAsync(bumpGroup.map((bump) => async () => {
1025
+ const props = {
1026
+ ...bump,
1027
+ totalBumps,
1028
+ totalBumpOrder
1029
+ };
1030
+ const cwd2 = dirname4(bump.path);
1031
+ const env2 = {
1032
+ PP_PACKAGE_NAME: bump.name,
1033
+ PP_PACKAGE_DIR: bump.dir,
1034
+ PP_PACKAGE_PATH: bump.path,
1035
+ PP_PACKAGE_VERSION: bump.version,
1036
+ PP_PACKAGE_PREVIOUS_VERSION: bump.previousVersion,
1037
+ PP_PACKAGE_BUMP_TYPE: bump.type
1038
+ };
1039
+ await runBumpHookCommand(`before bump ${bump.name}`, toShellCommand(await bumpConfig.hooks.onBeforeProcessPackage(props)), {
1040
+ cwd: cwd2,
1041
+ env: env2,
1042
+ logger
1043
+ });
1044
+ await runBumpHookCommand(`bump ${bump.name}`, toShellCommand(await bumpConfig.hooks.onProcessPackage(props)), {
1045
+ cwd: cwd2,
1046
+ env: env2,
1047
+ logger
1048
+ });
1049
+ await runBumpHookCommand(`after bump ${bump.name}`, toShellCommand(await bumpConfig.hooks.onAfterProcessPackage(props)), {
1050
+ cwd: cwd2,
1051
+ env: env2,
1052
+ logger
1053
+ });
1054
+ }), bumpConfig.subprocess.concurrency);
1055
+ };
1056
+ var runBumpReadyHooks = async (bumpConfig, bumpGroups, logger) => {
1057
+ const {
1058
+ totalBumps,
1059
+ totalBumpOrder
1060
+ } = getBumpHookProps(bumpGroups);
1061
+ const readyProps = {
1062
+ totalBumps,
1063
+ totalBumpOrder
1064
+ };
1065
+ await runBumpHookCommand("before bump packages ready", toShellCommand(await bumpConfig.hooks.onBeforePackagesReady(readyProps)), { logger });
1066
+ await runBumpHookCommand("bump packages ready", toShellCommand(await bumpConfig.hooks.onPackagesReady(readyProps)), { logger });
1067
+ await runBumpHookCommand("after bump packages ready", toShellCommand(await bumpConfig.hooks.onAfterPackagesReady(readyProps)), { logger });
1068
+ };
1069
+ var createBumpPackage = (packageName, options) => ({
1070
+ name: packageName,
1071
+ dir: options.dir,
1072
+ path: options.path,
1073
+ previousVersion: options.previousVersion,
1074
+ version: options.version,
1075
+ type: options.type,
1076
+ isSourcePackage: options.isSourcePackage
1077
+ });
1078
+ var bumpPackageVersion = async (options) => {
1079
+ const exact = isDefined2(options.exact) ? options.exact : options.config.version.exact;
1080
+ const preId = isDefined2(options.preId) ? options.preId : options.config.version.preId;
1081
+ const {
1082
+ packageName,
1083
+ type,
1084
+ cascade,
1085
+ packageGraphs,
1086
+ adapter,
1087
+ config: {
1088
+ bump,
1089
+ logger
1090
+ }
1091
+ } = options;
1092
+ logger.debug(styleText6("dim", `Bumping package '${packageName}'...`));
1093
+ const packageNode = packageGraphs.dependencies.get(packageName);
1094
+ if (!packageNode) {
1095
+ throw new Error(`Package '${packageName}' not found.`);
1096
+ }
1097
+ const ignoreGlobs = getIgnoreGlobs(bump.ignore);
1098
+ const ignoredPackageNames = !ignoreGlobs ? new Set : new Set(Array.from(packageGraphs.dependencies.values()).filter((node) => isIgnoredPackage(node.packageData, ignoreGlobs)).map((node) => node.packageData.name));
1099
+ if (ignoredPackageNames.has(packageName)) {
1100
+ throw new Error(`Package '${packageName}' matches bump.ignore and cannot be bumped.`);
1101
+ }
1102
+ const traversed = Array.from(dfsTraverseGraph(packageGraphs.dependents, packageName, { shouldTraverse: (name) => {
1103
+ if (ignoredPackageNames.has(name)) {
1104
+ logger.debug(styleText6("dim", `Ignoring bump cascade through '${name}' (matched bump.ignore).`));
1105
+ return false;
1106
+ }
1107
+ return true;
1108
+ } }));
1109
+ const packageNamesToBump = new Set(traversed.map((pkg) => pkg.name));
1110
+ const dependentsToBump = traversed.filter((pkg) => pkg.name !== packageName);
1111
+ const bumpGroups = [];
1112
+ if (cascade) {
1113
+ const sortedGroupsObj = generateTopologicalSortedGroups(packageGraphs.dependencies, logger);
1114
+ const packagesToProcessInOrder = sortedGroupsObj.groups.map((group) => group.filter((name) => packageNamesToBump.has(name))).filter((group) => group.length > 0);
1115
+ const circularPackagesToProcess = sortedGroupsObj.circular.filter((name) => packageNamesToBump.has(name));
1116
+ if (circularPackagesToProcess.length > 0) {
1117
+ packagesToProcessInOrder.push(circularPackagesToProcess);
1118
+ }
1119
+ for (const packageGroup of packagesToProcessInOrder) {
1120
+ const groupBumps = [];
1121
+ for (const currentPackageName of packageGroup) {
1122
+ const node = packageGraphs.dependencies.get(currentPackageName);
1123
+ if (!node) {
1124
+ continue;
1125
+ }
1126
+ const currentVersion = node.packageData.version ?? "1.0.0";
1127
+ const bumpType = currentPackageName === packageName ? type : cascade;
1128
+ const nextVersion = inc(currentVersion, bumpType, undefined, preId);
1129
+ if (!nextVersion) {
1130
+ throw new Error(`Package '${currentPackageName}' version '${currentVersion}' is invalid.`);
1131
+ }
1132
+ groupBumps.push(createBumpPackage(currentPackageName, {
1133
+ dir: node.packageData.dir,
1134
+ path: node.packageData.path,
1135
+ previousVersion: currentVersion,
1136
+ version: nextVersion,
1137
+ type: bumpType,
1138
+ isSourcePackage: currentPackageName === packageName
1139
+ }));
1140
+ }
1141
+ if (groupBumps.length > 0) {
1142
+ bumpGroups.push(groupBumps);
1143
+ }
1144
+ }
1145
+ const bumpedVersionsMap = new Map;
1146
+ for (const groupBumps of bumpGroups) {
1147
+ const groupBumpedVersionsMap = new Map(groupBumps.map((bumpPackage) => [bumpPackage.name, bumpPackage.version]));
1148
+ for (const [currentPackageName, nextVersion] of groupBumpedVersionsMap) {
1149
+ bumpedVersionsMap.set(currentPackageName, nextVersion);
1150
+ }
1151
+ await runAsync(groupBumps.map((bumpPackage) => async () => {
1152
+ const node = packageGraphs.dependencies.get(bumpPackage.name);
1153
+ if (!node) {
1154
+ return;
1155
+ }
1156
+ for (const depName of node.packageData.localDependencies ?? []) {
1157
+ const newlyBumpedVersion = bumpedVersionsMap.get(depName);
1158
+ if (newlyBumpedVersion) {
1159
+ await adapter.bumpDependencyVersion(node.packageData, depName, newlyBumpedVersion, exact, logger);
1160
+ }
1161
+ }
1162
+ logger.debug(styleText6("dim", `Bumping '${bumpPackage.name}' (${bumpPackage.type}): ${bumpPackage.previousVersion} \u2192 ${bumpPackage.version}`));
1163
+ await adapter.bumpOwnVersion(node.packageData, bumpPackage.version, logger);
1164
+ node.packageData.version = bumpPackage.version;
1165
+ }), dependentWriteConcurrency);
1166
+ await runBumpPackageHooks(bump, groupBumps, bumpGroups, logger);
1167
+ }
1168
+ } else {
1169
+ const currentVersion = packageNode.packageData.version ?? "1.0.0";
1170
+ const bumpedVersion = inc(currentVersion, type, undefined, preId);
1171
+ if (!bumpedVersion) {
1172
+ throw new Error(`Package '${packageName}' version '${currentVersion}' is invalid.`);
1173
+ }
1174
+ const sourceBump = createBumpPackage(packageName, {
1175
+ dir: packageNode.packageData.dir,
1176
+ path: packageNode.packageData.path,
1177
+ previousVersion: currentVersion,
1178
+ version: bumpedVersion,
1179
+ type,
1180
+ isSourcePackage: true
1181
+ });
1182
+ bumpGroups.push([sourceBump]);
1183
+ logger.debug(styleText6("dim", `Bumping '${packageName}' (${type}): ${currentVersion} \u2192 ${bumpedVersion}`));
1184
+ await adapter.bumpOwnVersion(packageNode.packageData, bumpedVersion, logger);
1185
+ const dependentWriteTasks = [];
1186
+ for (const dependent of dependentsToBump) {
1187
+ dependentWriteTasks.push(async () => {
1188
+ const updated = await adapter.bumpDependencyVersion(dependent, packageName, bumpedVersion, exact, logger);
1189
+ if (updated) {
1190
+ logger.debug(styleText6("dim", `Updated dependency '${packageName}' in '${dependent.name}'.`));
1191
+ }
1192
+ });
1193
+ }
1194
+ await runAsync(dependentWriteTasks, dependentWriteConcurrency);
1195
+ await runBumpPackageHooks(bump, [sourceBump], bumpGroups, logger);
1196
+ }
1197
+ await runBumpReadyHooks(bump, bumpGroups, logger);
1198
+ };
1199
+
1200
+ // packages/core/src/lib/package/functions/load-packages.ts
1201
+ import { styleText as styleText7 } from "util";
1202
+ import { normalisePath as normalisePath2 } from "@package-pal/util";
1203
+ var loadPackages = async (rootDir, packagePatterns, adapter, logger) => {
1204
+ let resolvedPatterns = packagePatterns;
1205
+ if (packagePatterns.length === 1 && packagePatterns[0] === "packages/*") {
1206
+ resolvedPatterns = adapter.defaultPatterns;
1207
+ }
1208
+ const patternContent = resolvedPatterns.map((pattern) => `'${pattern}'`).join(", ");
1209
+ logger.debug(styleText7("dim", `Loading packages matching pattern/s ${patternContent}...${rootDir ? ` from ${rootDir}` : ""}`));
1210
+ const packages = [];
1211
+ const seenByName = new Map;
1212
+ for await (const packageData of adapter.scanPackages(Array.from(new Set(resolvedPatterns)), logger, rootDir)) {
1213
+ const normalizedPath = normalisePath2(packageData.path);
1214
+ const existingPath = seenByName.get(packageData.name);
1215
+ if (existingPath === normalizedPath) {
1216
+ continue;
1217
+ }
1218
+ if (existingPath) {
1219
+ const duplicatePaths = existingPath.localeCompare(normalizedPath) <= 0 ? [existingPath, normalizedPath] : [normalizedPath, existingPath];
1220
+ throw new Error(`Duplicate package name '${packageData.name}' found in multiple manifests: '${duplicatePaths[0]}' and '${duplicatePaths[1]}'.`);
1221
+ }
1222
+ seenByName.set(packageData.name, normalizedPath);
1223
+ packages.push(packageData);
1224
+ }
1225
+ if (!packages.length) {
1226
+ throw new Error(`No packages found for pattern/s ${patternContent}.`);
1227
+ }
1228
+ return packages.sort((a, b) => a.name.localeCompare(b.name) || normalisePath2(a.path).localeCompare(normalisePath2(b.path)));
1229
+ };
1230
+
1014
1231
  // packages/core/src/lib/package/functions/run-for-each-package.ts
1232
+ import { dirname as dirname5 } from "path";
1233
+ import {
1234
+ assertDefined as assertDefined8,
1235
+ runAsync as runAsync2
1236
+ } from "@package-pal/util";
1015
1237
  var runForEachPackage = async (packageGraphs, packageOrder, getCommand, logger, topological = true, concurrency) => {
1016
1238
  const controller = new AbortController;
1017
1239
  let processPackageOrder = packageOrder.circular.length > 0 ? packageOrder.groups.concat([packageOrder.circular]) : packageOrder.groups;
@@ -1019,13 +1241,13 @@ var runForEachPackage = async (packageGraphs, packageOrder, getCommand, logger,
1019
1241
  processPackageOrder = [processPackageOrder.flat()];
1020
1242
  }
1021
1243
  for (const group of processPackageOrder) {
1022
- await runAsync(group.map((packageName) => async () => {
1244
+ await runAsync2(group.map((packageName) => async () => {
1023
1245
  const packageNode = assertDefined8(packageGraphs.dependencies.get(packageName));
1024
1246
  const processPackageProps = {
1025
1247
  name: packageName,
1026
1248
  dir: packageNode.packageData.dir
1027
1249
  };
1028
- const processPackageCwd = dirname4(packageNode.packageData.path);
1250
+ const processPackageCwd = dirname5(packageNode.packageData.path);
1029
1251
  const shellCommand = await getCommand(processPackageProps);
1030
1252
  if (!shellCommand) {
1031
1253
  return;
@@ -1054,19 +1276,18 @@ import {
1054
1276
  watch
1055
1277
  } from "fs";
1056
1278
  import {
1057
- dirname as dirname6,
1279
+ dirname as dirname7,
1058
1280
  join as join3
1059
1281
  } from "path";
1060
1282
  import { styleText as styleText9 } from "util";
1061
1283
  import {
1062
- assertDefined as assertDefined12,
1284
+ assertDefined as assertDefined11,
1063
1285
  getDeferredPromise,
1064
1286
  getStringMatcher,
1065
1287
  isDefined as isDefined4,
1066
- normalisePath,
1067
- runAsync as runAsync3
1288
+ normalisePath as normalisePath3,
1289
+ runAsync as runAsync4
1068
1290
  } from "@package-pal/util";
1069
- var {Glob } = globalThis.Bun;
1070
1291
 
1071
1292
  // packages/core/src/lib/graph/functions/merge-graphs.ts
1072
1293
  var mergeGraphs = (a, b) => {
@@ -1101,48 +1322,40 @@ var DedupePathsBy = {
1101
1322
 
1102
1323
  // packages/core/src/lib/watch/functions/dedupe-shared-paths.ts
1103
1324
  import { sep } from "path";
1104
- import { assertDefined as assertDefined9 } from "@package-pal/util";
1325
+ var isStrictDescendant = (path, candidateParent) => path.startsWith(candidateParent + sep);
1105
1326
  var dedupeSharedPaths = (paths, by) => {
1106
- const mapped = paths.map((path) => {
1107
- let count = 0;
1108
- for (const char of path) {
1109
- if (char === sep) {
1110
- count++;
1111
- }
1112
- }
1113
- return {
1114
- path,
1115
- count
1116
- };
1117
- });
1118
- mapped.sort((a, b) => a.count - b.count);
1119
- const sorted = mapped.map((item) => item.path);
1120
- const deduped = [];
1327
+ const sortedUniquePaths = Array.from(new Set(paths)).sort((a, b) => a.localeCompare(b));
1121
1328
  if (by === DedupePathsBy.Parent) {
1122
- for (const path of sorted) {
1123
- if (!deduped.some((base) => path.startsWith(base + sep))) {
1124
- deduped.push(path);
1329
+ const deduped2 = [];
1330
+ let lastKept2;
1331
+ for (const path of sortedUniquePaths) {
1332
+ if (!lastKept2 || !isStrictDescendant(path, lastKept2)) {
1333
+ deduped2.push(path);
1334
+ lastKept2 = path;
1125
1335
  }
1126
1336
  }
1127
- return deduped;
1337
+ return deduped2;
1128
1338
  }
1129
- for (const path of sorted) {
1130
- for (let i = deduped.length - 1;i >= 0; i--) {
1131
- const base = assertDefined9(deduped[i]);
1132
- if (path.startsWith(base + sep)) {
1133
- deduped.splice(i, 1);
1134
- }
1339
+ const deduped = [];
1340
+ let lastKept;
1341
+ for (let i = sortedUniquePaths.length - 1;i >= 0; i--) {
1342
+ const path = sortedUniquePaths[i];
1343
+ if (!path) {
1344
+ continue;
1135
1345
  }
1136
- if (!deduped.some((base) => base.startsWith(path + sep))) {
1346
+ if (!lastKept || !isStrictDescendant(lastKept, path)) {
1137
1347
  deduped.push(path);
1348
+ lastKept = path;
1138
1349
  }
1139
1350
  }
1140
- return Array.from(new Set(deduped));
1351
+ deduped.reverse();
1352
+ return deduped;
1141
1353
  };
1142
1354
 
1143
1355
  // packages/core/src/lib/watch/functions/filter-files-modified-since.ts
1144
1356
  import { stat } from "fs/promises";
1145
- import { runAsync as runAsync2 } from "@package-pal/util";
1357
+ import { runAsync as runAsync3 } from "@package-pal/util";
1358
+ var fileStatConcurrency = 20;
1146
1359
  var filterFilesModifiedSince = async (paths, sinceMs) => {
1147
1360
  const tasks = paths.map((path) => async () => {
1148
1361
  try {
@@ -1153,13 +1366,13 @@ var filterFilesModifiedSince = async (paths, sinceMs) => {
1153
1366
  return path;
1154
1367
  }
1155
1368
  });
1156
- const results = await runAsync2(tasks, 20);
1369
+ const results = await runAsync3(tasks, fileStatConcurrency);
1157
1370
  return results.filter((path) => path !== null);
1158
1371
  };
1159
1372
 
1160
1373
  // packages/core/src/lib/watch/functions/get-change-logic.ts
1161
1374
  import { styleText as styleText8 } from "util";
1162
- import { assertDefined as assertDefined11 } from "@package-pal/util";
1375
+ import { assertDefined as assertDefined10 } from "@package-pal/util";
1163
1376
 
1164
1377
  // packages/core/src/lib/graph/functions/generate-topological-ranking-range.ts
1165
1378
  import { isDefined as isDefined3 } from "@package-pal/util";
@@ -1185,11 +1398,11 @@ var generateTopologicalRankingRange = (graph, ranking) => {
1185
1398
  };
1186
1399
 
1187
1400
  // packages/core/src/lib/graph/functions/generate-topological-ranking.ts
1188
- import { assertDefined as assertDefined10 } from "@package-pal/util";
1401
+ import { assertDefined as assertDefined9 } from "@package-pal/util";
1189
1402
  var generateTopologicalRanking = (packageProcessOrder) => {
1190
1403
  const rankMap = new Map;
1191
1404
  for (let i = 0;i < packageProcessOrder.length; i++) {
1192
- for (const packageName of assertDefined10(packageProcessOrder[i])) {
1405
+ for (const packageName of assertDefined9(packageProcessOrder[i])) {
1193
1406
  rankMap.set(packageName, i);
1194
1407
  }
1195
1408
  }
@@ -1285,9 +1498,9 @@ var getChangeLogic = (packageGraphs, packageChanges, lastProcessedSubgraph, conf
1285
1498
  action = ChangeAction.Partial;
1286
1499
  }
1287
1500
  if (action === ChangeAction.Partial && isRankedGreaterThanOrEqualToPrevious) {
1288
- const [prevMinRank] = generateTopologicalRankingRange(assertDefined11(lastProcessedSubgraph), packageRankings);
1501
+ const [prevMinRank] = generateTopologicalRankingRange(assertDefined10(lastProcessedSubgraph), packageRankings);
1289
1502
  for (let i = 0;i < changedPackageProcessOrder.length; i++) {
1290
- changedPackageProcessOrder[i] = assertDefined11(changedPackageProcessOrder[i]).filter((packageName) => {
1503
+ changedPackageProcessOrder[i] = assertDefined10(changedPackageProcessOrder[i]).filter((packageName) => {
1291
1504
  const rank = packageRankings.get(packageName);
1292
1505
  return rank !== undefined && rank >= prevMinRank;
1293
1506
  });
@@ -1304,7 +1517,7 @@ var getChangeLogic = (packageGraphs, packageChanges, lastProcessedSubgraph, conf
1304
1517
  // packages/core/src/lib/watch/functions/normalise-watched-file-path.ts
1305
1518
  import {
1306
1519
  basename as basename3,
1307
- dirname as dirname5,
1520
+ dirname as dirname6,
1308
1521
  join as join2
1309
1522
  } from "path";
1310
1523
  var removeTrailing = [
@@ -1318,7 +1531,7 @@ var removeTrailing = [
1318
1531
  ".swn"
1319
1532
  ];
1320
1533
  var normaliseWatchedFilePath = (filePath) => {
1321
- const dir = dirname5(filePath);
1534
+ const dir = dirname6(filePath);
1322
1535
  let base = basename3(filePath);
1323
1536
  const baseLower = base.toLowerCase();
1324
1537
  for (const trailing of removeTrailing) {
@@ -1356,8 +1569,8 @@ var onProcessPackage = async (packageGraphs, packageChanges, watchConfig, determ
1356
1569
  state.lastProcessedSubgraph = state.lastProcessedSubgraph && !isRestart ? mergeGraphs(state.lastProcessedSubgraph, changedPackageSubgraph) : changedPackageSubgraph;
1357
1570
  }
1358
1571
  for (const group of changedPackageProcessOrder) {
1359
- await runAsync3(group.map((packageName) => async () => {
1360
- const packageNode = assertDefined12(packageGraphs.dependencies.get(packageName));
1572
+ await runAsync4(group.map((packageName) => async () => {
1573
+ const packageNode = assertDefined11(packageGraphs.dependencies.get(packageName));
1361
1574
  const changedPaths = packageChanges.get(packageName) ?? [];
1362
1575
  const processPackageProps = {
1363
1576
  name: packageName,
@@ -1367,13 +1580,18 @@ var onProcessPackage = async (packageGraphs, packageChanges, watchConfig, determ
1367
1580
  totalProcessOrder: changedPackageProcessOrder,
1368
1581
  signal: controller.signal
1369
1582
  };
1370
- const processPackageCwd = dirname6(packageNode.packageData.path);
1583
+ const processPackageCwd = dirname7(packageNode.packageData.path);
1584
+ const processPackageEnv = {
1585
+ PP_PACKAGE_NAME: packageName,
1586
+ PP_PACKAGE_DIR: processPackageProps.dir
1587
+ };
1371
1588
  const beforeProcessPackageShellCommand = await watchConfig.hooks.onBeforeProcessPackage(processPackageProps);
1372
1589
  if (beforeProcessPackageShellCommand) {
1373
1590
  await runSubprocess({
1374
1591
  debugName: `before process ${packageName}`,
1375
1592
  shellCommand: beforeProcessPackageShellCommand,
1376
1593
  cwd: processPackageCwd,
1594
+ env: processPackageEnv,
1377
1595
  signal: controller.signal,
1378
1596
  logger
1379
1597
  });
@@ -1394,6 +1612,7 @@ var onProcessPackage = async (packageGraphs, packageChanges, watchConfig, determ
1394
1612
  debugName: `process ${packageName}`,
1395
1613
  shellCommand: processPackageShellCommand,
1396
1614
  cwd: processPackageCwd,
1615
+ env: processPackageEnv,
1397
1616
  signal: controller.signal,
1398
1617
  logger,
1399
1618
  onStdChunk: (chunk) => {
@@ -1419,6 +1638,7 @@ var onProcessPackage = async (packageGraphs, packageChanges, watchConfig, determ
1419
1638
  debugName: `after process ${packageName}`,
1420
1639
  shellCommand: processPackageErrorCommand,
1421
1640
  cwd: processPackageCwd,
1641
+ env: processPackageEnv,
1422
1642
  signal: controller.signal,
1423
1643
  logger
1424
1644
  });
@@ -1443,6 +1663,7 @@ var onProcessPackage = async (packageGraphs, packageChanges, watchConfig, determ
1443
1663
  debugName: `after process ${packageName}`,
1444
1664
  shellCommand: afterProcessPackageShellCommand,
1445
1665
  cwd: processPackageCwd,
1666
+ env: processPackageEnv,
1446
1667
  signal: controller.signal,
1447
1668
  logger
1448
1669
  });
@@ -1485,14 +1706,15 @@ var onProcessPackage = async (packageGraphs, packageChanges, watchConfig, determ
1485
1706
  }
1486
1707
  };
1487
1708
  var watchPackageChanges = (packageData, packageGraphs, watchConfig, rootDir, logger) => {
1488
- const dedupedRootPackageData = dedupeSharedPaths(packageData.map((packageData2) => packageData2.path), DedupePathsBy.Parent).map((packagePath) => assertDefined12(packageData.find((data) => data.path === packagePath)));
1709
+ const packageDataByPath = new Map(packageData.map((data) => [data.path, data]));
1710
+ const dedupedRootPackageData = dedupeSharedPaths(Array.from(packageDataByPath.keys()), DedupePathsBy.Parent).map((packagePath) => assertDefined11(packageDataByPath.get(packagePath)));
1489
1711
  logger.debug(styleText9("dim", `Starting ${dedupedRootPackageData.length.toString()} watchers for ${packageData.length.toString()} packages.`));
1490
1712
  let closed = false;
1491
1713
  const state = { lastProcessedSubgraph: undefined };
1492
1714
  let debounceTimeout;
1493
1715
  let startedDebounceMs;
1494
1716
  let controller;
1495
- const ignoreGlobs = watchConfig.ignore ? (Array.isArray(watchConfig.ignore) ? watchConfig.ignore : [watchConfig.ignore]).map((pattern) => new Glob(pattern)) : undefined;
1717
+ const ignoreGlobs = watchConfig.ignore ? getIgnoreGlobs(watchConfig.ignore) : undefined;
1496
1718
  const changedPackagePaths = new Map;
1497
1719
  const useController = (reset) => {
1498
1720
  if (controller && (reset || controller.signal.aborted)) {
@@ -1515,7 +1737,7 @@ var watchPackageChanges = (packageData, packageGraphs, watchConfig, rootDir, log
1515
1737
  startedDebounceMs = Date.now();
1516
1738
  }
1517
1739
  if (packageName && watchPath && filePath) {
1518
- const changedPath = normalisePath(join3(watchPath, normaliseWatchedFilePath(filePath)));
1740
+ const changedPath = normalisePath3(join3(watchPath, normaliseWatchedFilePath(filePath)));
1519
1741
  if (ignoreGlobs?.some((glob) => glob.match(changedPath))) {
1520
1742
  logger.debug(styleText9("dim", `Ignoring change '${changedPath}' (matched ignore pattern).`));
1521
1743
  return;
@@ -1540,7 +1762,7 @@ var watchPackageChanges = (packageData, packageGraphs, watchConfig, rootDir, log
1540
1762
  const packageChanges = new Map;
1541
1763
  for (const [packageName2, paths] of changedPackagePaths) {
1542
1764
  const dedupedPaths = dedupeSharedPaths(Array.from(paths), DedupePathsBy.Child).sort();
1543
- const processedPaths = await filterFilesModifiedSince(dedupedPaths, assertDefined12(startedDebounceMs) - fileModifiedThresholdMs);
1765
+ const processedPaths = await filterFilesModifiedSince(dedupedPaths, assertDefined11(startedDebounceMs) - fileModifiedThresholdMs);
1544
1766
  if (processedPaths.length) {
1545
1767
  packageChanges.set(packageName2, processedPaths);
1546
1768
  }
@@ -1558,7 +1780,7 @@ var watchPackageChanges = (packageData, packageGraphs, watchConfig, rootDir, log
1558
1780
  name,
1559
1781
  path
1560
1782
  }) => {
1561
- const watchPath = dirname6(path);
1783
+ const watchPath = dirname7(path);
1562
1784
  return watch(watchPath, { recursive: true }, (event, filePath) => {
1563
1785
  onWatchEvent({
1564
1786
  watchPath,
@@ -1652,5 +1874,5 @@ export {
1652
1874
  BumpVersionType
1653
1875
  };
1654
1876
 
1655
- //# debugId=C18A12C7802A030C64756E2164756E21
1877
+ //# debugId=D8A98DEC7186B6BF64756E2164756E21
1656
1878
  //# sourceMappingURL=index.js.map