package-versioner 0.5.3 → 0.6.0
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/README.md +20 -2
- package/dist/index.cjs +410 -156
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +397 -156
- package/docs/VERSIONING_STRATEGIES.md +30 -1
- package/package.json +10 -8
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
+
import * as fs7 from "node:fs";
|
|
5
|
+
import path5 from "node:path";
|
|
4
6
|
import { Command } from "commander";
|
|
5
7
|
|
|
6
8
|
// src/config.ts
|
|
@@ -117,9 +119,13 @@ function printJsonOutput() {
|
|
|
117
119
|
}
|
|
118
120
|
|
|
119
121
|
// src/utils/logging.ts
|
|
120
|
-
function log(message,
|
|
122
|
+
function log(message, level = "info") {
|
|
123
|
+
const showDebug = process.env.DEBUG === "true" || process.env.DEBUG === "1";
|
|
124
|
+
if (level === "debug" && !showDebug) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
121
127
|
let chalkFn;
|
|
122
|
-
switch (
|
|
128
|
+
switch (level) {
|
|
123
129
|
case "success":
|
|
124
130
|
chalkFn = chalk.green;
|
|
125
131
|
break;
|
|
@@ -136,22 +142,23 @@ function log(message, status = "info") {
|
|
|
136
142
|
chalkFn = chalk.blue;
|
|
137
143
|
}
|
|
138
144
|
if (isJsonOutputMode()) {
|
|
139
|
-
if (
|
|
145
|
+
if (level === "error") {
|
|
140
146
|
chalkFn(message);
|
|
141
147
|
console.error(message);
|
|
142
148
|
}
|
|
143
149
|
return;
|
|
144
150
|
}
|
|
145
|
-
|
|
146
|
-
|
|
151
|
+
const formattedMessage = level === "debug" ? `[DEBUG] ${message}` : message;
|
|
152
|
+
if (level === "error") {
|
|
153
|
+
console.error(chalkFn(formattedMessage));
|
|
147
154
|
} else {
|
|
148
|
-
console.log(chalkFn(
|
|
155
|
+
console.log(chalkFn(formattedMessage));
|
|
149
156
|
}
|
|
150
157
|
}
|
|
151
158
|
|
|
152
159
|
// src/core/versionStrategies.ts
|
|
153
|
-
import
|
|
154
|
-
import * as
|
|
160
|
+
import fs6 from "node:fs";
|
|
161
|
+
import * as path4 from "node:path";
|
|
155
162
|
|
|
156
163
|
// src/git/commands.ts
|
|
157
164
|
import { cwd as cwd2 } from "node:process";
|
|
@@ -374,11 +381,53 @@ async function lastMergeBranchName(branches, baseBranch) {
|
|
|
374
381
|
}
|
|
375
382
|
async function getLatestTagForPackage(packageName, versionPrefix) {
|
|
376
383
|
try {
|
|
384
|
+
const escapedPackageName = escapeRegExp(packageName);
|
|
385
|
+
log(
|
|
386
|
+
`Looking for tags for package ${packageName} with prefix ${versionPrefix || "none"}`,
|
|
387
|
+
"debug"
|
|
388
|
+
);
|
|
377
389
|
const allTags = await getSemverTags({
|
|
378
390
|
tagPrefix: versionPrefix
|
|
379
391
|
});
|
|
380
|
-
|
|
381
|
-
|
|
392
|
+
log(`Retrieved ${allTags.length} tags: ${allTags.join(", ")}`, "debug");
|
|
393
|
+
let packageTags = [];
|
|
394
|
+
if (versionPrefix) {
|
|
395
|
+
const pattern1 = new RegExp(`^${escapedPackageName}@${escapeRegExp(versionPrefix)}`);
|
|
396
|
+
packageTags = allTags.filter((tag) => pattern1.test(tag));
|
|
397
|
+
if (packageTags.length > 0) {
|
|
398
|
+
log(
|
|
399
|
+
`Found ${packageTags.length} package tags using pattern: packageName@${versionPrefix}...`,
|
|
400
|
+
"debug"
|
|
401
|
+
);
|
|
402
|
+
log(`Using tag: ${packageTags[0]}`, "debug");
|
|
403
|
+
return packageTags[0];
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (versionPrefix) {
|
|
407
|
+
const pattern2 = new RegExp(`^${escapeRegExp(versionPrefix)}${escapedPackageName}@`);
|
|
408
|
+
packageTags = allTags.filter((tag) => pattern2.test(tag));
|
|
409
|
+
if (packageTags.length > 0) {
|
|
410
|
+
log(
|
|
411
|
+
`Found ${packageTags.length} package tags using pattern: ${versionPrefix}packageName@...`,
|
|
412
|
+
"debug"
|
|
413
|
+
);
|
|
414
|
+
log(`Using tag: ${packageTags[0]}`, "debug");
|
|
415
|
+
return packageTags[0];
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
const pattern3 = new RegExp(`^${escapedPackageName}@`);
|
|
419
|
+
packageTags = allTags.filter((tag) => pattern3.test(tag));
|
|
420
|
+
log(`Found ${packageTags.length} package tags for ${packageName}`, "debug");
|
|
421
|
+
if (packageTags.length === 0) {
|
|
422
|
+
log("No matching tags found for pattern: packageName@version", "debug");
|
|
423
|
+
if (allTags.length > 0) {
|
|
424
|
+
log(`Available tags: ${allTags.join(", ")}`, "debug");
|
|
425
|
+
} else {
|
|
426
|
+
log("No tags available in the repository", "debug");
|
|
427
|
+
}
|
|
428
|
+
} else {
|
|
429
|
+
log(`Using tag: ${packageTags[0]}`, "debug");
|
|
430
|
+
}
|
|
382
431
|
return packageTags[0] || "";
|
|
383
432
|
} catch (error) {
|
|
384
433
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -391,14 +440,83 @@ async function getLatestTagForPackage(packageName, versionPrefix) {
|
|
|
391
440
|
}
|
|
392
441
|
|
|
393
442
|
// src/package/packageManagement.ts
|
|
443
|
+
import fs3 from "node:fs";
|
|
444
|
+
|
|
445
|
+
// src/cargo/cargoHandler.ts
|
|
394
446
|
import fs2 from "node:fs";
|
|
447
|
+
import path from "node:path";
|
|
448
|
+
import * as TOML from "smol-toml";
|
|
449
|
+
function getCargoInfo(cargoPath) {
|
|
450
|
+
var _a;
|
|
451
|
+
if (!fs2.existsSync(cargoPath)) {
|
|
452
|
+
log(`Cargo.toml file not found at: ${cargoPath}`, "error");
|
|
453
|
+
throw new Error(`Cargo.toml file not found at: ${cargoPath}`);
|
|
454
|
+
}
|
|
455
|
+
try {
|
|
456
|
+
const fileContent = fs2.readFileSync(cargoPath, "utf8");
|
|
457
|
+
const cargo = TOML.parse(fileContent);
|
|
458
|
+
if (!((_a = cargo.package) == null ? void 0 : _a.name)) {
|
|
459
|
+
log(`Package name not found in: ${cargoPath}`, "error");
|
|
460
|
+
throw new Error(`Package name not found in: ${cargoPath}`);
|
|
461
|
+
}
|
|
462
|
+
return {
|
|
463
|
+
name: cargo.package.name,
|
|
464
|
+
version: cargo.package.version || "0.0.0",
|
|
465
|
+
path: cargoPath,
|
|
466
|
+
dir: path.dirname(cargoPath),
|
|
467
|
+
content: cargo
|
|
468
|
+
};
|
|
469
|
+
} catch (error) {
|
|
470
|
+
log(`Error reading Cargo.toml: ${cargoPath}`, "error");
|
|
471
|
+
if (error instanceof Error) {
|
|
472
|
+
log(error.message, "error");
|
|
473
|
+
throw error;
|
|
474
|
+
}
|
|
475
|
+
throw new Error(`Failed to process Cargo.toml at ${cargoPath}`);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
function isCargoToml(filePath) {
|
|
479
|
+
return path.basename(filePath) === "Cargo.toml";
|
|
480
|
+
}
|
|
481
|
+
function updateCargoVersion(cargoPath, version) {
|
|
482
|
+
var _a;
|
|
483
|
+
try {
|
|
484
|
+
const originalContent = fs2.readFileSync(cargoPath, "utf8");
|
|
485
|
+
const cargo = TOML.parse(originalContent);
|
|
486
|
+
const packageName = (_a = cargo.package) == null ? void 0 : _a.name;
|
|
487
|
+
if (!packageName) {
|
|
488
|
+
throw new Error(`No package name found in ${cargoPath}`);
|
|
489
|
+
}
|
|
490
|
+
if (!cargo.package) {
|
|
491
|
+
cargo.package = { name: packageName, version };
|
|
492
|
+
} else {
|
|
493
|
+
cargo.package.version = version;
|
|
494
|
+
}
|
|
495
|
+
const updatedContent = TOML.stringify(cargo);
|
|
496
|
+
fs2.writeFileSync(cargoPath, updatedContent);
|
|
497
|
+
addPackageUpdate(packageName, version, cargoPath);
|
|
498
|
+
log(`Updated Cargo.toml at ${cargoPath} to version ${version}`, "success");
|
|
499
|
+
} catch (error) {
|
|
500
|
+
log(`Failed to update Cargo.toml at ${cargoPath}`, "error");
|
|
501
|
+
if (error instanceof Error) {
|
|
502
|
+
log(error.message, "error");
|
|
503
|
+
}
|
|
504
|
+
throw error;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// src/package/packageManagement.ts
|
|
395
509
|
function updatePackageVersion(packagePath, version) {
|
|
510
|
+
if (isCargoToml(packagePath)) {
|
|
511
|
+
updateCargoVersion(packagePath, version);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
396
514
|
try {
|
|
397
|
-
const packageContent =
|
|
515
|
+
const packageContent = fs3.readFileSync(packagePath, "utf8");
|
|
398
516
|
const packageJson = JSON.parse(packageContent);
|
|
399
517
|
const packageName = packageJson.name;
|
|
400
518
|
packageJson.version = version;
|
|
401
|
-
|
|
519
|
+
fs3.writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}
|
|
402
520
|
`);
|
|
403
521
|
addPackageUpdate(packageName, version, packagePath);
|
|
404
522
|
log(`Updated package.json at ${packagePath} to version ${version}`, "success");
|
|
@@ -412,124 +530,217 @@ function updatePackageVersion(packagePath, version) {
|
|
|
412
530
|
}
|
|
413
531
|
|
|
414
532
|
// src/package/packageProcessor.ts
|
|
415
|
-
import
|
|
533
|
+
import * as fs5 from "node:fs";
|
|
534
|
+
import path3 from "node:path";
|
|
416
535
|
import { exit } from "node:process";
|
|
417
536
|
|
|
418
537
|
// src/core/versionCalculator.ts
|
|
419
|
-
import * as fs3 from "node:fs";
|
|
420
|
-
import * as path from "node:path";
|
|
421
538
|
import { cwd as cwd3 } from "node:process";
|
|
422
539
|
import { Bumper } from "conventional-recommended-bump";
|
|
423
|
-
import
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
const
|
|
430
|
-
const
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
540
|
+
import semver2 from "semver";
|
|
541
|
+
|
|
542
|
+
// src/utils/manifestHelpers.ts
|
|
543
|
+
import fs4 from "node:fs";
|
|
544
|
+
import path2 from "node:path";
|
|
545
|
+
function getVersionFromManifests(packageDir) {
|
|
546
|
+
const packageJsonPath = path2.join(packageDir, "package.json");
|
|
547
|
+
const cargoTomlPath = path2.join(packageDir, "Cargo.toml");
|
|
548
|
+
if (fs4.existsSync(packageJsonPath)) {
|
|
549
|
+
try {
|
|
550
|
+
const packageJson = JSON.parse(fs4.readFileSync(packageJsonPath, "utf-8"));
|
|
551
|
+
if (packageJson.version) {
|
|
552
|
+
log(`Found version ${packageJson.version} in package.json`, "debug");
|
|
553
|
+
return {
|
|
554
|
+
version: packageJson.version,
|
|
555
|
+
manifestFound: true,
|
|
556
|
+
manifestPath: packageJsonPath,
|
|
557
|
+
manifestType: "package.json"
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
log("No version field found in package.json", "debug");
|
|
561
|
+
} catch (packageJsonError) {
|
|
562
|
+
const errMsg = packageJsonError instanceof Error ? packageJsonError.message : String(packageJsonError);
|
|
563
|
+
log(`Error reading package.json: ${errMsg}`, "warning");
|
|
435
564
|
}
|
|
436
|
-
return prefix;
|
|
437
565
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
log(
|
|
455
|
-
`Cleaning prerelease identifier from ${currentVersion} for ${specifiedType} bump`,
|
|
456
|
-
"debug"
|
|
457
|
-
);
|
|
458
|
-
return bumpVersion(currentVersion, specifiedType, prereleaseIdentifier);
|
|
566
|
+
if (fs4.existsSync(cargoTomlPath)) {
|
|
567
|
+
try {
|
|
568
|
+
const cargoInfo = getCargoInfo(cargoTomlPath);
|
|
569
|
+
if (cargoInfo.version) {
|
|
570
|
+
log(`Found version ${cargoInfo.version} in Cargo.toml`, "debug");
|
|
571
|
+
return {
|
|
572
|
+
version: cargoInfo.version,
|
|
573
|
+
manifestFound: true,
|
|
574
|
+
manifestPath: cargoTomlPath,
|
|
575
|
+
manifestType: "Cargo.toml"
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
log("No version field found in Cargo.toml", "debug");
|
|
579
|
+
} catch (cargoTomlError) {
|
|
580
|
+
const errMsg = cargoTomlError instanceof Error ? cargoTomlError.message : String(cargoTomlError);
|
|
581
|
+
log(`Error reading Cargo.toml: ${errMsg}`, "warning");
|
|
459
582
|
}
|
|
460
|
-
return semver.inc(currentVersion, specifiedType, prereleaseIdentifier) || "";
|
|
461
583
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
584
|
+
return {
|
|
585
|
+
version: null,
|
|
586
|
+
manifestFound: false,
|
|
587
|
+
manifestPath: "",
|
|
588
|
+
manifestType: null
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
function throwIfNoManifestsFound(packageDir) {
|
|
592
|
+
const packageJsonPath = path2.join(packageDir, "package.json");
|
|
593
|
+
const cargoTomlPath = path2.join(packageDir, "Cargo.toml");
|
|
594
|
+
throw new Error(
|
|
595
|
+
`Neither package.json nor Cargo.toml found at ${packageDir}. Checked paths: ${packageJsonPath}, ${cargoTomlPath}. Cannot determine version.`
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// src/utils/versionUtils.ts
|
|
600
|
+
import semver from "semver";
|
|
601
|
+
import * as TOML2 from "smol-toml";
|
|
602
|
+
var STANDARD_BUMP_TYPES = ["major", "minor", "patch"];
|
|
603
|
+
function bumpVersion(currentVersion, bumpType, prereleaseIdentifier) {
|
|
604
|
+
if (semver.prerelease(currentVersion) && STANDARD_BUMP_TYPES.includes(bumpType)) {
|
|
605
|
+
const parsed = semver.parse(currentVersion);
|
|
606
|
+
if (bumpType === "major" && (parsed == null ? void 0 : parsed.major) === 1 && parsed.minor === 0 && parsed.patch === 0 && semver.prerelease(currentVersion)) {
|
|
607
|
+
return `${parsed.major}.${parsed.minor}.${parsed.patch}`;
|
|
467
608
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
609
|
+
log(`Cleaning prerelease identifier from ${currentVersion} for ${bumpType} bump`, "debug");
|
|
610
|
+
return semver.inc(currentVersion, bumpType) || "";
|
|
611
|
+
}
|
|
612
|
+
return semver.inc(currentVersion, bumpType, prereleaseIdentifier) || "";
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// src/core/versionCalculator.ts
|
|
616
|
+
async function calculateVersion(config, options) {
|
|
617
|
+
const {
|
|
618
|
+
latestTag = "",
|
|
619
|
+
type,
|
|
620
|
+
versionPrefix = "",
|
|
621
|
+
branchPattern,
|
|
622
|
+
baseBranch,
|
|
623
|
+
prereleaseIdentifier,
|
|
624
|
+
path: pkgPath,
|
|
625
|
+
name
|
|
626
|
+
} = options;
|
|
627
|
+
const preset = config.preset || "conventional-commits";
|
|
628
|
+
const initialVersion = "0.1.0";
|
|
629
|
+
try {
|
|
630
|
+
let determineTagSearchPattern2 = function(packageName, prefix) {
|
|
631
|
+
if (packageName) {
|
|
632
|
+
const escapedPackageName = escapeRegExp(packageName);
|
|
633
|
+
const escapedPrefix = escapeRegExp(prefix);
|
|
634
|
+
return `${escapedPackageName}[@]?${escapedPrefix}`;
|
|
480
635
|
}
|
|
481
|
-
|
|
482
|
-
|
|
636
|
+
return escapeRegExp(prefix);
|
|
637
|
+
};
|
|
638
|
+
var determineTagSearchPattern = determineTagSearchPattern2;
|
|
639
|
+
const hasNoTags = !latestTag;
|
|
640
|
+
const originalPrefix = versionPrefix;
|
|
641
|
+
const tagSearchPattern = determineTagSearchPattern2(name, originalPrefix);
|
|
642
|
+
const escapedTagPattern = escapeRegExp(tagSearchPattern);
|
|
643
|
+
const specifiedType = type;
|
|
644
|
+
if (specifiedType) {
|
|
483
645
|
if (hasNoTags) {
|
|
484
646
|
return getPackageVersionFallback(
|
|
485
647
|
pkgPath,
|
|
486
648
|
name,
|
|
487
|
-
|
|
649
|
+
specifiedType,
|
|
488
650
|
prereleaseIdentifier,
|
|
489
651
|
initialVersion
|
|
490
652
|
);
|
|
491
653
|
}
|
|
492
|
-
const cleanedTag =
|
|
493
|
-
const currentVersion =
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
try {
|
|
499
|
-
const bumper = new Bumper();
|
|
500
|
-
bumper.loadPreset(preset);
|
|
501
|
-
const recommendedBump = await bumper.bump();
|
|
502
|
-
const releaseTypeFromCommits = recommendedBump == null ? void 0 : recommendedBump.releaseType;
|
|
503
|
-
if (hasNoTags) {
|
|
504
|
-
if (releaseTypeFromCommits) {
|
|
505
|
-
return getPackageVersionFallback(
|
|
506
|
-
pkgPath,
|
|
507
|
-
name,
|
|
508
|
-
releaseTypeFromCommits,
|
|
509
|
-
prereleaseIdentifier,
|
|
510
|
-
initialVersion
|
|
654
|
+
const cleanedTag = semver2.clean(latestTag) || latestTag;
|
|
655
|
+
const currentVersion = semver2.clean(cleanedTag.replace(new RegExp(`^${escapedTagPattern}`), "")) || "0.0.0";
|
|
656
|
+
if (STANDARD_BUMP_TYPES.includes(specifiedType) && semver2.prerelease(currentVersion)) {
|
|
657
|
+
log(
|
|
658
|
+
`Cleaning prerelease identifier from ${currentVersion} for ${specifiedType} bump`,
|
|
659
|
+
"debug"
|
|
511
660
|
);
|
|
661
|
+
return bumpVersion(currentVersion, specifiedType, prereleaseIdentifier);
|
|
512
662
|
}
|
|
513
|
-
return
|
|
663
|
+
return semver2.inc(currentVersion, specifiedType, prereleaseIdentifier) || "";
|
|
514
664
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
665
|
+
if (branchPattern && branchPattern.length > 0) {
|
|
666
|
+
const currentBranch = getCurrentBranch();
|
|
667
|
+
if (baseBranch) {
|
|
668
|
+
lastMergeBranchName(branchPattern, baseBranch);
|
|
669
|
+
}
|
|
670
|
+
const branchToCheck = currentBranch;
|
|
671
|
+
let branchVersionType;
|
|
672
|
+
for (const pattern of branchPattern) {
|
|
673
|
+
if (!pattern.includes(":")) {
|
|
674
|
+
log(`Invalid branch pattern "${pattern}" - missing colon. Skipping.`, "warning");
|
|
675
|
+
continue;
|
|
676
|
+
}
|
|
677
|
+
const [patternRegex, releaseType] = pattern.split(":");
|
|
678
|
+
if (new RegExp(patternRegex).test(branchToCheck)) {
|
|
679
|
+
branchVersionType = releaseType;
|
|
680
|
+
log(`Using branch pattern ${patternRegex} for version type ${releaseType}`, "debug");
|
|
681
|
+
break;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
if (branchVersionType) {
|
|
685
|
+
if (hasNoTags) {
|
|
686
|
+
return getPackageVersionFallback(
|
|
687
|
+
pkgPath,
|
|
688
|
+
name,
|
|
689
|
+
branchVersionType,
|
|
690
|
+
prereleaseIdentifier,
|
|
691
|
+
initialVersion
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
const cleanedTag = semver2.clean(latestTag) || latestTag;
|
|
695
|
+
const currentVersion = semver2.clean(cleanedTag.replace(new RegExp(`^${escapedTagPattern}`), "")) || "0.0.0";
|
|
696
|
+
log(`Applying ${branchVersionType} bump based on branch pattern`, "debug");
|
|
697
|
+
return semver2.inc(currentVersion, branchVersionType, void 0) || "";
|
|
698
|
+
}
|
|
523
699
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
700
|
+
try {
|
|
701
|
+
const bumper = new Bumper();
|
|
702
|
+
bumper.loadPreset(preset);
|
|
703
|
+
const recommendedBump = await bumper.bump();
|
|
704
|
+
const releaseTypeFromCommits = recommendedBump == null ? void 0 : recommendedBump.releaseType;
|
|
705
|
+
if (hasNoTags) {
|
|
706
|
+
if (releaseTypeFromCommits) {
|
|
707
|
+
return getPackageVersionFallback(
|
|
708
|
+
pkgPath,
|
|
709
|
+
name,
|
|
710
|
+
releaseTypeFromCommits,
|
|
711
|
+
prereleaseIdentifier,
|
|
712
|
+
initialVersion
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
return initialVersion;
|
|
716
|
+
}
|
|
717
|
+
const checkPath = pkgPath || cwd3();
|
|
718
|
+
const commitsLength = getCommitsLength(checkPath);
|
|
719
|
+
if (commitsLength === 0) {
|
|
720
|
+
log(
|
|
721
|
+
`No new commits found for ${name || "project"} since ${latestTag}, skipping version bump`,
|
|
722
|
+
"info"
|
|
723
|
+
);
|
|
724
|
+
return "";
|
|
725
|
+
}
|
|
726
|
+
if (!releaseTypeFromCommits) {
|
|
727
|
+
log(
|
|
728
|
+
`No relevant commits found for ${name || "project"} since ${latestTag}, skipping version bump`,
|
|
729
|
+
"info"
|
|
730
|
+
);
|
|
731
|
+
return "";
|
|
732
|
+
}
|
|
733
|
+
const currentVersion = semver2.clean(latestTag.replace(new RegExp(`^${escapedTagPattern}`), "")) || "0.0.0";
|
|
734
|
+
return semver2.inc(currentVersion, releaseTypeFromCommits, prereleaseIdentifier) || "";
|
|
735
|
+
} catch (error) {
|
|
736
|
+
log(`Failed to calculate version for ${name || "project"}`, "error");
|
|
737
|
+
console.error(error);
|
|
738
|
+
if (error instanceof Error && error.message.includes("No names found")) {
|
|
739
|
+
log("No tags found, proceeding with initial version calculation (if applicable).", "info");
|
|
740
|
+
return initialVersion;
|
|
741
|
+
}
|
|
742
|
+
throw error;
|
|
530
743
|
}
|
|
531
|
-
const currentVersion = semver.clean(latestTag.replace(new RegExp(`^${escapedTagPattern}`), "")) || "0.0.0";
|
|
532
|
-
return semver.inc(currentVersion, releaseTypeFromCommits, prereleaseIdentifier) || "";
|
|
533
744
|
} catch (error) {
|
|
534
745
|
log(`Failed to calculate version for ${name || "project"}`, "error");
|
|
535
746
|
console.error(error);
|
|
@@ -542,51 +753,37 @@ async function calculateVersion(config, options) {
|
|
|
542
753
|
}
|
|
543
754
|
function getPackageVersionFallback(pkgPath, name, releaseType, prereleaseIdentifier, initialVersion) {
|
|
544
755
|
const packageDir = pkgPath || cwd3();
|
|
545
|
-
const
|
|
546
|
-
if (
|
|
547
|
-
throw new Error(`package.json not found at ${packageJsonPath}. Cannot determine version.`);
|
|
548
|
-
}
|
|
549
|
-
try {
|
|
550
|
-
const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
|
|
551
|
-
if (!packageJson.version) {
|
|
552
|
-
log(`No version found in package.json. Using initial version ${initialVersion}`, "info");
|
|
553
|
-
return initialVersion;
|
|
554
|
-
}
|
|
756
|
+
const manifestResult = getVersionFromManifests(packageDir);
|
|
757
|
+
if (manifestResult.manifestFound && manifestResult.version) {
|
|
555
758
|
log(
|
|
556
|
-
`No tags found for ${name || "package"}, using
|
|
759
|
+
`No tags found for ${name || "package"}, using ${manifestResult.manifestType} version: ${manifestResult.version} as base`,
|
|
557
760
|
"info"
|
|
558
761
|
);
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
}
|
|
567
|
-
log(
|
|
568
|
-
`Cleaning prerelease identifier from ${packageJson.version} for ${releaseType} bump`,
|
|
569
|
-
"debug"
|
|
570
|
-
);
|
|
571
|
-
return bumpVersion(packageJson.version, releaseType, prereleaseIdentifier);
|
|
572
|
-
}
|
|
573
|
-
return semver.inc(packageJson.version, releaseType, prereleaseIdentifier) || initialVersion;
|
|
574
|
-
} catch (err) {
|
|
575
|
-
throw new Error(
|
|
576
|
-
`Error reading package.json: ${err instanceof Error ? err.message : String(err)}`
|
|
762
|
+
return calculateNextVersion(
|
|
763
|
+
manifestResult.version,
|
|
764
|
+
manifestResult.manifestType || "manifest",
|
|
765
|
+
name,
|
|
766
|
+
releaseType,
|
|
767
|
+
prereleaseIdentifier,
|
|
768
|
+
initialVersion
|
|
577
769
|
);
|
|
578
770
|
}
|
|
771
|
+
throwIfNoManifestsFound(packageDir);
|
|
579
772
|
}
|
|
580
|
-
function
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
773
|
+
function calculateNextVersion(version, manifestType, name, releaseType, prereleaseIdentifier, initialVersion) {
|
|
774
|
+
log(
|
|
775
|
+
`No tags found for ${name || "package"}, using ${manifestType} version: ${version} as base`,
|
|
776
|
+
"info"
|
|
777
|
+
);
|
|
778
|
+
if (STANDARD_BUMP_TYPES.includes(releaseType) && semver2.prerelease(version)) {
|
|
779
|
+
if (version === "1.0.0-next.0" && releaseType === "major") {
|
|
780
|
+
log(`Cleaning prerelease identifier from ${version} for ${releaseType} bump`, "debug");
|
|
781
|
+
return "1.0.0";
|
|
585
782
|
}
|
|
586
|
-
log(`Cleaning prerelease identifier from ${
|
|
587
|
-
return
|
|
783
|
+
log(`Cleaning prerelease identifier from ${version} for ${releaseType} bump`, "debug");
|
|
784
|
+
return bumpVersion(version, releaseType, prereleaseIdentifier);
|
|
588
785
|
}
|
|
589
|
-
return
|
|
786
|
+
return semver2.inc(version, releaseType, prereleaseIdentifier) || initialVersion;
|
|
590
787
|
}
|
|
591
788
|
|
|
592
789
|
// src/package/packageProcessor.ts
|
|
@@ -670,14 +867,31 @@ var PackageProcessor = class {
|
|
|
670
867
|
}
|
|
671
868
|
if (!latestTagResult) {
|
|
672
869
|
try {
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
870
|
+
const packageDir = pkgPath;
|
|
871
|
+
let manifestFallbackUsed = false;
|
|
872
|
+
const manifestResult = getVersionFromManifests(packageDir);
|
|
873
|
+
if (manifestResult.manifestFound && manifestResult.version) {
|
|
874
|
+
log(
|
|
875
|
+
`Using ${manifestResult.manifestType} version ${manifestResult.version} for ${name} as no package-specific tags found`,
|
|
876
|
+
"info"
|
|
877
|
+
);
|
|
878
|
+
log(
|
|
879
|
+
`FALLBACK: Using package version from ${manifestResult.manifestType} instead of global tag`,
|
|
880
|
+
"debug"
|
|
881
|
+
);
|
|
882
|
+
latestTagResult = `${this.versionPrefix || ""}${manifestResult.version}`;
|
|
883
|
+
manifestFallbackUsed = true;
|
|
884
|
+
}
|
|
885
|
+
if (!manifestFallbackUsed) {
|
|
886
|
+
const globalTagResult = await this.getLatestTag();
|
|
887
|
+
if (globalTagResult) {
|
|
888
|
+
latestTagResult = globalTagResult;
|
|
889
|
+
log(`Using global tag ${globalTagResult} as fallback for package ${name}`, "info");
|
|
890
|
+
}
|
|
677
891
|
}
|
|
678
892
|
} catch (error) {
|
|
679
893
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
680
|
-
log(`Error getting
|
|
894
|
+
log(`Error getting fallback version, using empty tag value: ${errorMessage}`, "warning");
|
|
681
895
|
}
|
|
682
896
|
}
|
|
683
897
|
const latestTag = latestTagResult;
|
|
@@ -694,7 +908,14 @@ var PackageProcessor = class {
|
|
|
694
908
|
if (!nextVersion) {
|
|
695
909
|
continue;
|
|
696
910
|
}
|
|
697
|
-
|
|
911
|
+
const packageJsonPath = path3.join(pkgPath, "package.json");
|
|
912
|
+
const cargoTomlPath = path3.join(pkgPath, "Cargo.toml");
|
|
913
|
+
if (fs5.existsSync(packageJsonPath)) {
|
|
914
|
+
updatePackageVersion(packageJsonPath, nextVersion);
|
|
915
|
+
}
|
|
916
|
+
if (fs5.existsSync(cargoTomlPath)) {
|
|
917
|
+
updatePackageVersion(cargoTomlPath, nextVersion);
|
|
918
|
+
}
|
|
698
919
|
const packageTag = formatTag(
|
|
699
920
|
nextVersion,
|
|
700
921
|
this.versionPrefix,
|
|
@@ -725,7 +946,7 @@ var PackageProcessor = class {
|
|
|
725
946
|
log("No targeted packages required a version update.", "info");
|
|
726
947
|
return { updatedPackages: [], tags };
|
|
727
948
|
}
|
|
728
|
-
const filesToCommit = updatedPackagesInfo.map((info) =>
|
|
949
|
+
const filesToCommit = updatedPackagesInfo.map((info) => path3.join(info.path, "package.json"));
|
|
729
950
|
const packageNames = updatedPackagesInfo.map((p) => p.name).join(", ");
|
|
730
951
|
const representativeVersion = ((_a = updatedPackagesInfo[0]) == null ? void 0 : _a.version) || "multiple";
|
|
731
952
|
let commitMessage = this.commitMessageTemplate || "chore(release): publish packages";
|
|
@@ -802,8 +1023,8 @@ function createSyncedStrategy(config) {
|
|
|
802
1023
|
const files = [];
|
|
803
1024
|
const updatedPackages = [];
|
|
804
1025
|
try {
|
|
805
|
-
const rootPkgPath =
|
|
806
|
-
if (
|
|
1026
|
+
const rootPkgPath = path4.join(packages.root, "package.json");
|
|
1027
|
+
if (fs6.existsSync(rootPkgPath)) {
|
|
807
1028
|
updatePackageVersion(rootPkgPath, nextVersion);
|
|
808
1029
|
files.push(rootPkgPath);
|
|
809
1030
|
updatedPackages.push("root");
|
|
@@ -815,7 +1036,7 @@ function createSyncedStrategy(config) {
|
|
|
815
1036
|
if (!shouldProcessPackage(pkg, config)) {
|
|
816
1037
|
continue;
|
|
817
1038
|
}
|
|
818
|
-
const packageJsonPath =
|
|
1039
|
+
const packageJsonPath = path4.join(pkg.dir, "package.json");
|
|
819
1040
|
updatePackageVersion(packageJsonPath, nextVersion);
|
|
820
1041
|
files.push(packageJsonPath);
|
|
821
1042
|
updatedPackages.push(pkg.packageJson.name);
|
|
@@ -888,7 +1109,7 @@ function createSingleStrategy(config) {
|
|
|
888
1109
|
log(`No version change needed for ${packageName}`, "info");
|
|
889
1110
|
return;
|
|
890
1111
|
}
|
|
891
|
-
const packageJsonPath =
|
|
1112
|
+
const packageJsonPath = path4.join(pkgPath, "package.json");
|
|
892
1113
|
updatePackageVersion(packageJsonPath, nextVersion);
|
|
893
1114
|
log(`Updated package ${packageName} to version ${nextVersion}`, "success");
|
|
894
1115
|
const nextTag = formatTag(
|
|
@@ -1064,11 +1285,28 @@ var VersionEngine = class {
|
|
|
1064
1285
|
};
|
|
1065
1286
|
|
|
1066
1287
|
// src/index.ts
|
|
1288
|
+
function getPackageVersion() {
|
|
1289
|
+
try {
|
|
1290
|
+
const packageJsonPath = path5.resolve(
|
|
1291
|
+
path5.dirname(import.meta.url.replace("file:", "")),
|
|
1292
|
+
"../package.json"
|
|
1293
|
+
);
|
|
1294
|
+
const packageJsonContent = fs7.readFileSync(packageJsonPath, "utf-8");
|
|
1295
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
1296
|
+
return packageJson.version || "0.0.0";
|
|
1297
|
+
} catch (error) {
|
|
1298
|
+
console.error("Failed to read package version:", error);
|
|
1299
|
+
return "0.0.0";
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1067
1302
|
async function run() {
|
|
1303
|
+
const buildTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1304
|
+
const packageVersion = getPackageVersion();
|
|
1305
|
+
log(`package-versioner v${packageVersion} (Build: ${buildTimestamp})`, "debug");
|
|
1068
1306
|
const program = new Command();
|
|
1069
1307
|
program.name("package-versioner").description(
|
|
1070
1308
|
"A lightweight yet powerful CLI tool for automated semantic versioning based on Git history and conventional commits."
|
|
1071
|
-
).version(
|
|
1309
|
+
).version(packageVersion).option(
|
|
1072
1310
|
"-c, --config <path>",
|
|
1073
1311
|
"Path to config file (defaults to version.config.json in current directory)"
|
|
1074
1312
|
).option("-d, --dry-run", "Dry run (no changes made)", false).option("-b, --bump <type>", "Specify bump type (patch|minor|major)").option("-p, --prerelease [identifier]", "Create prerelease version").option("-s, --synced", "Use synchronized versioning across all packages").option("-j, --json", "Output results as JSON", false).option("-t, --target <packages>", "Comma-delimited list of package names to target").parse(process.argv);
|
|
@@ -1083,7 +1321,7 @@ async function run() {
|
|
|
1083
1321
|
if (options.synced) config.synced = true;
|
|
1084
1322
|
if (options.bump) config.type = options.bump;
|
|
1085
1323
|
if (options.prerelease)
|
|
1086
|
-
config.prereleaseIdentifier = options.prerelease === true ? "
|
|
1324
|
+
config.prereleaseIdentifier = options.prerelease === true ? "next" : options.prerelease;
|
|
1087
1325
|
const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
|
|
1088
1326
|
const engine = new VersionEngine(config, !!options.json);
|
|
1089
1327
|
if (config.synced) {
|
|
@@ -1116,3 +1354,6 @@ run().catch((error) => {
|
|
|
1116
1354
|
console.error("Fatal error:", error);
|
|
1117
1355
|
process.exit(1);
|
|
1118
1356
|
});
|
|
1357
|
+
export {
|
|
1358
|
+
run
|
|
1359
|
+
};
|