@codluv/versionguard 0.1.1 → 0.3.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/LICENSE +0 -0
- package/README.md +0 -0
- package/dist/calver.d.ts +0 -0
- package/dist/calver.d.ts.map +0 -0
- package/dist/changelog.d.ts +0 -0
- package/dist/changelog.d.ts.map +0 -0
- package/dist/chunks/{index-C6jrxye7.js → index-BrZJDWya.js} +645 -58
- package/dist/chunks/index-BrZJDWya.js.map +1 -0
- package/dist/cli.d.ts +0 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +61 -19
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +0 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/feedback/index.d.ts +0 -0
- package/dist/feedback/index.d.ts.map +0 -0
- package/dist/fix/index.d.ts +2 -2
- package/dist/fix/index.d.ts.map +1 -1
- package/dist/guard.d.ts +104 -0
- package/dist/guard.d.ts.map +1 -0
- package/dist/hooks.d.ts +0 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -23
- package/dist/index.js.map +0 -0
- package/dist/project.d.ts +33 -10
- package/dist/project.d.ts.map +1 -1
- package/dist/semver.d.ts +0 -0
- package/dist/semver.d.ts.map +0 -0
- package/dist/sources/git-tag.d.ts +23 -0
- package/dist/sources/git-tag.d.ts.map +1 -0
- package/dist/sources/index.d.ts +15 -0
- package/dist/sources/index.d.ts.map +1 -0
- package/dist/sources/json.d.ts +22 -0
- package/dist/sources/json.d.ts.map +1 -0
- package/dist/sources/provider.d.ts +25 -0
- package/dist/sources/provider.d.ts.map +1 -0
- package/dist/sources/regex.d.ts +26 -0
- package/dist/sources/regex.d.ts.map +1 -0
- package/dist/sources/resolve.d.ts +35 -0
- package/dist/sources/resolve.d.ts.map +1 -0
- package/dist/sources/toml.d.ts +25 -0
- package/dist/sources/toml.d.ts.map +1 -0
- package/dist/sources/version-file.d.ts +24 -0
- package/dist/sources/version-file.d.ts.map +1 -0
- package/dist/sources/yaml.d.ts +24 -0
- package/dist/sources/yaml.d.ts.map +1 -0
- package/dist/sync.d.ts +0 -0
- package/dist/sync.d.ts.map +0 -0
- package/dist/tag/index.d.ts +0 -0
- package/dist/tag/index.d.ts.map +0 -0
- package/dist/types.d.ts +49 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -7
- package/dist/chunks/index-C6jrxye7.js.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as childProcess from "node:child_process";
|
|
2
|
-
import { execSync } from "node:child_process";
|
|
2
|
+
import { execFileSync, execSync } from "node:child_process";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import * as fs from "node:fs";
|
|
5
|
+
import { parse as parse$2 } from "smol-toml";
|
|
6
|
+
import * as yaml from "js-yaml";
|
|
5
7
|
import { globSync } from "glob";
|
|
6
8
|
import { fileURLToPath } from "node:url";
|
|
7
|
-
import * as yaml from "js-yaml";
|
|
8
9
|
function parseFormat(calverFormat) {
|
|
9
10
|
const parts = calverFormat.split(".");
|
|
10
11
|
const result = {
|
|
@@ -245,7 +246,7 @@ function validateChangelog(changelogPath, version, strict = true, requireEntry =
|
|
|
245
246
|
errors.push("Changelog should include compare links at the bottom");
|
|
246
247
|
}
|
|
247
248
|
const versionHeaderMatch = content.match(
|
|
248
|
-
new RegExp(`## \\[${escapeRegExp(version)}\\] - ([^\r
|
|
249
|
+
new RegExp(`## \\[${escapeRegExp$2(version)}\\] - ([^\r
|
|
249
250
|
]+)`)
|
|
250
251
|
);
|
|
251
252
|
if (requireEntry && hasEntryForVersion) {
|
|
@@ -285,10 +286,10 @@ function addVersionEntry(changelogPath, version, date = (/* @__PURE__ */ new Dat
|
|
|
285
286
|
const updated = `${content.slice(0, insertIndex)}${block}${content.slice(insertIndex)}`;
|
|
286
287
|
fs.writeFileSync(changelogPath, updated, "utf-8");
|
|
287
288
|
}
|
|
288
|
-
function escapeRegExp(value) {
|
|
289
|
+
function escapeRegExp$2(value) {
|
|
289
290
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
290
291
|
}
|
|
291
|
-
const HOOK_NAMES = ["pre-commit", "pre-push", "post-tag"];
|
|
292
|
+
const HOOK_NAMES$1 = ["pre-commit", "pre-push", "post-tag"];
|
|
292
293
|
function installHooks(config, cwd = process.cwd()) {
|
|
293
294
|
const gitDir = findGitDir(cwd);
|
|
294
295
|
if (!gitDir) {
|
|
@@ -296,7 +297,7 @@ function installHooks(config, cwd = process.cwd()) {
|
|
|
296
297
|
}
|
|
297
298
|
const hooksDir = path.join(gitDir, "hooks");
|
|
298
299
|
fs.mkdirSync(hooksDir, { recursive: true });
|
|
299
|
-
for (const hookName of HOOK_NAMES) {
|
|
300
|
+
for (const hookName of HOOK_NAMES$1) {
|
|
300
301
|
if (config.hooks[hookName]) {
|
|
301
302
|
const hookPath = path.join(hooksDir, hookName);
|
|
302
303
|
fs.writeFileSync(hookPath, generateHookScript(hookName), { encoding: "utf-8", mode: 493 });
|
|
@@ -309,7 +310,7 @@ function uninstallHooks(cwd = process.cwd()) {
|
|
|
309
310
|
return;
|
|
310
311
|
}
|
|
311
312
|
const hooksDir = path.join(gitDir, "hooks");
|
|
312
|
-
for (const hookName of HOOK_NAMES) {
|
|
313
|
+
for (const hookName of HOOK_NAMES$1) {
|
|
313
314
|
const hookPath = path.join(hooksDir, hookName);
|
|
314
315
|
if (fs.existsSync(hookPath) && fs.readFileSync(hookPath, "utf-8").includes("versionguard")) {
|
|
315
316
|
fs.unlinkSync(hookPath);
|
|
@@ -335,13 +336,14 @@ function areHooksInstalled(cwd = process.cwd()) {
|
|
|
335
336
|
if (!gitDir) {
|
|
336
337
|
return false;
|
|
337
338
|
}
|
|
338
|
-
return HOOK_NAMES.every((hookName) => {
|
|
339
|
+
return HOOK_NAMES$1.every((hookName) => {
|
|
339
340
|
const hookPath = path.join(gitDir, "hooks", hookName);
|
|
340
341
|
return fs.existsSync(hookPath) && fs.readFileSync(hookPath, "utf-8").includes("versionguard");
|
|
341
342
|
});
|
|
342
343
|
}
|
|
343
344
|
function generateHookScript(hookName) {
|
|
344
345
|
return `#!/bin/sh
|
|
346
|
+
# versionguard
|
|
345
347
|
# VersionGuard ${hookName} hook
|
|
346
348
|
# --no-install prevents accidentally downloading an unscoped package
|
|
347
349
|
# if @codluv/versionguard is not installed locally
|
|
@@ -353,6 +355,428 @@ if [ $status -ne 0 ]; then
|
|
|
353
355
|
fi
|
|
354
356
|
`;
|
|
355
357
|
}
|
|
358
|
+
class GitTagSource {
|
|
359
|
+
name = "git-tag";
|
|
360
|
+
manifestFile = "";
|
|
361
|
+
exists(cwd) {
|
|
362
|
+
try {
|
|
363
|
+
execFileSync("git", ["rev-parse", "--git-dir"], {
|
|
364
|
+
cwd,
|
|
365
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
366
|
+
});
|
|
367
|
+
return true;
|
|
368
|
+
} catch {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
getVersion(cwd) {
|
|
373
|
+
try {
|
|
374
|
+
const tag = execFileSync("git", ["describe", "--tags", "--abbrev=0"], {
|
|
375
|
+
cwd,
|
|
376
|
+
encoding: "utf-8",
|
|
377
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
378
|
+
}).trim();
|
|
379
|
+
return tag.replace(/^v/, "");
|
|
380
|
+
} catch {
|
|
381
|
+
throw new Error("No git tags found. Create a tag first (e.g., git tag v0.1.0)");
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
setVersion(version, cwd) {
|
|
385
|
+
const tagName = `v${version}`;
|
|
386
|
+
execFileSync("git", ["tag", "-a", tagName, "-m", `Release ${version}`], {
|
|
387
|
+
cwd,
|
|
388
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
class JsonVersionSource {
|
|
393
|
+
name;
|
|
394
|
+
manifestFile;
|
|
395
|
+
versionPath;
|
|
396
|
+
constructor(manifestFile = "package.json", versionPath = "version") {
|
|
397
|
+
this.name = manifestFile;
|
|
398
|
+
this.manifestFile = manifestFile;
|
|
399
|
+
this.versionPath = versionPath;
|
|
400
|
+
}
|
|
401
|
+
exists(cwd) {
|
|
402
|
+
return fs.existsSync(path.join(cwd, this.manifestFile));
|
|
403
|
+
}
|
|
404
|
+
getVersion(cwd) {
|
|
405
|
+
const filePath = path.join(cwd, this.manifestFile);
|
|
406
|
+
if (!fs.existsSync(filePath)) {
|
|
407
|
+
throw new Error(`${this.manifestFile} not found in ${cwd}`);
|
|
408
|
+
}
|
|
409
|
+
const content = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
410
|
+
const version = getNestedValue$1(content, this.versionPath);
|
|
411
|
+
if (typeof version !== "string" || version.length === 0) {
|
|
412
|
+
throw new Error(`No version field in ${this.manifestFile}`);
|
|
413
|
+
}
|
|
414
|
+
return version;
|
|
415
|
+
}
|
|
416
|
+
setVersion(version, cwd) {
|
|
417
|
+
const filePath = path.join(cwd, this.manifestFile);
|
|
418
|
+
if (!fs.existsSync(filePath)) {
|
|
419
|
+
throw new Error(`${this.manifestFile} not found in ${cwd}`);
|
|
420
|
+
}
|
|
421
|
+
const content = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
422
|
+
setNestedValue(content, this.versionPath, version);
|
|
423
|
+
fs.writeFileSync(filePath, `${JSON.stringify(content, null, 2)}
|
|
424
|
+
`, "utf-8");
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
function getNestedValue$1(obj, dotPath) {
|
|
428
|
+
let current = obj;
|
|
429
|
+
for (const key of dotPath.split(".")) {
|
|
430
|
+
if (current === null || typeof current !== "object") {
|
|
431
|
+
return void 0;
|
|
432
|
+
}
|
|
433
|
+
current = current[key];
|
|
434
|
+
}
|
|
435
|
+
return current;
|
|
436
|
+
}
|
|
437
|
+
function setNestedValue(obj, dotPath, value) {
|
|
438
|
+
const keys = dotPath.split(".");
|
|
439
|
+
let current = obj;
|
|
440
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
441
|
+
const key = keys[i];
|
|
442
|
+
if (typeof current[key] !== "object" || current[key] === null) {
|
|
443
|
+
current[key] = {};
|
|
444
|
+
}
|
|
445
|
+
current = current[key];
|
|
446
|
+
}
|
|
447
|
+
current[keys[keys.length - 1]] = value;
|
|
448
|
+
}
|
|
449
|
+
class RegexVersionSource {
|
|
450
|
+
name;
|
|
451
|
+
manifestFile;
|
|
452
|
+
versionRegex;
|
|
453
|
+
constructor(manifestFile, versionRegex) {
|
|
454
|
+
this.name = manifestFile;
|
|
455
|
+
this.manifestFile = manifestFile;
|
|
456
|
+
try {
|
|
457
|
+
this.versionRegex = new RegExp(versionRegex, "m");
|
|
458
|
+
} catch (err) {
|
|
459
|
+
throw new Error(`Invalid version regex for ${manifestFile}: ${err.message}`);
|
|
460
|
+
}
|
|
461
|
+
if (!/\((?!\?)/.test(versionRegex)) {
|
|
462
|
+
throw new Error(`Version regex for ${manifestFile} must contain at least one capture group`);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
exists(cwd) {
|
|
466
|
+
return fs.existsSync(path.join(cwd, this.manifestFile));
|
|
467
|
+
}
|
|
468
|
+
getVersion(cwd) {
|
|
469
|
+
const filePath = path.join(cwd, this.manifestFile);
|
|
470
|
+
if (!fs.existsSync(filePath)) {
|
|
471
|
+
throw new Error(`${this.manifestFile} not found in ${cwd}`);
|
|
472
|
+
}
|
|
473
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
474
|
+
const match = content.match(this.versionRegex);
|
|
475
|
+
if (!match?.[1]) {
|
|
476
|
+
throw new Error(`No version match found in ${this.manifestFile}`);
|
|
477
|
+
}
|
|
478
|
+
return match[1];
|
|
479
|
+
}
|
|
480
|
+
setVersion(version, cwd) {
|
|
481
|
+
const filePath = path.join(cwd, this.manifestFile);
|
|
482
|
+
if (!fs.existsSync(filePath)) {
|
|
483
|
+
throw new Error(`${this.manifestFile} not found in ${cwd}`);
|
|
484
|
+
}
|
|
485
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
486
|
+
const match = this.versionRegex.exec(content);
|
|
487
|
+
if (!match || match.index === void 0) {
|
|
488
|
+
throw new Error(`No version match found in ${this.manifestFile}`);
|
|
489
|
+
}
|
|
490
|
+
const captureStart = match.index + match[0].indexOf(match[1]);
|
|
491
|
+
const captureEnd = captureStart + match[1].length;
|
|
492
|
+
const updated = content.slice(0, captureStart) + version + content.slice(captureEnd);
|
|
493
|
+
fs.writeFileSync(filePath, updated, "utf-8");
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
class TomlVersionSource {
|
|
497
|
+
name;
|
|
498
|
+
manifestFile;
|
|
499
|
+
versionPath;
|
|
500
|
+
constructor(manifestFile = "Cargo.toml", versionPath = "package.version") {
|
|
501
|
+
this.name = manifestFile;
|
|
502
|
+
this.manifestFile = manifestFile;
|
|
503
|
+
this.versionPath = versionPath;
|
|
504
|
+
}
|
|
505
|
+
exists(cwd) {
|
|
506
|
+
return fs.existsSync(path.join(cwd, this.manifestFile));
|
|
507
|
+
}
|
|
508
|
+
getVersion(cwd) {
|
|
509
|
+
const filePath = path.join(cwd, this.manifestFile);
|
|
510
|
+
if (!fs.existsSync(filePath)) {
|
|
511
|
+
throw new Error(`${this.manifestFile} not found in ${cwd}`);
|
|
512
|
+
}
|
|
513
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
514
|
+
const parsed = parse$2(content);
|
|
515
|
+
const version = getNestedValue(parsed, this.versionPath);
|
|
516
|
+
if (typeof version !== "string" || version.length === 0) {
|
|
517
|
+
throw new Error(`No version field at '${this.versionPath}' in ${this.manifestFile}`);
|
|
518
|
+
}
|
|
519
|
+
return version;
|
|
520
|
+
}
|
|
521
|
+
setVersion(version, cwd) {
|
|
522
|
+
const filePath = path.join(cwd, this.manifestFile);
|
|
523
|
+
if (!fs.existsSync(filePath)) {
|
|
524
|
+
throw new Error(`${this.manifestFile} not found in ${cwd}`);
|
|
525
|
+
}
|
|
526
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
527
|
+
const sectionKey = this.getSectionKey();
|
|
528
|
+
const updated = replaceTomlVersion(content, sectionKey, version);
|
|
529
|
+
if (updated === content) {
|
|
530
|
+
throw new Error(`Could not find version field to update in ${this.manifestFile}`);
|
|
531
|
+
}
|
|
532
|
+
fs.writeFileSync(filePath, updated, "utf-8");
|
|
533
|
+
}
|
|
534
|
+
getSectionKey() {
|
|
535
|
+
const parts = this.versionPath.split(".");
|
|
536
|
+
if (parts.length === 1) {
|
|
537
|
+
return { section: "", key: parts[0] };
|
|
538
|
+
}
|
|
539
|
+
return {
|
|
540
|
+
section: parts.slice(0, -1).join("."),
|
|
541
|
+
key: parts[parts.length - 1]
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
function getNestedValue(obj, dotPath) {
|
|
546
|
+
let current = obj;
|
|
547
|
+
for (const key of dotPath.split(".")) {
|
|
548
|
+
if (current === null || typeof current !== "object") {
|
|
549
|
+
return void 0;
|
|
550
|
+
}
|
|
551
|
+
current = current[key];
|
|
552
|
+
}
|
|
553
|
+
return current;
|
|
554
|
+
}
|
|
555
|
+
function replaceTomlVersion(content, target, newVersion) {
|
|
556
|
+
const lines = content.split("\n");
|
|
557
|
+
const sectionHeader = target.section ? `[${target.section}]` : null;
|
|
558
|
+
let inSection = sectionHeader === null;
|
|
559
|
+
const versionRegex = new RegExp(`^(\\s*${escapeRegExp$1(target.key)}\\s*=\\s*)(["'])([^"']*)(\\2)`);
|
|
560
|
+
for (let i = 0; i < lines.length; i++) {
|
|
561
|
+
const trimmed = lines[i].trim();
|
|
562
|
+
if (sectionHeader !== null) {
|
|
563
|
+
if (trimmed === sectionHeader) {
|
|
564
|
+
inSection = true;
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
if (inSection && trimmed.startsWith("[") && trimmed !== sectionHeader) {
|
|
568
|
+
inSection = false;
|
|
569
|
+
continue;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
if (inSection) {
|
|
573
|
+
const match = lines[i].match(versionRegex);
|
|
574
|
+
if (match) {
|
|
575
|
+
lines[i] = lines[i].replace(versionRegex, `$1$2${newVersion}$4`);
|
|
576
|
+
return lines.join("\n");
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return content;
|
|
581
|
+
}
|
|
582
|
+
function escapeRegExp$1(value) {
|
|
583
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
584
|
+
}
|
|
585
|
+
class VersionFileSource {
|
|
586
|
+
name;
|
|
587
|
+
manifestFile;
|
|
588
|
+
constructor(manifestFile = "VERSION") {
|
|
589
|
+
this.name = manifestFile;
|
|
590
|
+
this.manifestFile = manifestFile;
|
|
591
|
+
}
|
|
592
|
+
exists(cwd) {
|
|
593
|
+
return fs.existsSync(path.join(cwd, this.manifestFile));
|
|
594
|
+
}
|
|
595
|
+
getVersion(cwd) {
|
|
596
|
+
const filePath = path.join(cwd, this.manifestFile);
|
|
597
|
+
if (!fs.existsSync(filePath)) {
|
|
598
|
+
throw new Error(`${this.manifestFile} not found in ${cwd}`);
|
|
599
|
+
}
|
|
600
|
+
const version = fs.readFileSync(filePath, "utf-8").trim();
|
|
601
|
+
if (version.length === 0) {
|
|
602
|
+
throw new Error(`${this.manifestFile} is empty`);
|
|
603
|
+
}
|
|
604
|
+
return version;
|
|
605
|
+
}
|
|
606
|
+
setVersion(version, cwd) {
|
|
607
|
+
const filePath = path.join(cwd, this.manifestFile);
|
|
608
|
+
if (!fs.existsSync(filePath)) {
|
|
609
|
+
throw new Error(`${this.manifestFile} not found in ${cwd}`);
|
|
610
|
+
}
|
|
611
|
+
fs.writeFileSync(filePath, `${version}
|
|
612
|
+
`, "utf-8");
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
class YamlVersionSource {
|
|
616
|
+
name;
|
|
617
|
+
manifestFile;
|
|
618
|
+
versionKey;
|
|
619
|
+
constructor(manifestFile = "pubspec.yaml", versionKey = "version") {
|
|
620
|
+
this.name = manifestFile;
|
|
621
|
+
this.manifestFile = manifestFile;
|
|
622
|
+
this.versionKey = versionKey;
|
|
623
|
+
}
|
|
624
|
+
exists(cwd) {
|
|
625
|
+
return fs.existsSync(path.join(cwd, this.manifestFile));
|
|
626
|
+
}
|
|
627
|
+
getVersion(cwd) {
|
|
628
|
+
const filePath = path.join(cwd, this.manifestFile);
|
|
629
|
+
if (!fs.existsSync(filePath)) {
|
|
630
|
+
throw new Error(`${this.manifestFile} not found in ${cwd}`);
|
|
631
|
+
}
|
|
632
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
633
|
+
const parsed = yaml.load(content);
|
|
634
|
+
if (!parsed || typeof parsed !== "object") {
|
|
635
|
+
throw new Error(`Failed to parse ${this.manifestFile}`);
|
|
636
|
+
}
|
|
637
|
+
const version = parsed[this.versionKey];
|
|
638
|
+
if (typeof version !== "string" || version.length === 0) {
|
|
639
|
+
if (typeof version === "number") {
|
|
640
|
+
return String(version);
|
|
641
|
+
}
|
|
642
|
+
throw new Error(`No version field in ${this.manifestFile}`);
|
|
643
|
+
}
|
|
644
|
+
return version;
|
|
645
|
+
}
|
|
646
|
+
setVersion(version, cwd) {
|
|
647
|
+
const filePath = path.join(cwd, this.manifestFile);
|
|
648
|
+
if (!fs.existsSync(filePath)) {
|
|
649
|
+
throw new Error(`${this.manifestFile} not found in ${cwd}`);
|
|
650
|
+
}
|
|
651
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
652
|
+
const regex = new RegExp(`^(${escapeRegExp(this.versionKey)}:\\s*)(["']?)(.+?)\\2\\s*$`, "m");
|
|
653
|
+
const updated = content.replace(regex, `$1$2${version}$2`);
|
|
654
|
+
if (updated === content) {
|
|
655
|
+
throw new Error(`Could not find version field to update in ${this.manifestFile}`);
|
|
656
|
+
}
|
|
657
|
+
fs.writeFileSync(filePath, updated, "utf-8");
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
function escapeRegExp(value) {
|
|
661
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
662
|
+
}
|
|
663
|
+
const VALID_SOURCES = /* @__PURE__ */ new Set([
|
|
664
|
+
"auto",
|
|
665
|
+
"package.json",
|
|
666
|
+
"composer.json",
|
|
667
|
+
"Cargo.toml",
|
|
668
|
+
"pyproject.toml",
|
|
669
|
+
"pubspec.yaml",
|
|
670
|
+
"pom.xml",
|
|
671
|
+
"VERSION",
|
|
672
|
+
"git-tag",
|
|
673
|
+
"custom"
|
|
674
|
+
]);
|
|
675
|
+
const DETECTION_TABLE = [
|
|
676
|
+
{
|
|
677
|
+
file: "package.json",
|
|
678
|
+
source: "package.json",
|
|
679
|
+
factory: () => new JsonVersionSource("package.json", "version")
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
file: "Cargo.toml",
|
|
683
|
+
source: "Cargo.toml",
|
|
684
|
+
factory: () => new TomlVersionSource("Cargo.toml", "package.version")
|
|
685
|
+
},
|
|
686
|
+
{
|
|
687
|
+
file: "pyproject.toml",
|
|
688
|
+
source: "pyproject.toml",
|
|
689
|
+
factory: () => new TomlVersionSource("pyproject.toml", "project.version")
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
file: "pubspec.yaml",
|
|
693
|
+
source: "pubspec.yaml",
|
|
694
|
+
factory: () => new YamlVersionSource("pubspec.yaml", "version")
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
file: "composer.json",
|
|
698
|
+
source: "composer.json",
|
|
699
|
+
factory: () => new JsonVersionSource("composer.json", "version")
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
// H-002: Use regex that skips <parent> blocks for pom.xml
|
|
703
|
+
file: "pom.xml",
|
|
704
|
+
source: "pom.xml",
|
|
705
|
+
factory: () => new RegexVersionSource("pom.xml", "<project[^>]*>[\\s\\S]*?<version>([^<]+)</version>")
|
|
706
|
+
},
|
|
707
|
+
{ file: "VERSION", source: "VERSION", factory: () => new VersionFileSource("VERSION") }
|
|
708
|
+
];
|
|
709
|
+
function assertPathContained(manifestFile, cwd) {
|
|
710
|
+
const resolved = path.resolve(cwd, manifestFile);
|
|
711
|
+
const root = path.resolve(cwd);
|
|
712
|
+
if (!resolved.startsWith(`${root}${path.sep}`) && resolved !== root) {
|
|
713
|
+
throw new Error(`Manifest path "${manifestFile}" resolves outside the project directory`);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
function createProvider(source, config, cwd) {
|
|
717
|
+
if (!VALID_SOURCES.has(source)) {
|
|
718
|
+
throw new Error(
|
|
719
|
+
`Invalid manifest source "${source}". Valid sources: ${[...VALID_SOURCES].join(", ")}`
|
|
720
|
+
);
|
|
721
|
+
}
|
|
722
|
+
switch (source) {
|
|
723
|
+
case "package.json":
|
|
724
|
+
return new JsonVersionSource("package.json", config.path ?? "version");
|
|
725
|
+
case "composer.json":
|
|
726
|
+
return new JsonVersionSource("composer.json", config.path ?? "version");
|
|
727
|
+
case "Cargo.toml":
|
|
728
|
+
return new TomlVersionSource("Cargo.toml", config.path ?? "package.version");
|
|
729
|
+
case "pyproject.toml":
|
|
730
|
+
return new TomlVersionSource("pyproject.toml", config.path ?? "project.version");
|
|
731
|
+
case "pubspec.yaml":
|
|
732
|
+
return new YamlVersionSource("pubspec.yaml", config.path ?? "version");
|
|
733
|
+
case "pom.xml":
|
|
734
|
+
return new RegexVersionSource(
|
|
735
|
+
"pom.xml",
|
|
736
|
+
config.regex ?? "<project[^>]*>[\\s\\S]*?<version>([^<]+)</version>"
|
|
737
|
+
);
|
|
738
|
+
case "VERSION":
|
|
739
|
+
return new VersionFileSource(config.path ?? "VERSION");
|
|
740
|
+
case "git-tag":
|
|
741
|
+
return new GitTagSource();
|
|
742
|
+
case "custom": {
|
|
743
|
+
if (!config.regex) {
|
|
744
|
+
throw new Error("Custom manifest source requires a 'regex' field in manifest config");
|
|
745
|
+
}
|
|
746
|
+
if (!config.path) {
|
|
747
|
+
throw new Error(
|
|
748
|
+
"Custom manifest source requires a 'path' field (manifest filename) in manifest config"
|
|
749
|
+
);
|
|
750
|
+
}
|
|
751
|
+
assertPathContained(config.path, cwd);
|
|
752
|
+
return new RegexVersionSource(config.path, config.regex);
|
|
753
|
+
}
|
|
754
|
+
default:
|
|
755
|
+
throw new Error(`Unknown manifest source: ${source}`);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
function resolveVersionSource(config, cwd = process.cwd()) {
|
|
759
|
+
if (config.source !== "auto") {
|
|
760
|
+
return createProvider(config.source, config, cwd);
|
|
761
|
+
}
|
|
762
|
+
for (const entry of DETECTION_TABLE) {
|
|
763
|
+
const provider = entry.factory();
|
|
764
|
+
if (provider.exists(cwd)) {
|
|
765
|
+
return provider;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
return new JsonVersionSource("package.json", "version");
|
|
769
|
+
}
|
|
770
|
+
function detectManifests(cwd = process.cwd()) {
|
|
771
|
+
const detected = [];
|
|
772
|
+
for (const entry of DETECTION_TABLE) {
|
|
773
|
+
const provider = entry.factory();
|
|
774
|
+
if (provider.exists(cwd)) {
|
|
775
|
+
detected.push(entry.source);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
return detected;
|
|
779
|
+
}
|
|
356
780
|
function getPackageJsonPath(cwd = process.cwd()) {
|
|
357
781
|
return path.join(cwd, "package.json");
|
|
358
782
|
}
|
|
@@ -367,18 +791,30 @@ function writePackageJson(pkg, cwd = process.cwd()) {
|
|
|
367
791
|
fs.writeFileSync(getPackageJsonPath(cwd), `${JSON.stringify(pkg, null, 2)}
|
|
368
792
|
`, "utf-8");
|
|
369
793
|
}
|
|
370
|
-
function getPackageVersion(cwd = process.cwd()) {
|
|
794
|
+
function getPackageVersion(cwd = process.cwd(), manifest) {
|
|
795
|
+
if (manifest) {
|
|
796
|
+
const provider = resolveVersionSource(manifest, cwd);
|
|
797
|
+
return provider.getVersion(cwd);
|
|
798
|
+
}
|
|
371
799
|
const pkg = readPackageJson(cwd);
|
|
372
800
|
if (typeof pkg.version !== "string" || pkg.version.length === 0) {
|
|
373
801
|
throw new Error("No version field in package.json");
|
|
374
802
|
}
|
|
375
803
|
return pkg.version;
|
|
376
804
|
}
|
|
377
|
-
function setPackageVersion(version, cwd = process.cwd()) {
|
|
805
|
+
function setPackageVersion(version, cwd = process.cwd(), manifest) {
|
|
806
|
+
if (manifest) {
|
|
807
|
+
const provider = resolveVersionSource(manifest, cwd);
|
|
808
|
+
provider.setVersion(version, cwd);
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
378
811
|
const pkg = readPackageJson(cwd);
|
|
379
812
|
pkg.version = version;
|
|
380
813
|
writePackageJson(pkg, cwd);
|
|
381
814
|
}
|
|
815
|
+
function getVersionSource(manifest, cwd = process.cwd()) {
|
|
816
|
+
return resolveVersionSource(manifest, cwd);
|
|
817
|
+
}
|
|
382
818
|
const SEMVER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
|
383
819
|
function parse(version) {
|
|
384
820
|
const match = version.match(SEMVER_REGEX);
|
|
@@ -637,6 +1073,9 @@ const DEFAULT_CONFIG = {
|
|
|
637
1073
|
preventFutureDates: true
|
|
638
1074
|
}
|
|
639
1075
|
},
|
|
1076
|
+
manifest: {
|
|
1077
|
+
source: "auto"
|
|
1078
|
+
},
|
|
640
1079
|
sync: {
|
|
641
1080
|
files: ["README.md", "CHANGELOG.md"],
|
|
642
1081
|
patterns: [
|
|
@@ -896,7 +1335,7 @@ function getCalVerFeedback(version, calverConfig, previousVersion) {
|
|
|
896
1335
|
});
|
|
897
1336
|
suggestions.push({
|
|
898
1337
|
message: `Expected format: ${format2}`,
|
|
899
|
-
fix: `Update
|
|
1338
|
+
fix: `Update version to current date: "${getCurrentVersion(format2)}"`,
|
|
900
1339
|
autoFixable: true
|
|
901
1340
|
});
|
|
902
1341
|
return { valid: false, errors, suggestions, canAutoFix: true };
|
|
@@ -1003,7 +1442,7 @@ function getChangelogFeedback(hasEntry, version, latestChangelogVersion) {
|
|
|
1003
1442
|
}
|
|
1004
1443
|
if (latestChangelogVersion && latestChangelogVersion !== version) {
|
|
1005
1444
|
suggestions.push({
|
|
1006
|
-
message: `CHANGELOG.md latest entry is ${latestChangelogVersion}, but
|
|
1445
|
+
message: `CHANGELOG.md latest entry is ${latestChangelogVersion}, but manifest version is ${version}`,
|
|
1007
1446
|
fix: `Make sure versions are in sync`,
|
|
1008
1447
|
autoFixable: false
|
|
1009
1448
|
});
|
|
@@ -1014,7 +1453,7 @@ function getTagFeedback(tagVersion, packageVersion, hasUnsyncedFiles) {
|
|
|
1014
1453
|
const suggestions = [];
|
|
1015
1454
|
if (tagVersion !== packageVersion) {
|
|
1016
1455
|
suggestions.push({
|
|
1017
|
-
message: `Git tag "${tagVersion}" doesn't match
|
|
1456
|
+
message: `Git tag "${tagVersion}" doesn't match manifest version "${packageVersion}"`,
|
|
1018
1457
|
fix: `Delete tag and recreate: git tag -d ${tagVersion} && git tag ${packageVersion}`,
|
|
1019
1458
|
autoFixable: false
|
|
1020
1459
|
});
|
|
@@ -1028,25 +1467,43 @@ function getTagFeedback(tagVersion, packageVersion, hasUnsyncedFiles) {
|
|
|
1028
1467
|
}
|
|
1029
1468
|
return suggestions;
|
|
1030
1469
|
}
|
|
1031
|
-
function fixPackageVersion(targetVersion, cwd = process.cwd()) {
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1470
|
+
function fixPackageVersion(targetVersion, cwd = process.cwd(), manifest) {
|
|
1471
|
+
if (!manifest) {
|
|
1472
|
+
const packagePath = path.join(cwd, "package.json");
|
|
1473
|
+
if (!fs.existsSync(packagePath)) {
|
|
1474
|
+
return { fixed: false, message: "package.json not found" };
|
|
1475
|
+
}
|
|
1476
|
+
const pkg = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
|
|
1477
|
+
const oldVersion2 = typeof pkg.version === "string" ? pkg.version : void 0;
|
|
1478
|
+
if (oldVersion2 === targetVersion) {
|
|
1479
|
+
return { fixed: false, message: `Already at version ${targetVersion}` };
|
|
1480
|
+
}
|
|
1481
|
+
setPackageVersion(targetVersion, cwd);
|
|
1482
|
+
return {
|
|
1483
|
+
fixed: true,
|
|
1484
|
+
message: `Updated package.json from ${oldVersion2} to ${targetVersion}`,
|
|
1485
|
+
file: packagePath
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
const provider = getVersionSource(manifest, cwd);
|
|
1489
|
+
let oldVersion;
|
|
1490
|
+
try {
|
|
1491
|
+
oldVersion = provider.getVersion(cwd);
|
|
1492
|
+
} catch {
|
|
1493
|
+
return { fixed: false, message: "Version source not found" };
|
|
1035
1494
|
}
|
|
1036
|
-
const pkg = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
|
|
1037
|
-
const oldVersion = typeof pkg.version === "string" ? pkg.version : void 0;
|
|
1038
1495
|
if (oldVersion === targetVersion) {
|
|
1039
1496
|
return { fixed: false, message: `Already at version ${targetVersion}` };
|
|
1040
1497
|
}
|
|
1041
|
-
|
|
1498
|
+
provider.setVersion(targetVersion, cwd);
|
|
1042
1499
|
return {
|
|
1043
1500
|
fixed: true,
|
|
1044
|
-
message: `Updated
|
|
1045
|
-
file:
|
|
1501
|
+
message: `Updated version from ${oldVersion} to ${targetVersion}`,
|
|
1502
|
+
file: provider.manifestFile ? path.join(cwd, provider.manifestFile) : void 0
|
|
1046
1503
|
};
|
|
1047
1504
|
}
|
|
1048
1505
|
function fixSyncIssues(config, cwd = process.cwd()) {
|
|
1049
|
-
const version = getPackageVersion(cwd);
|
|
1506
|
+
const version = getPackageVersion(cwd, config.manifest);
|
|
1050
1507
|
const results = syncVersion(version, config.sync, cwd).filter((result) => result.updated).map((result) => ({
|
|
1051
1508
|
fixed: true,
|
|
1052
1509
|
message: `Updated ${path.relative(cwd, result.file)} (${result.changes.length} changes)`,
|
|
@@ -1102,9 +1559,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1102
1559
|
}
|
|
1103
1560
|
function fixAll(config, targetVersion, cwd = process.cwd()) {
|
|
1104
1561
|
const results = [];
|
|
1105
|
-
const version = targetVersion || getPackageVersion(cwd);
|
|
1106
|
-
if (targetVersion && targetVersion !== getPackageVersion(cwd)) {
|
|
1107
|
-
results.push(fixPackageVersion(targetVersion, cwd));
|
|
1562
|
+
const version = targetVersion || getPackageVersion(cwd, config.manifest);
|
|
1563
|
+
if (targetVersion && targetVersion !== getPackageVersion(cwd, config.manifest)) {
|
|
1564
|
+
results.push(fixPackageVersion(targetVersion, cwd, config.manifest));
|
|
1108
1565
|
}
|
|
1109
1566
|
const syncResults = fixSyncIssues(config, cwd);
|
|
1110
1567
|
results.push(...syncResults);
|
|
@@ -1157,6 +1614,122 @@ function getCalVerConfig$1(config) {
|
|
|
1157
1614
|
}
|
|
1158
1615
|
return config.versioning.calver;
|
|
1159
1616
|
}
|
|
1617
|
+
const HOOK_NAMES = ["pre-commit", "pre-push", "post-tag"];
|
|
1618
|
+
function checkHooksPathOverride(cwd) {
|
|
1619
|
+
try {
|
|
1620
|
+
const hooksPath = execSync("git config core.hooksPath", {
|
|
1621
|
+
cwd,
|
|
1622
|
+
encoding: "utf-8"
|
|
1623
|
+
}).trim();
|
|
1624
|
+
if (hooksPath) {
|
|
1625
|
+
const resolved = path.resolve(cwd, hooksPath);
|
|
1626
|
+
const huskyDir = path.resolve(cwd, ".husky");
|
|
1627
|
+
if (resolved === huskyDir || resolved.startsWith(`${huskyDir}${path.sep}`)) {
|
|
1628
|
+
return {
|
|
1629
|
+
code: "HOOKS_PATH_HUSKY",
|
|
1630
|
+
severity: "warning",
|
|
1631
|
+
message: `Husky detected — core.hooksPath is set to "${hooksPath}". Hooks in .git/hooks/ are bypassed. Add versionguard validate to your .husky/pre-commit manually or use a tool like forge-ts that manages .husky/ hooks cooperatively.`
|
|
1632
|
+
};
|
|
1633
|
+
}
|
|
1634
|
+
return {
|
|
1635
|
+
code: "HOOKS_PATH_OVERRIDE",
|
|
1636
|
+
severity: "error",
|
|
1637
|
+
message: `git core.hooksPath is set to "${hooksPath}" — hooks in .git/hooks/ are bypassed`,
|
|
1638
|
+
fix: "git config --unset core.hooksPath"
|
|
1639
|
+
};
|
|
1640
|
+
}
|
|
1641
|
+
} catch {
|
|
1642
|
+
}
|
|
1643
|
+
return null;
|
|
1644
|
+
}
|
|
1645
|
+
function checkHuskyBypass() {
|
|
1646
|
+
if (process.env.HUSKY === "0") {
|
|
1647
|
+
return {
|
|
1648
|
+
code: "HUSKY_BYPASS",
|
|
1649
|
+
severity: "error",
|
|
1650
|
+
message: "HUSKY=0 is set — git hooks are disabled via environment variable",
|
|
1651
|
+
fix: "unset HUSKY"
|
|
1652
|
+
};
|
|
1653
|
+
}
|
|
1654
|
+
return null;
|
|
1655
|
+
}
|
|
1656
|
+
function checkHookIntegrity(config, cwd) {
|
|
1657
|
+
const warnings = [];
|
|
1658
|
+
const gitDir = findGitDir(cwd);
|
|
1659
|
+
if (!gitDir) {
|
|
1660
|
+
return warnings;
|
|
1661
|
+
}
|
|
1662
|
+
const hooksDir = path.join(gitDir, "hooks");
|
|
1663
|
+
for (const hookName of HOOK_NAMES) {
|
|
1664
|
+
if (!config.git.hooks[hookName]) {
|
|
1665
|
+
continue;
|
|
1666
|
+
}
|
|
1667
|
+
const hookPath = path.join(hooksDir, hookName);
|
|
1668
|
+
if (!fs.existsSync(hookPath)) {
|
|
1669
|
+
warnings.push({
|
|
1670
|
+
code: "HOOK_MISSING",
|
|
1671
|
+
severity: "error",
|
|
1672
|
+
message: `Required hook "${hookName}" is not installed`,
|
|
1673
|
+
fix: "npx versionguard hooks install"
|
|
1674
|
+
});
|
|
1675
|
+
continue;
|
|
1676
|
+
}
|
|
1677
|
+
const actual = fs.readFileSync(hookPath, "utf-8");
|
|
1678
|
+
const expected = generateHookScript(hookName);
|
|
1679
|
+
if (actual !== expected) {
|
|
1680
|
+
if (!actual.includes("versionguard")) {
|
|
1681
|
+
warnings.push({
|
|
1682
|
+
code: "HOOK_REPLACED",
|
|
1683
|
+
severity: "error",
|
|
1684
|
+
message: `Hook "${hookName}" has been replaced — versionguard invocation is missing`,
|
|
1685
|
+
fix: "npx versionguard hooks install"
|
|
1686
|
+
});
|
|
1687
|
+
} else {
|
|
1688
|
+
warnings.push({
|
|
1689
|
+
code: "HOOK_TAMPERED",
|
|
1690
|
+
severity: "warning",
|
|
1691
|
+
message: `Hook "${hookName}" has been modified from the expected template`,
|
|
1692
|
+
fix: "npx versionguard hooks install"
|
|
1693
|
+
});
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
return warnings;
|
|
1698
|
+
}
|
|
1699
|
+
function checkEnforceHooksPolicy(config) {
|
|
1700
|
+
const anyHookEnabled = HOOK_NAMES.some((name) => config.git.hooks[name]);
|
|
1701
|
+
if (anyHookEnabled && !config.git.enforceHooks) {
|
|
1702
|
+
return {
|
|
1703
|
+
code: "HOOKS_NOT_ENFORCED",
|
|
1704
|
+
severity: "warning",
|
|
1705
|
+
message: "Hooks are enabled but enforceHooks is false — missing hooks will not fail validation",
|
|
1706
|
+
fix: "Set git.enforceHooks: true in .versionguard.yml"
|
|
1707
|
+
};
|
|
1708
|
+
}
|
|
1709
|
+
return null;
|
|
1710
|
+
}
|
|
1711
|
+
function runGuardChecks(config, cwd) {
|
|
1712
|
+
const warnings = [];
|
|
1713
|
+
const hooksPathWarning = checkHooksPathOverride(cwd);
|
|
1714
|
+
if (hooksPathWarning) {
|
|
1715
|
+
warnings.push(hooksPathWarning);
|
|
1716
|
+
}
|
|
1717
|
+
const huskyWarning = checkHuskyBypass();
|
|
1718
|
+
if (huskyWarning) {
|
|
1719
|
+
warnings.push(huskyWarning);
|
|
1720
|
+
}
|
|
1721
|
+
const integrityWarnings = checkHookIntegrity(config, cwd);
|
|
1722
|
+
warnings.push(...integrityWarnings);
|
|
1723
|
+
const enforceWarning = checkEnforceHooksPolicy(config);
|
|
1724
|
+
if (enforceWarning) {
|
|
1725
|
+
warnings.push(enforceWarning);
|
|
1726
|
+
}
|
|
1727
|
+
const hasErrors = warnings.some((w) => w.severity === "error");
|
|
1728
|
+
return {
|
|
1729
|
+
safe: !hasErrors,
|
|
1730
|
+
warnings
|
|
1731
|
+
};
|
|
1732
|
+
}
|
|
1160
1733
|
function runGit(cwd, args, encoding) {
|
|
1161
1734
|
return childProcess.execFileSync("git", args, {
|
|
1162
1735
|
cwd,
|
|
@@ -1208,7 +1781,7 @@ function createTag(version, message, autoFix = true, config, cwd = process.cwd()
|
|
|
1208
1781
|
actions
|
|
1209
1782
|
};
|
|
1210
1783
|
}
|
|
1211
|
-
const packageVersion = getPackageVersion(cwd);
|
|
1784
|
+
const packageVersion = getPackageVersion(cwd, config.manifest);
|
|
1212
1785
|
const shouldAutoFix = autoFix;
|
|
1213
1786
|
const preflightError = getTagPreflightError(config, cwd, version, shouldAutoFix);
|
|
1214
1787
|
if (preflightError) {
|
|
@@ -1221,7 +1794,7 @@ function createTag(version, message, autoFix = true, config, cwd = process.cwd()
|
|
|
1221
1794
|
if (version !== packageVersion && !autoFix) {
|
|
1222
1795
|
return {
|
|
1223
1796
|
success: false,
|
|
1224
|
-
message: `Version mismatch:
|
|
1797
|
+
message: `Version mismatch: manifest version is ${packageVersion}, tag is ${version}`,
|
|
1225
1798
|
actions: []
|
|
1226
1799
|
};
|
|
1227
1800
|
}
|
|
@@ -1281,15 +1854,15 @@ function handlePostTag(config, cwd = process.cwd()) {
|
|
|
1281
1854
|
actions
|
|
1282
1855
|
};
|
|
1283
1856
|
}
|
|
1284
|
-
const packageVersion = getPackageVersion(cwd);
|
|
1857
|
+
const packageVersion = getPackageVersion(cwd, config.manifest);
|
|
1285
1858
|
if (tag.version !== packageVersion) {
|
|
1286
1859
|
return {
|
|
1287
1860
|
success: false,
|
|
1288
|
-
message: `Tag version ${tag.version} doesn't match
|
|
1861
|
+
message: `Tag version ${tag.version} doesn't match manifest version ${packageVersion}`,
|
|
1289
1862
|
actions: [
|
|
1290
1863
|
"To fix: delete tag and recreate with correct version",
|
|
1291
1864
|
` git tag -d ${tag.name}`,
|
|
1292
|
-
`
|
|
1865
|
+
` Update manifest to ${tag.version}`,
|
|
1293
1866
|
` git tag ${tag.name}`
|
|
1294
1867
|
]
|
|
1295
1868
|
};
|
|
@@ -1320,7 +1893,7 @@ function getTagPreflightError(config, cwd, expectedVersion, allowAutoFix = false
|
|
|
1320
1893
|
if (hasDirtyWorktree(cwd)) {
|
|
1321
1894
|
return "Working tree must be clean before creating or validating release tags";
|
|
1322
1895
|
}
|
|
1323
|
-
const version = expectedVersion ?? getPackageVersion(cwd);
|
|
1896
|
+
const version = expectedVersion ?? getPackageVersion(cwd, config.manifest);
|
|
1324
1897
|
const versionResult = config.versioning.type === "semver" ? validate$1(version) : validate$2(
|
|
1325
1898
|
version,
|
|
1326
1899
|
config.versioning.calver?.format ?? "YYYY.MM.PATCH",
|
|
@@ -1414,7 +1987,7 @@ function validate(config, cwd = process.cwd()) {
|
|
|
1414
1987
|
const errors = [];
|
|
1415
1988
|
let version;
|
|
1416
1989
|
try {
|
|
1417
|
-
version = getPackageVersion(cwd);
|
|
1990
|
+
version = getPackageVersion(cwd, config.manifest);
|
|
1418
1991
|
} catch (err) {
|
|
1419
1992
|
return {
|
|
1420
1993
|
valid: false,
|
|
@@ -1485,7 +2058,7 @@ function doctor(config, cwd = process.cwd()) {
|
|
|
1485
2058
|
};
|
|
1486
2059
|
}
|
|
1487
2060
|
function sync(config, cwd = process.cwd()) {
|
|
1488
|
-
const version = getPackageVersion(cwd);
|
|
2061
|
+
const version = getPackageVersion(cwd, config.manifest);
|
|
1489
2062
|
syncVersion(version, config.sync, cwd);
|
|
1490
2063
|
}
|
|
1491
2064
|
function canBump(currentVersion, newVersion, config) {
|
|
@@ -1534,37 +2107,51 @@ function isWorktreeClean(cwd) {
|
|
|
1534
2107
|
}
|
|
1535
2108
|
}
|
|
1536
2109
|
export {
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
2110
|
+
fixChangelog as A,
|
|
2111
|
+
fixPackageVersion as B,
|
|
2112
|
+
getAllTags as C,
|
|
2113
|
+
getLatestTag as D,
|
|
2114
|
+
getTagFeedback as E,
|
|
2115
|
+
getVersionSource as F,
|
|
2116
|
+
GitTagSource as G,
|
|
2117
|
+
resolveVersionSource as H,
|
|
2118
|
+
semver as I,
|
|
2119
|
+
JsonVersionSource as J,
|
|
2120
|
+
suggestTagMessage as K,
|
|
2121
|
+
sync as L,
|
|
2122
|
+
syncVersion as M,
|
|
2123
|
+
validateChangelog as N,
|
|
2124
|
+
validateTagForPush as O,
|
|
2125
|
+
validateVersion as P,
|
|
2126
|
+
RegexVersionSource as R,
|
|
2127
|
+
TomlVersionSource as T,
|
|
2128
|
+
VersionFileSource as V,
|
|
2129
|
+
YamlVersionSource as Y,
|
|
2130
|
+
installHooks as a,
|
|
2131
|
+
getPackageVersion as b,
|
|
2132
|
+
getVersionFeedback as c,
|
|
2133
|
+
getSyncFeedback as d,
|
|
2134
|
+
getChangelogFeedback as e,
|
|
2135
|
+
doctor as f,
|
|
1549
2136
|
getConfig as g,
|
|
1550
2137
|
handlePostTag as h,
|
|
1551
2138
|
initConfig as i,
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
2139
|
+
fixAll as j,
|
|
2140
|
+
fixSyncIssues as k,
|
|
2141
|
+
setPackageVersion as l,
|
|
2142
|
+
createTag as m,
|
|
1556
2143
|
areHooksInstalled as n,
|
|
1557
2144
|
calver as o,
|
|
1558
2145
|
canBump as p,
|
|
1559
|
-
|
|
1560
|
-
|
|
2146
|
+
checkEnforceHooksPolicy as q,
|
|
2147
|
+
runGuardChecks as r,
|
|
1561
2148
|
suggestNextVersion as s,
|
|
1562
|
-
|
|
2149
|
+
checkHardcodedVersions as t,
|
|
1563
2150
|
uninstallHooks as u,
|
|
1564
2151
|
validate as v,
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
2152
|
+
checkHookIntegrity as w,
|
|
2153
|
+
checkHooksPathOverride as x,
|
|
2154
|
+
checkHuskyBypass as y,
|
|
2155
|
+
detectManifests as z
|
|
1569
2156
|
};
|
|
1570
|
-
//# sourceMappingURL=index-
|
|
2157
|
+
//# sourceMappingURL=index-BrZJDWya.js.map
|