@eldrforge/kodrdriv 1.2.4 → 1.2.5
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/commands/publish.js +129 -28
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/tree.js +94 -25
- package/dist/commands/tree.js.map +1 -1
- package/dist/constants.js +1 -1
- package/package.json +1 -1
package/dist/commands/tree.js
CHANGED
|
@@ -114,6 +114,11 @@ const updateInterProjectDependencies = async (packageDir, publishedVersions, all
|
|
|
114
114
|
];
|
|
115
115
|
for (const publishedVersion of publishedVersions){
|
|
116
116
|
const { packageName, version } = publishedVersion;
|
|
117
|
+
// Do not propagate prerelease versions to consumers (often not available on registry)
|
|
118
|
+
if (typeof version === 'string' && version.includes('-')) {
|
|
119
|
+
packageLogger.verbose(`Skipping prerelease version for ${packageName}: ${version}`);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
117
122
|
// Only update if this is an inter-project dependency (exists in our build tree)
|
|
118
123
|
if (!allPackageNames.has(packageName)) {
|
|
119
124
|
continue;
|
|
@@ -592,6 +597,7 @@ const executePackage = async (packageName, packageInfo, commandToRun, runConfig,
|
|
|
592
597
|
}
|
|
593
598
|
// For built-in commands, shell out to a separate kodrdriv process
|
|
594
599
|
// This preserves individual project configurations
|
|
600
|
+
let publishWasSkipped;
|
|
595
601
|
if (isBuiltInCommand) {
|
|
596
602
|
// Extract the command name from "kodrdriv <command>"
|
|
597
603
|
const builtInCommandName = commandToRun.replace('kodrdriv ', '');
|
|
@@ -601,28 +607,39 @@ const executePackage = async (packageName, packageInfo, commandToRun, runConfig,
|
|
|
601
607
|
// Ensure dry-run propagates to subprocess even during overall dry-run mode
|
|
602
608
|
const effectiveCommand = runConfig.dryRun && !commandToRun.includes('--dry-run') ? `${commandToRun} --dry-run` : commandToRun;
|
|
603
609
|
// Use runWithLogging for built-in commands to capture all output
|
|
604
|
-
await runWithLogging(effectiveCommand, packageLogger, {}, showOutput);
|
|
610
|
+
const { stdout } = await runWithLogging(effectiveCommand, packageLogger, {}, showOutput);
|
|
611
|
+
// Detect explicit skip marker from publish to avoid propagating versions
|
|
612
|
+
if (builtInCommandName === 'publish' && stdout && stdout.includes('KODRDRIV_PUBLISH_SKIPPED')) {
|
|
613
|
+
packageLogger.info('Publish skipped for this package; will not record or propagate a version.');
|
|
614
|
+
publishWasSkipped = true;
|
|
615
|
+
}
|
|
605
616
|
} else {
|
|
606
617
|
// For custom commands, use the existing logic
|
|
607
618
|
await runWithLogging(commandToRun, packageLogger, {}, showOutput);
|
|
608
619
|
}
|
|
609
620
|
// Track published version after successful publish (skip during dry run)
|
|
610
621
|
if (!isDryRun && isBuiltInCommand && commandToRun.includes('publish')) {
|
|
611
|
-
|
|
612
|
-
if (
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
622
|
+
// If publish was skipped, do not record a version
|
|
623
|
+
if (publishWasSkipped) {
|
|
624
|
+
packageLogger.verbose('Skipping version tracking due to earlier skip.');
|
|
625
|
+
} else {
|
|
626
|
+
// Only record a published version if a new tag exists (avoid recording for skipped publishes)
|
|
627
|
+
const publishedVersion = await extractPublishedVersion(packageDir, packageLogger);
|
|
628
|
+
if (publishedVersion) {
|
|
629
|
+
let mutexLocked = false;
|
|
630
|
+
try {
|
|
631
|
+
await globalStateMutex.lock();
|
|
632
|
+
mutexLocked = true;
|
|
633
|
+
publishedVersions.push(publishedVersion);
|
|
634
|
+
packageLogger.info(`Tracked published version: ${publishedVersion.packageName}@${publishedVersion.version}`);
|
|
623
635
|
globalStateMutex.unlock();
|
|
636
|
+
mutexLocked = false;
|
|
637
|
+
} catch (error) {
|
|
638
|
+
if (mutexLocked) {
|
|
639
|
+
globalStateMutex.unlock();
|
|
640
|
+
}
|
|
641
|
+
throw error;
|
|
624
642
|
}
|
|
625
|
-
throw error;
|
|
626
643
|
}
|
|
627
644
|
}
|
|
628
645
|
}
|
|
@@ -802,13 +819,16 @@ const execute = async (runConfig)=>{
|
|
|
802
819
|
const startFrom = (_runConfig_tree6 = runConfig.tree) === null || _runConfig_tree6 === void 0 ? void 0 : _runConfig_tree6.startFrom;
|
|
803
820
|
if (startFrom) {
|
|
804
821
|
logger.verbose(`${isDryRun ? 'DRY RUN: ' : ''}Looking for start package: ${startFrom}`);
|
|
805
|
-
//
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
const dirName = path__default.basename(
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
822
|
+
// Resolve the actual package name (can be package name or directory name)
|
|
823
|
+
let startPackageName = null;
|
|
824
|
+
for (const [pkgName, pkgInfo] of dependencyGraph.packages){
|
|
825
|
+
const dirName = path__default.basename(pkgInfo.path);
|
|
826
|
+
if (dirName === startFrom || pkgName === startFrom) {
|
|
827
|
+
startPackageName = pkgName;
|
|
828
|
+
break;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
if (!startPackageName) {
|
|
812
832
|
// Check if the package exists but was excluded across all directories
|
|
813
833
|
let allPackageJsonPathsForCheck = [];
|
|
814
834
|
for (const targetDirectory of directories){
|
|
@@ -842,11 +862,60 @@ const execute = async (runConfig)=>{
|
|
|
842
862
|
throw new Error(`Package directory '${startFrom}' not found. Available packages: ${availablePackages}`);
|
|
843
863
|
}
|
|
844
864
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
865
|
+
// Build reverse dependency map (who depends on whom)
|
|
866
|
+
const reverseEdges = new Map();
|
|
867
|
+
for (const [pkg, deps] of dependencyGraph.edges){
|
|
868
|
+
for (const dep of deps){
|
|
869
|
+
if (!reverseEdges.has(dep)) reverseEdges.set(dep, new Set());
|
|
870
|
+
reverseEdges.get(dep).add(pkg);
|
|
871
|
+
}
|
|
872
|
+
if (!reverseEdges.has(pkg)) reverseEdges.set(pkg, new Set());
|
|
873
|
+
}
|
|
874
|
+
// Step 1: collect the start package and all its transitive dependents (consumers)
|
|
875
|
+
const dependentsClosure = new Set();
|
|
876
|
+
const queueDependents = [
|
|
877
|
+
startPackageName
|
|
878
|
+
];
|
|
879
|
+
while(queueDependents.length > 0){
|
|
880
|
+
const current = queueDependents.shift();
|
|
881
|
+
if (dependentsClosure.has(current)) continue;
|
|
882
|
+
dependentsClosure.add(current);
|
|
883
|
+
const consumers = reverseEdges.get(current) || new Set();
|
|
884
|
+
for (const consumer of consumers){
|
|
885
|
+
if (!dependentsClosure.has(consumer)) queueDependents.push(consumer);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
// Step 2: expand to include all forward dependencies required to build those packages
|
|
889
|
+
const relevantPackages = new Set(dependentsClosure);
|
|
890
|
+
const queueDependencies = Array.from(relevantPackages);
|
|
891
|
+
while(queueDependencies.length > 0){
|
|
892
|
+
const current = queueDependencies.shift();
|
|
893
|
+
const deps = dependencyGraph.edges.get(current) || new Set();
|
|
894
|
+
for (const dep of deps){
|
|
895
|
+
if (!relevantPackages.has(dep)) {
|
|
896
|
+
relevantPackages.add(dep);
|
|
897
|
+
queueDependencies.push(dep);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
// Filter graph to only relevant packages
|
|
902
|
+
const filteredGraph = {
|
|
903
|
+
packages: new Map(),
|
|
904
|
+
edges: new Map()
|
|
905
|
+
};
|
|
906
|
+
for (const pkgName of relevantPackages){
|
|
907
|
+
const info = dependencyGraph.packages.get(pkgName);
|
|
908
|
+
filteredGraph.packages.set(pkgName, info);
|
|
909
|
+
const deps = dependencyGraph.edges.get(pkgName) || new Set();
|
|
910
|
+
const filteredDeps = new Set();
|
|
911
|
+
for (const dep of deps){
|
|
912
|
+
if (relevantPackages.has(dep)) filteredDeps.add(dep);
|
|
913
|
+
}
|
|
914
|
+
filteredGraph.edges.set(pkgName, filteredDeps);
|
|
849
915
|
}
|
|
916
|
+
// Recompute build order for the filtered subgraph
|
|
917
|
+
buildOrder = topologicalSort(filteredGraph);
|
|
918
|
+
logger.info(`${isDryRun ? 'DRY RUN: ' : ''}Limiting scope to '${startFrom}' and its dependencies (${buildOrder.length} package${buildOrder.length === 1 ? '' : 's'}).`);
|
|
850
919
|
}
|
|
851
920
|
// Handle stop-at functionality if specified
|
|
852
921
|
const stopAt = (_runConfig_tree7 = runConfig.tree) === null || _runConfig_tree7 === void 0 ? void 0 : _runConfig_tree7.stopAt;
|