@versu/core 0.4.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 +241 -0
- package/dist/adapters/gradle/constants.d.ts +13 -0
- package/dist/adapters/gradle/constants.d.ts.map +1 -0
- package/dist/adapters/gradle/constants.js +12 -0
- package/dist/adapters/gradle/gradle-project-information.d.ts +19 -0
- package/dist/adapters/gradle/gradle-project-information.d.ts.map +1 -0
- package/dist/adapters/gradle/gradle-project-information.js +233 -0
- package/dist/adapters/gradle/init-project-information.gradle.kts +163 -0
- package/dist/adapters/gradle/services/gradle-adapter-identifier.d.ts +21 -0
- package/dist/adapters/gradle/services/gradle-adapter-identifier.d.ts.map +1 -0
- package/dist/adapters/gradle/services/gradle-adapter-identifier.js +44 -0
- package/dist/adapters/gradle/services/gradle-module-detector.d.ts +19 -0
- package/dist/adapters/gradle/services/gradle-module-detector.d.ts.map +1 -0
- package/dist/adapters/gradle/services/gradle-module-detector.js +28 -0
- package/dist/adapters/gradle/services/gradle-module-system-factory.d.ts +26 -0
- package/dist/adapters/gradle/services/gradle-module-system-factory.d.ts.map +1 -0
- package/dist/adapters/gradle/services/gradle-module-system-factory.js +29 -0
- package/dist/adapters/gradle/services/gradle-version-update-strategy.d.ts +23 -0
- package/dist/adapters/gradle/services/gradle-version-update-strategy.d.ts.map +1 -0
- package/dist/adapters/gradle/services/gradle-version-update-strategy.js +38 -0
- package/dist/adapters/project-information.d.ts +62 -0
- package/dist/adapters/project-information.d.ts.map +1 -0
- package/dist/adapters/project-information.js +1 -0
- package/dist/changelog/index.d.ts +14 -0
- package/dist/changelog/index.d.ts.map +1 -0
- package/dist/changelog/index.js +132 -0
- package/dist/config/index.d.ts +122 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +117 -0
- package/dist/factories/adapter-identifier-registry.d.ts +12 -0
- package/dist/factories/adapter-identifier-registry.d.ts.map +1 -0
- package/dist/factories/adapter-identifier-registry.js +24 -0
- package/dist/factories/module-system-factory.d.ts +10 -0
- package/dist/factories/module-system-factory.d.ts.map +1 -0
- package/dist/factories/module-system-factory.js +18 -0
- package/dist/git/index.d.ts +355 -0
- package/dist/git/index.d.ts.map +1 -0
- package/dist/git/index.js +702 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/semver/index.d.ts +86 -0
- package/dist/semver/index.d.ts.map +1 -0
- package/dist/semver/index.js +186 -0
- package/dist/services/adapter-identifier-registry.d.ts +38 -0
- package/dist/services/adapter-identifier-registry.d.ts.map +1 -0
- package/dist/services/adapter-identifier-registry.js +59 -0
- package/dist/services/adapter-identifier.d.ts +31 -0
- package/dist/services/adapter-identifier.d.ts.map +1 -0
- package/dist/services/adapter-identifier.js +1 -0
- package/dist/services/adapter-metadata-provider.d.ts +51 -0
- package/dist/services/adapter-metadata-provider.d.ts.map +1 -0
- package/dist/services/adapter-metadata-provider.js +66 -0
- package/dist/services/changelog-generator.d.ts +16 -0
- package/dist/services/changelog-generator.d.ts.map +1 -0
- package/dist/services/changelog-generator.js +28 -0
- package/dist/services/commit-analyzer.d.ts +47 -0
- package/dist/services/commit-analyzer.d.ts.map +1 -0
- package/dist/services/commit-analyzer.js +89 -0
- package/dist/services/configuration-loader.d.ts +23 -0
- package/dist/services/configuration-loader.d.ts.map +1 -0
- package/dist/services/configuration-loader.js +79 -0
- package/dist/services/configuration-validator.d.ts +16 -0
- package/dist/services/configuration-validator.d.ts.map +1 -0
- package/dist/services/configuration-validator.js +24 -0
- package/dist/services/git-operations.d.ts +16 -0
- package/dist/services/git-operations.d.ts.map +1 -0
- package/dist/services/git-operations.js +89 -0
- package/dist/services/module-detector.d.ts +24 -0
- package/dist/services/module-detector.d.ts.map +1 -0
- package/dist/services/module-detector.js +1 -0
- package/dist/services/module-registry.d.ts +45 -0
- package/dist/services/module-registry.d.ts.map +1 -0
- package/dist/services/module-registry.js +57 -0
- package/dist/services/module-system-factory.d.ts +27 -0
- package/dist/services/module-system-factory.d.ts.map +1 -0
- package/dist/services/module-system-factory.js +1 -0
- package/dist/services/version-applier.d.ts +26 -0
- package/dist/services/version-applier.d.ts.map +1 -0
- package/dist/services/version-applier.js +63 -0
- package/dist/services/version-bumper.d.ts +159 -0
- package/dist/services/version-bumper.d.ts.map +1 -0
- package/dist/services/version-bumper.js +291 -0
- package/dist/services/version-manager.d.ts +68 -0
- package/dist/services/version-manager.d.ts.map +1 -0
- package/dist/services/version-manager.js +94 -0
- package/dist/services/version-update-strategy.d.ts +18 -0
- package/dist/services/version-update-strategy.d.ts.map +1 -0
- package/dist/services/version-update-strategy.js +1 -0
- package/dist/services/versu-runner.d.ts +46 -0
- package/dist/services/versu-runner.d.ts.map +1 -0
- package/dist/services/versu-runner.js +188 -0
- package/dist/utils/banner.d.ts +2 -0
- package/dist/utils/banner.d.ts.map +1 -0
- package/dist/utils/banner.js +12 -0
- package/dist/utils/commits.d.ts +12 -0
- package/dist/utils/commits.d.ts.map +1 -0
- package/dist/utils/commits.js +24 -0
- package/dist/utils/file.d.ts +7 -0
- package/dist/utils/file.d.ts.map +1 -0
- package/dist/utils/file.js +19 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +22 -0
- package/dist/utils/properties.d.ts +24 -0
- package/dist/utils/properties.d.ts.map +1 -0
- package/dist/utils/properties.js +94 -0
- package/dist/utils/version.d.ts +3 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +4 -0
- package/dist/utils/versioning.d.ts +9 -0
- package/dist/utils/versioning.d.ts.map +1 -0
- package/dist/utils/versioning.js +20 -0
- package/package.json +73 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { formatSemVer } from "../semver/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Manages version updates for modules with staged commits and batch persistence.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Implements a two-phase update strategy:
|
|
7
|
+
* 1. Stage updates in memory via `updateVersion()`
|
|
8
|
+
* 2. Persist all updates via `commit()`
|
|
9
|
+
*
|
|
10
|
+
* Uses {@link VersionUpdateStrategy} for build system-specific operations.
|
|
11
|
+
* Validates modules against {@link ModuleRegistry}.
|
|
12
|
+
*/
|
|
13
|
+
export class VersionManager {
|
|
14
|
+
moduleRegistry;
|
|
15
|
+
strategy;
|
|
16
|
+
/** Pending version updates awaiting commit (module ID → version string). */
|
|
17
|
+
pendingUpdates = new Map();
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new VersionManager.
|
|
20
|
+
*
|
|
21
|
+
* @param moduleRegistry - Module registry for validation
|
|
22
|
+
* @param strategy - Build system-specific strategy for writing updates
|
|
23
|
+
*/
|
|
24
|
+
constructor(moduleRegistry, strategy) {
|
|
25
|
+
this.moduleRegistry = moduleRegistry;
|
|
26
|
+
this.strategy = strategy;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Stages a version update for a module without persisting to files.
|
|
30
|
+
*
|
|
31
|
+
* @param moduleId - Module identifier (e.g., `':'`, `':core'`)
|
|
32
|
+
* @param newVersion - New version as SemVer object or string
|
|
33
|
+
* @throws {Error} If module ID doesn't exist in registry
|
|
34
|
+
*/
|
|
35
|
+
updateVersion(moduleId, newVersion) {
|
|
36
|
+
// Validate module exists in registry
|
|
37
|
+
if (!this.moduleRegistry.hasModule(moduleId)) {
|
|
38
|
+
throw new Error(`Module ${moduleId} not found`);
|
|
39
|
+
}
|
|
40
|
+
// Convert SemVer to string if needed, otherwise use string directly
|
|
41
|
+
const versionString = typeof newVersion === "string" ? newVersion : formatSemVer(newVersion);
|
|
42
|
+
// Store update in pending updates map
|
|
43
|
+
this.pendingUpdates.set(moduleId, versionString);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Commits all pending version updates to build files in a single batch operation.
|
|
47
|
+
*
|
|
48
|
+
* @returns Promise that resolves when all updates are written
|
|
49
|
+
* @throws {Error} If file operations fail (specific errors depend on strategy)
|
|
50
|
+
*/
|
|
51
|
+
async commit() {
|
|
52
|
+
// Early return if nothing to commit
|
|
53
|
+
if (this.pendingUpdates.size === 0) {
|
|
54
|
+
return; // Nothing to commit
|
|
55
|
+
}
|
|
56
|
+
// Write all version updates using build system-specific strategy
|
|
57
|
+
await this.strategy.writeVersionUpdates(this.pendingUpdates);
|
|
58
|
+
// Clear the pending updates after successful commit
|
|
59
|
+
this.pendingUpdates.clear();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Returns a copy of all pending updates that haven't been committed.
|
|
63
|
+
*
|
|
64
|
+
* @returns Map of module ID to version string
|
|
65
|
+
*/
|
|
66
|
+
getPendingUpdates() {
|
|
67
|
+
return new Map(this.pendingUpdates);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Checks whether there are any pending updates awaiting commit.
|
|
71
|
+
*
|
|
72
|
+
* @returns `true` if updates are staged, `false` otherwise
|
|
73
|
+
*/
|
|
74
|
+
hasPendingUpdates() {
|
|
75
|
+
return this.pendingUpdates.size > 0;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Clears all pending updates without committing them.
|
|
79
|
+
*
|
|
80
|
+
* @remarks
|
|
81
|
+
* Use with caution - this operation cannot be undone.
|
|
82
|
+
*/
|
|
83
|
+
clearPendingUpdates() {
|
|
84
|
+
this.pendingUpdates.clear();
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Gets the number of pending updates in the queue.
|
|
88
|
+
*
|
|
89
|
+
* @returns The count of pending updates that have not been processed yet.
|
|
90
|
+
*/
|
|
91
|
+
getPendingUpdatesCount() {
|
|
92
|
+
return this.pendingUpdates.size;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strategy for writing version updates to build system-specific files.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Implementations handle version persistence for different build systems (Gradle, Maven, npm).
|
|
6
|
+
* Created by {@link ModuleSystemFactory} and used by {@link VersionManager}.
|
|
7
|
+
*/
|
|
8
|
+
export interface VersionUpdateStrategy {
|
|
9
|
+
/**
|
|
10
|
+
* Writes version updates for multiple modules to build system configuration files.
|
|
11
|
+
*
|
|
12
|
+
* @param moduleVersions - Map of module ID to new version string
|
|
13
|
+
* @returns Promise that resolves when all updates are written
|
|
14
|
+
* @throws {Error} If build files cannot be found, are not writable, or I/O operations fail
|
|
15
|
+
*/
|
|
16
|
+
writeVersionUpdates(moduleVersions: Map<string, string>): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=version-update-strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-update-strategy.d.ts","sourceRoot":"","sources":["../../src/services/version-update-strategy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,mBAAmB,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ModuleChangeResult } from "./version-applier.js";
|
|
2
|
+
import { Module } from "../adapters/project-information.js";
|
|
3
|
+
export type RunnerOptions = {
|
|
4
|
+
readonly repoRoot: string;
|
|
5
|
+
readonly adapter?: string;
|
|
6
|
+
readonly dryRun: boolean;
|
|
7
|
+
readonly pushTags: boolean;
|
|
8
|
+
readonly prereleaseMode: boolean;
|
|
9
|
+
readonly prereleaseId: string;
|
|
10
|
+
readonly bumpUnchanged: boolean;
|
|
11
|
+
readonly addBuildMetadata: boolean;
|
|
12
|
+
readonly timestampVersions: boolean;
|
|
13
|
+
readonly appendSnapshot: boolean;
|
|
14
|
+
readonly pushChanges: boolean;
|
|
15
|
+
readonly generateChangelog: boolean;
|
|
16
|
+
readonly outputFile: string;
|
|
17
|
+
};
|
|
18
|
+
export type RunnerResult = {
|
|
19
|
+
readonly bumped: boolean;
|
|
20
|
+
readonly discoveredModules: Array<Module>;
|
|
21
|
+
readonly changedModules: Array<ModuleChangeResult>;
|
|
22
|
+
readonly createdTags: string[];
|
|
23
|
+
readonly changelogPaths: string[];
|
|
24
|
+
};
|
|
25
|
+
export declare class VersuRunner {
|
|
26
|
+
private moduleSystemFactory;
|
|
27
|
+
private moduleRegistry;
|
|
28
|
+
private versionManager;
|
|
29
|
+
private config;
|
|
30
|
+
private adapter;
|
|
31
|
+
private options;
|
|
32
|
+
private configurationLoader;
|
|
33
|
+
private commitAnalyzer;
|
|
34
|
+
private versionBumper;
|
|
35
|
+
private versionApplier;
|
|
36
|
+
private changelogGenerator;
|
|
37
|
+
private gitOperations;
|
|
38
|
+
private adapterIdentifierRegistry;
|
|
39
|
+
private adapterMetadataProvider;
|
|
40
|
+
constructor(options: RunnerOptions);
|
|
41
|
+
private logStartupInfo;
|
|
42
|
+
private logShutdownInfo;
|
|
43
|
+
run(): Promise<RunnerResult>;
|
|
44
|
+
private doRun;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=versu-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"versu-runner.d.ts","sourceRoot":"","sources":["../../src/services/versu-runner.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAO9B,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAK5D,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,iBAAiB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACnD,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;CACnC,CAAC;AAEF,qBAAa,WAAW;IACtB,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,OAAO,CAAgB;IAG/B,OAAO,CAAC,mBAAmB,CAAsB;IACjD,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,yBAAyB,CAA4B;IAC7D,OAAO,CAAC,uBAAuB,CAA0B;gBAE7C,OAAO,EAAE,aAAa;IA0BlC,OAAO,CAAC,cAAc;IAuBtB,OAAO,CAAC,eAAe;IAgCjB,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC;YAYpB,KAAK;CAkIpB"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { logger } from "../utils/logger.js";
|
|
2
|
+
import { VersionManager } from "./version-manager.js";
|
|
3
|
+
import { createModuleSystemFactory } from "../factories/module-system-factory.js";
|
|
4
|
+
import { isWorkingDirectoryClean } from "../git/index.js";
|
|
5
|
+
// Service imports
|
|
6
|
+
import { ConfigurationLoader } from "./configuration-loader.js";
|
|
7
|
+
import { CommitAnalyzer } from "./commit-analyzer.js";
|
|
8
|
+
import { VersionBumper } from "./version-bumper.js";
|
|
9
|
+
import { VersionApplier, } from "./version-applier.js";
|
|
10
|
+
import { ChangelogGenerator } from "./changelog-generator.js";
|
|
11
|
+
import { GitOperations } from "./git-operations.js";
|
|
12
|
+
import { AdapterMetadataProvider } from "./adapter-metadata-provider.js";
|
|
13
|
+
import { createAdapterIdentifierRegistry } from "../factories/adapter-identifier-registry.js";
|
|
14
|
+
import { ConfigurationValidator } from "./configuration-validator.js";
|
|
15
|
+
import { banner } from "../utils/banner.js";
|
|
16
|
+
import path from "path";
|
|
17
|
+
export class VersuRunner {
|
|
18
|
+
moduleSystemFactory; // Will be initialized in run()
|
|
19
|
+
moduleRegistry; // Will be initialized in run()
|
|
20
|
+
versionManager; // Will be initialized in run()
|
|
21
|
+
config; // Will be initialized in run()
|
|
22
|
+
adapter; // Will be initialized in run()
|
|
23
|
+
options;
|
|
24
|
+
// Service instances
|
|
25
|
+
configurationLoader;
|
|
26
|
+
commitAnalyzer;
|
|
27
|
+
versionBumper; // Will be initialized in run()
|
|
28
|
+
versionApplier; // Will be initialized in run()
|
|
29
|
+
changelogGenerator;
|
|
30
|
+
gitOperations; // Will be initialized in run()
|
|
31
|
+
adapterIdentifierRegistry;
|
|
32
|
+
adapterMetadataProvider;
|
|
33
|
+
constructor(options) {
|
|
34
|
+
this.options = {
|
|
35
|
+
...options,
|
|
36
|
+
repoRoot: path.resolve(options.repoRoot),
|
|
37
|
+
outputFile: path.resolve(options.outputFile),
|
|
38
|
+
};
|
|
39
|
+
// Initialize services
|
|
40
|
+
this.configurationLoader = new ConfigurationLoader(new ConfigurationValidator());
|
|
41
|
+
this.changelogGenerator = new ChangelogGenerator({
|
|
42
|
+
generateChangelog: options.generateChangelog,
|
|
43
|
+
repoRoot: options.repoRoot,
|
|
44
|
+
dryRun: options.dryRun,
|
|
45
|
+
});
|
|
46
|
+
this.adapterIdentifierRegistry = createAdapterIdentifierRegistry();
|
|
47
|
+
this.adapterMetadataProvider = new AdapterMetadataProvider(this.adapterIdentifierRegistry, {
|
|
48
|
+
repoRoot: options.repoRoot,
|
|
49
|
+
adapter: options.adapter,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
logStartupInfo() {
|
|
53
|
+
logger.info(banner);
|
|
54
|
+
logger.info("🌌 Version Engine for Repo Semantic Evolution");
|
|
55
|
+
logger.info(" Orchestrating your monorepo multiverse...");
|
|
56
|
+
logger.info("");
|
|
57
|
+
logger.info("🚀 Starting VERSU engine...");
|
|
58
|
+
logger.info(`Repository: ${this.options.repoRoot}`);
|
|
59
|
+
logger.info(`Output file: ${this.options.outputFile}`);
|
|
60
|
+
logger.info(`Adapter: ${this.options.adapter || "(auto-detect)"}`);
|
|
61
|
+
logger.info(`Dry run: ${this.options.dryRun}`);
|
|
62
|
+
logger.info(`Prerelease mode: ${this.options.prereleaseMode}`);
|
|
63
|
+
if (this.options.prereleaseMode) {
|
|
64
|
+
logger.info(`Prerelease ID: ${this.options.prereleaseId}`);
|
|
65
|
+
logger.info(`Bump unchanged modules: ${this.options.bumpUnchanged}`);
|
|
66
|
+
}
|
|
67
|
+
logger.info(`Add build metadata: ${this.options.addBuildMetadata}`);
|
|
68
|
+
logger.info(`Timestamp versions: ${this.options.timestampVersions}`);
|
|
69
|
+
logger.info(`Append snapshot: ${this.options.appendSnapshot}`);
|
|
70
|
+
logger.info(`Push changes: ${this.options.pushChanges}`);
|
|
71
|
+
logger.info(`Generate changelog: ${this.options.generateChangelog}`);
|
|
72
|
+
logger.info("🏃 Running VERSU semantic evolution...");
|
|
73
|
+
}
|
|
74
|
+
logShutdownInfo(result) {
|
|
75
|
+
if (!result)
|
|
76
|
+
return;
|
|
77
|
+
if (result.bumped) {
|
|
78
|
+
logger.info(`✅ Successfully updated ${result.changedModules.length} modules`);
|
|
79
|
+
for (const module of result.changedModules) {
|
|
80
|
+
logger.info(` ${module.id}: ${module.from} → ${module.to} (${module.bumpType})`);
|
|
81
|
+
}
|
|
82
|
+
if (result.createdTags.length > 0) {
|
|
83
|
+
logger.info(`🏷️ Created ${result.createdTags.length} tags: ${result.createdTags.join(", ")}`);
|
|
84
|
+
}
|
|
85
|
+
if (result.changelogPaths.length > 0) {
|
|
86
|
+
logger.info(`📚 Generated ${result.changelogPaths.length} changelog files`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
logger.info("✨ No version changes needed");
|
|
91
|
+
}
|
|
92
|
+
logger.info("");
|
|
93
|
+
logger.info("🎯 VERSU completed successfully!");
|
|
94
|
+
logger.info(" Your multiverse has evolved semantically ✨");
|
|
95
|
+
}
|
|
96
|
+
async run() {
|
|
97
|
+
this.logStartupInfo();
|
|
98
|
+
let result = null;
|
|
99
|
+
try {
|
|
100
|
+
result = await this.doRun();
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
// Any cleanup if needed
|
|
105
|
+
this.logShutdownInfo(result);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async doRun() {
|
|
109
|
+
this.adapter = await this.adapterMetadataProvider.getMetadata();
|
|
110
|
+
// Initialize module system factory with resolved adapter
|
|
111
|
+
this.moduleSystemFactory = createModuleSystemFactory(this.adapter.id, this.options.repoRoot);
|
|
112
|
+
// Load configuration
|
|
113
|
+
this.config = await this.configurationLoader.load(this.options.repoRoot);
|
|
114
|
+
// Check if working directory is clean
|
|
115
|
+
if (!this.options.dryRun &&
|
|
116
|
+
!isWorkingDirectoryClean({ cwd: this.options.repoRoot })) {
|
|
117
|
+
throw new Error("Working directory is not clean. Please commit or stash your changes.");
|
|
118
|
+
}
|
|
119
|
+
// Discover modules and get hierarchy manager
|
|
120
|
+
logger.info("🔍 Discovering modules...");
|
|
121
|
+
const detector = this.moduleSystemFactory.createDetector(this.options.outputFile);
|
|
122
|
+
this.moduleRegistry = await detector.detect();
|
|
123
|
+
// Log discovered modules through hierarchy manager
|
|
124
|
+
const moduleIds = this.moduleRegistry.getModuleIds();
|
|
125
|
+
logger.info(`Found ${moduleIds.length} modules: ${moduleIds.join(", ")}`);
|
|
126
|
+
// Analyze commits since last release
|
|
127
|
+
this.commitAnalyzer = new CommitAnalyzer(this.moduleRegistry, this.options.repoRoot);
|
|
128
|
+
const moduleCommits = await this.commitAnalyzer.analyzeCommitsSinceLastRelease();
|
|
129
|
+
// Initialize version bumper service
|
|
130
|
+
const versionBumperOptions = {
|
|
131
|
+
prereleaseMode: this.options.prereleaseMode,
|
|
132
|
+
bumpUnchanged: this.options.bumpUnchanged,
|
|
133
|
+
addBuildMetadata: this.options.addBuildMetadata,
|
|
134
|
+
appendSnapshot: this.options.appendSnapshot,
|
|
135
|
+
adapter: this.adapter,
|
|
136
|
+
timestampVersions: this.options.timestampVersions,
|
|
137
|
+
prereleaseId: this.options.prereleaseId,
|
|
138
|
+
repoRoot: this.options.repoRoot,
|
|
139
|
+
config: this.config,
|
|
140
|
+
};
|
|
141
|
+
this.versionBumper = new VersionBumper(this.moduleRegistry, versionBumperOptions);
|
|
142
|
+
// Calculate version bumps with cascade effects
|
|
143
|
+
const processedModuleChanges = await this.versionBumper.calculateVersionBumps(moduleCommits);
|
|
144
|
+
const discoveredModules = Array.from(this.moduleRegistry.getModules().values());
|
|
145
|
+
if (processedModuleChanges.length === 0) {
|
|
146
|
+
logger.info("✨ No version changes needed");
|
|
147
|
+
return {
|
|
148
|
+
bumped: false,
|
|
149
|
+
discoveredModules,
|
|
150
|
+
changedModules: [],
|
|
151
|
+
createdTags: [],
|
|
152
|
+
changelogPaths: [],
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
// Create version manager
|
|
156
|
+
const versionUpdateStrategy = this.moduleSystemFactory.createVersionUpdateStrategy(this.moduleRegistry);
|
|
157
|
+
this.versionManager = new VersionManager(this.moduleRegistry, versionUpdateStrategy);
|
|
158
|
+
// Initialize version applier and apply changes
|
|
159
|
+
const versionApplierOptions = {
|
|
160
|
+
dryRun: this.options.dryRun,
|
|
161
|
+
};
|
|
162
|
+
this.versionApplier = new VersionApplier(this.versionManager, versionApplierOptions);
|
|
163
|
+
const changedModules = await this.versionApplier.applyVersionChanges(processedModuleChanges);
|
|
164
|
+
// Generate changelogs
|
|
165
|
+
const changelogPaths = await this.changelogGenerator.generateChangelogs(changedModules, moduleCommits);
|
|
166
|
+
// Initialize git operations service
|
|
167
|
+
const gitOperationsOptions = {
|
|
168
|
+
pushChanges: this.options.pushChanges,
|
|
169
|
+
pushTags: this.options.pushTags,
|
|
170
|
+
repoRoot: this.options.repoRoot,
|
|
171
|
+
dryRun: this.options.dryRun,
|
|
172
|
+
isTemporaryVersion: this.options.prereleaseMode || this.options.appendSnapshot,
|
|
173
|
+
};
|
|
174
|
+
this.gitOperations = new GitOperations(gitOperationsOptions);
|
|
175
|
+
// Commit and push changes
|
|
176
|
+
await this.gitOperations.commitAndPushChanges(changedModules);
|
|
177
|
+
// Create and push tags
|
|
178
|
+
const createdTags = await this.gitOperations.createAndPushTags(changedModules);
|
|
179
|
+
logger.info("✅ VERSU semantic evolution completed successfully!");
|
|
180
|
+
return {
|
|
181
|
+
bumped: true,
|
|
182
|
+
discoveredModules,
|
|
183
|
+
changedModules,
|
|
184
|
+
createdTags,
|
|
185
|
+
changelogPaths,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../src/utils/banner.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,MAAM,EAAE,MASpB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { VERSION, PACKAGE_NAME } from "./version.js";
|
|
2
|
+
const info = `${PACKAGE_NAME} v${VERSION}`;
|
|
3
|
+
export const banner = `
|
|
4
|
+
██╗ ██╗███████╗██████╗ ███████╗██╗ ██╗
|
|
5
|
+
██║ ██║██╔════╝██╔══██╗██╔════╝██║ ██║
|
|
6
|
+
██║ ██║█████╗ ██████╔╝███████╗██║ ██║
|
|
7
|
+
╚██╗ ██╔╝██╔══╝ ██╔══██╗╚════██║██║ ██║
|
|
8
|
+
╚████╔╝ ███████╗██║ ██║███████║╚██████╔╝
|
|
9
|
+
╚═══╝ ╚══════╝╚═╝ ╚═╝╚══════╝ ╚═════╝
|
|
10
|
+
|
|
11
|
+
${info.padStart(44)}
|
|
12
|
+
`;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Commit } from "conventional-commits-parser";
|
|
2
|
+
import { Config } from "../config/index.js";
|
|
3
|
+
import { BumpType } from "../semver/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* Calculates the overall semantic version bump type from a collection of commits.
|
|
6
|
+
* Returns the highest bump type: major > minor > patch > none.
|
|
7
|
+
* @param commits - Array of commit information to analyze
|
|
8
|
+
* @param config - Configuration containing commit type mappings
|
|
9
|
+
* @returns The highest BumpType required across all commits
|
|
10
|
+
*/
|
|
11
|
+
export declare function calculateBumpFromCommits(commits: Commit[], config: Config): BumpType;
|
|
12
|
+
//# sourceMappingURL=commits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commits.d.ts","sourceRoot":"","sources":["../../src/utils/commits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAwB,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAe,MAAM,oBAAoB,CAAC;AAE3D;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,GACb,QAAQ,CAiBV"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { getBumpTypeForCommit } from "../config/index.js";
|
|
2
|
+
import { maxBumpType } from "../semver/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Calculates the overall semantic version bump type from a collection of commits.
|
|
5
|
+
* Returns the highest bump type: major > minor > patch > none.
|
|
6
|
+
* @param commits - Array of commit information to analyze
|
|
7
|
+
* @param config - Configuration containing commit type mappings
|
|
8
|
+
* @returns The highest BumpType required across all commits
|
|
9
|
+
*/
|
|
10
|
+
export function calculateBumpFromCommits(commits, config) {
|
|
11
|
+
// Collect bump types for all commits
|
|
12
|
+
const bumpTypes = [];
|
|
13
|
+
// Analyze each commit and determine its version impact
|
|
14
|
+
for (const commit of commits) {
|
|
15
|
+
const bumpType = getBumpTypeForCommit(commit, config);
|
|
16
|
+
// Only include commits that require a version bump
|
|
17
|
+
if (bumpType !== "none") {
|
|
18
|
+
bumpTypes.push(bumpType);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// Return the highest bump type required across all commits
|
|
22
|
+
// If no meaningful commits found, returns 'none'
|
|
23
|
+
return maxBumpType(bumpTypes);
|
|
24
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks whether a file or directory exists at the specified path.
|
|
3
|
+
* @param path - Absolute or relative path to check
|
|
4
|
+
* @returns True if the path exists and is accessible, false otherwise
|
|
5
|
+
*/
|
|
6
|
+
export declare function exists(path: string): Promise<boolean>;
|
|
7
|
+
//# sourceMappingURL=file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/utils/file.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAW3D"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
/**
|
|
3
|
+
* Checks whether a file or directory exists at the specified path.
|
|
4
|
+
* @param path - Absolute or relative path to check
|
|
5
|
+
* @returns True if the path exists and is accessible, false otherwise
|
|
6
|
+
*/
|
|
7
|
+
export async function exists(path) {
|
|
8
|
+
try {
|
|
9
|
+
// Attempt to access the path
|
|
10
|
+
// If access succeeds, the path exists and is accessible
|
|
11
|
+
await fs.access(path);
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// If access fails (any error), consider path as non-existent
|
|
16
|
+
// This includes ENOENT (doesn't exist) and EACCES (no permission)
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface Logger {
|
|
2
|
+
debug(message: string): void;
|
|
3
|
+
info(message: string): void;
|
|
4
|
+
warning(message: string | Error, context?: Record<string, unknown>): void;
|
|
5
|
+
error(message: string | Error, context?: Record<string, unknown>): void;
|
|
6
|
+
}
|
|
7
|
+
export declare function initLogger(logger: Logger): void;
|
|
8
|
+
/**
|
|
9
|
+
* Convenience proxy so existing call sites can
|
|
10
|
+
* import `logger` and call methods. The proxy delegates
|
|
11
|
+
* to the mutable `_current` at call-time.
|
|
12
|
+
*/
|
|
13
|
+
export declare const logger: Logger;
|
|
14
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1E,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACzE;AAYD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,QAExC;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,EAAE,MAOpB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// default no-op
|
|
2
|
+
const noopLogger = {
|
|
3
|
+
debug: (_message) => { },
|
|
4
|
+
info: (_message) => { },
|
|
5
|
+
warning: (_message, _context) => { },
|
|
6
|
+
error: (_message, _context) => { },
|
|
7
|
+
};
|
|
8
|
+
let _current = noopLogger;
|
|
9
|
+
export function initLogger(logger) {
|
|
10
|
+
_current = logger;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Convenience proxy so existing call sites can
|
|
14
|
+
* import `logger` and call methods. The proxy delegates
|
|
15
|
+
* to the mutable `_current` at call-time.
|
|
16
|
+
*/
|
|
17
|
+
export const logger = {
|
|
18
|
+
debug: (message) => _current.debug(message),
|
|
19
|
+
info: (message) => _current.info(message),
|
|
20
|
+
warning: (message, context) => _current.warning(message, context),
|
|
21
|
+
error: (message, context) => _current.error(message, context),
|
|
22
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a generic properties file into key-value pairs
|
|
3
|
+
* Supports both '=' and ':' as delimiters
|
|
4
|
+
* Skips comments (lines starting with # or !) and empty lines
|
|
5
|
+
* @param propertiesPath - Path to the properties file
|
|
6
|
+
* @returns Map of property keys to values
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseProperties(propertiesPath: string): Promise<Map<string, string>>;
|
|
9
|
+
/**
|
|
10
|
+
* Updates or inserts a single property in a Java-style properties file.
|
|
11
|
+
* @param propertiesPath - Path to the properties file
|
|
12
|
+
* @param key - Property key to update or insert
|
|
13
|
+
* @param value - Property value to set
|
|
14
|
+
*/
|
|
15
|
+
export declare function upsertProperty(propertiesPath: string, key: string, value: string): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Updates or inserts multiple properties in a Java-style properties file.
|
|
18
|
+
* Updates existing properties in place, appends new ones to the end.
|
|
19
|
+
* @param propertiesPath - Path to the properties file
|
|
20
|
+
* @param properties - Map of property keys to values
|
|
21
|
+
* @throws {Error} If file operations fail
|
|
22
|
+
*/
|
|
23
|
+
export declare function upsertProperties(propertiesPath: string, properties: Map<string, string>): Promise<void>;
|
|
24
|
+
//# sourceMappingURL=properties.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../../src/utils/properties.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAiC9B;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,cAAc,EAAE,MAAM,EACtB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,OAAO,CAAC,IAAI,CAAC,CAgDf"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
import { exists } from "./file.js";
|
|
3
|
+
/**
|
|
4
|
+
* Parse a generic properties file into key-value pairs
|
|
5
|
+
* Supports both '=' and ':' as delimiters
|
|
6
|
+
* Skips comments (lines starting with # or !) and empty lines
|
|
7
|
+
* @param propertiesPath - Path to the properties file
|
|
8
|
+
* @returns Map of property keys to values
|
|
9
|
+
*/
|
|
10
|
+
export async function parseProperties(propertiesPath) {
|
|
11
|
+
const content = await fs.readFile(propertiesPath, "utf8");
|
|
12
|
+
const properties = new Map();
|
|
13
|
+
// Parse all properties line by line
|
|
14
|
+
const lines = content.split("\n");
|
|
15
|
+
for (const line of lines) {
|
|
16
|
+
const trimmedLine = line.trim();
|
|
17
|
+
// Skip comments and empty lines
|
|
18
|
+
if (trimmedLine.startsWith("#") ||
|
|
19
|
+
trimmedLine.startsWith("!") ||
|
|
20
|
+
!trimmedLine) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
// Parse property: key=value or key:value
|
|
24
|
+
const match = trimmedLine.match(/^([^=:]+)[=:]\s*(.+)$/);
|
|
25
|
+
if (!match) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const [, key, value] = match;
|
|
29
|
+
const trimmedKey = key.trim();
|
|
30
|
+
const trimmedValue = value.trim();
|
|
31
|
+
properties.set(trimmedKey, trimmedValue);
|
|
32
|
+
}
|
|
33
|
+
return properties;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Updates or inserts a single property in a Java-style properties file.
|
|
37
|
+
* @param propertiesPath - Path to the properties file
|
|
38
|
+
* @param key - Property key to update or insert
|
|
39
|
+
* @param value - Property value to set
|
|
40
|
+
*/
|
|
41
|
+
export async function upsertProperty(propertiesPath, key, value) {
|
|
42
|
+
// Delegate to batch function with single-entry map
|
|
43
|
+
await upsertProperties(propertiesPath, new Map([[key, value]]));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Updates or inserts multiple properties in a Java-style properties file.
|
|
47
|
+
* Updates existing properties in place, appends new ones to the end.
|
|
48
|
+
* @param propertiesPath - Path to the properties file
|
|
49
|
+
* @param properties - Map of property keys to values
|
|
50
|
+
* @throws {Error} If file operations fail
|
|
51
|
+
*/
|
|
52
|
+
export async function upsertProperties(propertiesPath, properties) {
|
|
53
|
+
// Early return for empty updates (optimization)
|
|
54
|
+
if (properties.size === 0) {
|
|
55
|
+
return; // Nothing to update
|
|
56
|
+
}
|
|
57
|
+
// Check if properties file already exists
|
|
58
|
+
const propertiesExist = await exists(propertiesPath);
|
|
59
|
+
let updatedContent;
|
|
60
|
+
if (propertiesExist) {
|
|
61
|
+
// File exists - read current content and update properties
|
|
62
|
+
let content = await fs.readFile(propertiesPath, "utf8");
|
|
63
|
+
// Process each property update
|
|
64
|
+
for (const [key, value] of properties) {
|
|
65
|
+
// Escape special regex characters in property key
|
|
66
|
+
// This ensures keys like 'my.app.version' don't become regex patterns
|
|
67
|
+
const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
68
|
+
// Match property lines: key=value or key:value (with optional whitespace)
|
|
69
|
+
// Anchored to line start (^) and end ($) with multiline flag (m)
|
|
70
|
+
const propertyRegex = new RegExp(`^${escapedKey}\\s*[=:]\\s*.*$`, "m");
|
|
71
|
+
if (propertyRegex.test(content)) {
|
|
72
|
+
// Property exists - replace the line with updated value
|
|
73
|
+
content = content.replace(propertyRegex, `${key}=${value}`);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Property doesn't exist - append to end of file
|
|
77
|
+
// Add newline separator if file doesn't end with one
|
|
78
|
+
const separator = content.endsWith("\n") ? "" : "\n";
|
|
79
|
+
content = content + separator + `${key}=${value}\n`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
updatedContent = content;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// File doesn't exist - create new properties content
|
|
86
|
+
const lines = [];
|
|
87
|
+
for (const [key, value] of properties) {
|
|
88
|
+
lines.push(`${key}=${value}`);
|
|
89
|
+
}
|
|
90
|
+
updatedContent = lines.join("\n") + "\n";
|
|
91
|
+
}
|
|
92
|
+
// Write updated content to file (creates or overwrites)
|
|
93
|
+
await fs.writeFile(propertiesPath, updatedContent, "utf8");
|
|
94
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,YAAY,gBAAgB,CAAC"}
|