@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,163 @@
|
|
|
1
|
+
import groovy.json.JsonOutput
|
|
2
|
+
import groovy.json.JsonGenerator
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Retrieves the qualified version property name for the project.
|
|
6
|
+
* Checks for properties in the order: "<projectName>.version", "<rootProjectName>.version", "version".
|
|
7
|
+
*/
|
|
8
|
+
fun Project.qualifiedVersionProperty(): String {
|
|
9
|
+
val candidates = listOf("${name}.version", "${rootProject.name}.version", "version")
|
|
10
|
+
return candidates.first(::hasProperty)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Retrieves the qualified version value for the project.
|
|
15
|
+
* Uses the qualified version property name to find the property value.
|
|
16
|
+
*/
|
|
17
|
+
fun Project.qualifiedVersion(): String =
|
|
18
|
+
qualifiedVersionProperty().run(::findProperty) as String
|
|
19
|
+
|
|
20
|
+
gradle.rootProject {
|
|
21
|
+
/**
|
|
22
|
+
* Collects and outputs project structure information as JSON.
|
|
23
|
+
* Includes module hierarchy, paths, versions, and affected modules.
|
|
24
|
+
*/
|
|
25
|
+
tasks.register("printProjectInformation") {
|
|
26
|
+
group = "help"
|
|
27
|
+
description = "Shows which subprojects are affected by changes (hierarchy + direct dependencies)."
|
|
28
|
+
notCompatibleWithConfigurationCache("uses project information at configuration time")
|
|
29
|
+
|
|
30
|
+
// Capture hierarchy data at configuration time
|
|
31
|
+
val hierarchyDepsProvider = provider {
|
|
32
|
+
val hierarchyEdges = linkedMapOf<String, Set<String>>()
|
|
33
|
+
|
|
34
|
+
gradle.rootProject.allprojects.forEach { project ->
|
|
35
|
+
val affectedChildren = mutableSetOf<String>()
|
|
36
|
+
|
|
37
|
+
// Recursively collect all subprojects
|
|
38
|
+
fun collectSubprojects(parent: org.gradle.api.Project) {
|
|
39
|
+
parent.subprojects.forEach { child ->
|
|
40
|
+
affectedChildren.add(child.path)
|
|
41
|
+
collectSubprojects(child)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
collectSubprojects(project)
|
|
46
|
+
hierarchyEdges[project.path] = affectedChildren.toSet()
|
|
47
|
+
}
|
|
48
|
+
hierarchyEdges
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Capture direct project dependencies at configuration time
|
|
52
|
+
val dependencyDepsProvider = provider {
|
|
53
|
+
val dependencyEdges = linkedMapOf<String, Set<String>>()
|
|
54
|
+
|
|
55
|
+
gradle.rootProject.allprojects.forEach { project ->
|
|
56
|
+
val directDeps = mutableSetOf<String>()
|
|
57
|
+
|
|
58
|
+
project.configurations.forEach { config ->
|
|
59
|
+
// Check regular dependencies
|
|
60
|
+
config.dependencies.forEach { dep ->
|
|
61
|
+
if (dep is ProjectDependency) {
|
|
62
|
+
directDeps.add(dep.path)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Check dependency constraints (platform/BOM imports)
|
|
67
|
+
config.dependencyConstraints.forEach { constraint ->
|
|
68
|
+
// Constraints reference projects by group:name, need to resolve to project path
|
|
69
|
+
val constraintProject = gradle.rootProject.allprojects.find { proj ->
|
|
70
|
+
proj.group.toString() == constraint.group && proj.name == constraint.name
|
|
71
|
+
}
|
|
72
|
+
constraintProject?.let { directDeps.add(it.path) }
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
dependencyEdges[project.path] = directDeps.toSet()
|
|
77
|
+
}
|
|
78
|
+
dependencyEdges
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Capture project metadata at configuration time
|
|
82
|
+
val projectDataProvider = provider {
|
|
83
|
+
val projectData = linkedMapOf<String, Map<String, Any?>>()
|
|
84
|
+
|
|
85
|
+
gradle.rootProject.allprojects.forEach { project ->
|
|
86
|
+
val relativePath = gradle.rootProject.projectDir.toPath().relativize(project.projectDir.toPath()).toString()
|
|
87
|
+
val path = relativePath.ifEmpty { "." }
|
|
88
|
+
val version = if (project.version == "unspecified") null else project.version
|
|
89
|
+
val type = if (project == gradle.rootProject) "root" else "module"
|
|
90
|
+
val versionProperty = project.qualifiedVersionProperty()
|
|
91
|
+
val versionFromProperty = project.qualifiedVersion().takeIf {
|
|
92
|
+
it.isNotBlank() && it != "unspecified"
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
projectData[project.path] = mapOf(
|
|
96
|
+
"path" to path,
|
|
97
|
+
"version" to version,
|
|
98
|
+
"type" to type,
|
|
99
|
+
"name" to project.name,
|
|
100
|
+
"declaredVersion" to (versionFromProperty != null),
|
|
101
|
+
"versionProperty" to versionProperty
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
projectData
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
doLast {
|
|
108
|
+
val hierarchyMap = hierarchyDepsProvider.get()
|
|
109
|
+
val dependencyMap = dependencyDepsProvider.get()
|
|
110
|
+
val projectDataMap = projectDataProvider.get()
|
|
111
|
+
|
|
112
|
+
// Calculate directly affected modules only
|
|
113
|
+
val result = projectDataMap.keys.sorted().associateWith { projectPath ->
|
|
114
|
+
val projectInfo = projectDataMap.getValue(projectPath)
|
|
115
|
+
val affectedModules = mutableSetOf<String>()
|
|
116
|
+
|
|
117
|
+
// Add hierarchy children
|
|
118
|
+
hierarchyMap[projectPath]?.let { affectedModules.addAll(it) }
|
|
119
|
+
|
|
120
|
+
// Add projects that directly depend on this one
|
|
121
|
+
dependencyMap.forEach { (dependent, dependencies) ->
|
|
122
|
+
if (projectPath in dependencies) {
|
|
123
|
+
affectedModules.add(dependent)
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
mapOf(
|
|
128
|
+
"path" to projectInfo["path"],
|
|
129
|
+
"affectedModules" to affectedModules.toSortedSet(),
|
|
130
|
+
"type" to projectInfo["type"],
|
|
131
|
+
"name" to projectInfo["name"],
|
|
132
|
+
"versionProperty" to projectInfo["versionProperty"]
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
val generator = JsonGenerator.Options()
|
|
137
|
+
.excludeNulls()
|
|
138
|
+
.build()
|
|
139
|
+
|
|
140
|
+
val json = JsonOutput.prettyPrint(generator.toJson(result))
|
|
141
|
+
|
|
142
|
+
// Get output path from project property or use default
|
|
143
|
+
val outputPath = project.findProperty("projectInfoOutput") as? String
|
|
144
|
+
?: "${layout.buildDirectory.asFile.get().path}/project-information.json"
|
|
145
|
+
|
|
146
|
+
val outputFile = file(outputPath)
|
|
147
|
+
outputFile.parentFile.mkdirs()
|
|
148
|
+
outputFile.writeText(json)
|
|
149
|
+
|
|
150
|
+
println("Project information written to: ${outputFile.absolutePath}")
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Convenience alias for printProjectInformation task.
|
|
156
|
+
* Usage: ./gradlew --init-script <path> structure
|
|
157
|
+
*/
|
|
158
|
+
tasks.register("structure") {
|
|
159
|
+
group = "help"
|
|
160
|
+
description = "Show project structure information"
|
|
161
|
+
dependsOn("printProjectInformation")
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AdapterIdentifier } from '../../../services/adapter-identifier.js';
|
|
2
|
+
/**
|
|
3
|
+
* Adapter identifier for Gradle-based projects.
|
|
4
|
+
* Detects Gradle projects by looking for gradle.properties, build.gradle(.kts), or settings.gradle(.kts) files.
|
|
5
|
+
*/
|
|
6
|
+
export declare class GradleAdapterIdentifier implements AdapterIdentifier {
|
|
7
|
+
/** Metadata describing this Gradle adapter (id: 'gradle', supports snapshots). */
|
|
8
|
+
readonly metadata: {
|
|
9
|
+
id: string;
|
|
10
|
+
capabilities: {
|
|
11
|
+
supportsSnapshots: boolean;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Determines whether the specified project is a Gradle project.
|
|
16
|
+
* @param projectRoot - Absolute path to the project root directory
|
|
17
|
+
* @returns True if any Gradle-specific file is found in the project root
|
|
18
|
+
*/
|
|
19
|
+
accept(projectRoot: string): Promise<boolean>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=gradle-adapter-identifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gradle-adapter-identifier.d.ts","sourceRoot":"","sources":["../../../../src/adapters/gradle/services/gradle-adapter-identifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAe5E;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,iBAAiB;IAC/D,kFAAkF;IAClF,QAAQ,CAAC,QAAQ;;;;;MAKf;IAEF;;;;OAIG;IACG,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAkBpD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import { GRADLE_PROPERTIES_FILE, GRADLE_BUILD_FILE, GRADLE_BUILD_KTS_FILE, GRADLE_SETTINGS_FILE, GRADLE_SETTINGS_KTS_FILE, GRADLE_ID } from '../constants.js';
|
|
3
|
+
import { exists } from '../../../utils/file.js';
|
|
4
|
+
import { logger } from '../../../utils/logger.js';
|
|
5
|
+
/** List of file names that indicate a Gradle project. */
|
|
6
|
+
const GRADLE_FILES = [
|
|
7
|
+
GRADLE_PROPERTIES_FILE,
|
|
8
|
+
GRADLE_BUILD_FILE,
|
|
9
|
+
GRADLE_BUILD_KTS_FILE,
|
|
10
|
+
GRADLE_SETTINGS_FILE,
|
|
11
|
+
GRADLE_SETTINGS_KTS_FILE
|
|
12
|
+
];
|
|
13
|
+
/**
|
|
14
|
+
* Adapter identifier for Gradle-based projects.
|
|
15
|
+
* Detects Gradle projects by looking for gradle.properties, build.gradle(.kts), or settings.gradle(.kts) files.
|
|
16
|
+
*/
|
|
17
|
+
export class GradleAdapterIdentifier {
|
|
18
|
+
/** Metadata describing this Gradle adapter (id: 'gradle', supports snapshots). */
|
|
19
|
+
metadata = {
|
|
20
|
+
id: GRADLE_ID,
|
|
21
|
+
capabilities: {
|
|
22
|
+
supportsSnapshots: true
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Determines whether the specified project is a Gradle project.
|
|
27
|
+
* @param projectRoot - Absolute path to the project root directory
|
|
28
|
+
* @returns True if any Gradle-specific file is found in the project root
|
|
29
|
+
*/
|
|
30
|
+
async accept(projectRoot) {
|
|
31
|
+
// Check if project root directory exists
|
|
32
|
+
const projectRootExists = await exists(projectRoot);
|
|
33
|
+
if (!projectRootExists) {
|
|
34
|
+
// Log for debugging and return false immediately
|
|
35
|
+
logger.debug(`Project root does not exist: ${projectRoot}`);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
// Read directory contents (only top-level files)
|
|
39
|
+
const files = await fs.readdir(projectRoot);
|
|
40
|
+
// Check if any known Gradle file is present in the directory
|
|
41
|
+
const hasGradleFile = GRADLE_FILES.some(file => files.includes(file));
|
|
42
|
+
return hasGradleFile;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ModuleDetector } from "../../../services/module-detector.js";
|
|
2
|
+
import { ModuleRegistry } from '../../../services/module-registry.js';
|
|
3
|
+
/**
|
|
4
|
+
* Module detector for Gradle-based projects.
|
|
5
|
+
* Executes Gradle to discover all modules and their dependencies, returning a ModuleRegistry.
|
|
6
|
+
*/
|
|
7
|
+
export declare class GradleModuleDetector implements ModuleDetector {
|
|
8
|
+
readonly repoRoot: string;
|
|
9
|
+
readonly outputFile: string;
|
|
10
|
+
/** Absolute path to the repository root directory. */
|
|
11
|
+
constructor(repoRoot: string, outputFile: string);
|
|
12
|
+
/**
|
|
13
|
+
* Detects and catalogs all modules in the Gradle project.
|
|
14
|
+
* @returns ModuleRegistry containing all discovered modules and their relationships
|
|
15
|
+
* @throws {Error} If Gradle execution fails or project information cannot be parsed
|
|
16
|
+
*/
|
|
17
|
+
detect(): Promise<ModuleRegistry>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=gradle-module-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gradle-module-detector.d.ts","sourceRoot":"","sources":["../../../../src/adapters/gradle/services/gradle-module-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAMtE;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IAE7C,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAAE,QAAQ,CAAC,UAAU,EAAE,MAAM;IADlE,sDAAsD;gBACjC,QAAQ,EAAE,MAAM,EAAW,UAAU,EAAE,MAAM;IAElE;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;CAUxC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ModuleRegistry } from '../../../services/module-registry.js';
|
|
2
|
+
import { getRawProjectInformation, getProjectInformation } from '../gradle-project-information.js';
|
|
3
|
+
/**
|
|
4
|
+
* Module detector for Gradle-based projects.
|
|
5
|
+
* Executes Gradle to discover all modules and their dependencies, returning a ModuleRegistry.
|
|
6
|
+
*/
|
|
7
|
+
export class GradleModuleDetector {
|
|
8
|
+
repoRoot;
|
|
9
|
+
outputFile;
|
|
10
|
+
/** Absolute path to the repository root directory. */
|
|
11
|
+
constructor(repoRoot, outputFile) {
|
|
12
|
+
this.repoRoot = repoRoot;
|
|
13
|
+
this.outputFile = outputFile;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Detects and catalogs all modules in the Gradle project.
|
|
17
|
+
* @returns ModuleRegistry containing all discovered modules and their relationships
|
|
18
|
+
* @throws {Error} If Gradle execution fails or project information cannot be parsed
|
|
19
|
+
*/
|
|
20
|
+
async detect() {
|
|
21
|
+
// Step 1: Execute Gradle and collect raw project structure data
|
|
22
|
+
const rawProjectInformation = await getRawProjectInformation(this.repoRoot, this.outputFile);
|
|
23
|
+
// Step 2: Parse and transform raw data into structured module information
|
|
24
|
+
const projectInformation = getProjectInformation(rawProjectInformation);
|
|
25
|
+
// Step 3: Create a registry for efficient module access and querying
|
|
26
|
+
return new ModuleRegistry(projectInformation);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ModuleSystemFactory } from "../../../services/module-system-factory.js";
|
|
2
|
+
import { ModuleDetector } from "../../../services/module-detector.js";
|
|
3
|
+
import { VersionUpdateStrategy } from "../../../services/version-update-strategy.js";
|
|
4
|
+
import { ModuleRegistry } from "../../../services/module-registry.js";
|
|
5
|
+
/**
|
|
6
|
+
* Factory for creating Gradle-specific module system components.
|
|
7
|
+
* Creates module detector and version update strategy instances.
|
|
8
|
+
*/
|
|
9
|
+
export declare class GradleModuleSystemFactory implements ModuleSystemFactory {
|
|
10
|
+
private readonly repoRoot;
|
|
11
|
+
/** Absolute path to the repository root directory. */
|
|
12
|
+
constructor(repoRoot: string);
|
|
13
|
+
/**
|
|
14
|
+
* Creates a Gradle-specific module detector.
|
|
15
|
+
* @param outputFile - Path to the output file for project information
|
|
16
|
+
* @returns GradleModuleDetector instance configured with the repository root
|
|
17
|
+
*/
|
|
18
|
+
createDetector(outputFile: string): ModuleDetector;
|
|
19
|
+
/**
|
|
20
|
+
* Creates a Gradle-specific version update strategy.
|
|
21
|
+
* @param moduleRegistry - ModuleRegistry containing all detected modules
|
|
22
|
+
* @returns GradleVersionUpdateStrategy instance configured with the repository root
|
|
23
|
+
*/
|
|
24
|
+
createVersionUpdateStrategy(moduleRegistry: ModuleRegistry): VersionUpdateStrategy;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=gradle-module-system-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gradle-module-system-factory.d.ts","sourceRoot":"","sources":["../../../../src/adapters/gradle/services/gradle-module-system-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AAGrF,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAEtE;;;GAGG;AACH,qBAAa,yBAA0B,YAAW,mBAAmB;IAEvD,OAAO,CAAC,QAAQ,CAAC,QAAQ;IADrC,sDAAsD;gBACzB,QAAQ,EAAE,MAAM;IAE7C;;;;OAIG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc;IAIlD;;;;OAIG;IACH,2BAA2B,CAAC,cAAc,EAAE,cAAc,GAAG,qBAAqB;CAGnF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { GradleModuleDetector } from './gradle-module-detector.js';
|
|
2
|
+
import { GradleVersionUpdateStrategy } from './gradle-version-update-strategy.js';
|
|
3
|
+
/**
|
|
4
|
+
* Factory for creating Gradle-specific module system components.
|
|
5
|
+
* Creates module detector and version update strategy instances.
|
|
6
|
+
*/
|
|
7
|
+
export class GradleModuleSystemFactory {
|
|
8
|
+
repoRoot;
|
|
9
|
+
/** Absolute path to the repository root directory. */
|
|
10
|
+
constructor(repoRoot) {
|
|
11
|
+
this.repoRoot = repoRoot;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a Gradle-specific module detector.
|
|
15
|
+
* @param outputFile - Path to the output file for project information
|
|
16
|
+
* @returns GradleModuleDetector instance configured with the repository root
|
|
17
|
+
*/
|
|
18
|
+
createDetector(outputFile) {
|
|
19
|
+
return new GradleModuleDetector(this.repoRoot, outputFile);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Creates a Gradle-specific version update strategy.
|
|
23
|
+
* @param moduleRegistry - ModuleRegistry containing all detected modules
|
|
24
|
+
* @returns GradleVersionUpdateStrategy instance configured with the repository root
|
|
25
|
+
*/
|
|
26
|
+
createVersionUpdateStrategy(moduleRegistry) {
|
|
27
|
+
return new GradleVersionUpdateStrategy(this.repoRoot, moduleRegistry);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { VersionUpdateStrategy } from "../../../services/version-update-strategy.js";
|
|
2
|
+
import { ModuleRegistry } from '../../../services/module-registry.js';
|
|
3
|
+
/**
|
|
4
|
+
* Gradle-specific implementation for version update operations.
|
|
5
|
+
* Updates module versions by modifying gradle.properties file.
|
|
6
|
+
*/
|
|
7
|
+
export declare class GradleVersionUpdateStrategy implements VersionUpdateStrategy {
|
|
8
|
+
private readonly moduleRegistry;
|
|
9
|
+
/** Absolute path to the gradle.properties file. */
|
|
10
|
+
private readonly versionFilePath;
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new Gradle version update strategy.
|
|
13
|
+
* @param repoRoot - Absolute path to the repository root directory
|
|
14
|
+
*/
|
|
15
|
+
constructor(repoRoot: string, moduleRegistry: ModuleRegistry);
|
|
16
|
+
/**
|
|
17
|
+
* Writes version updates for multiple modules to gradle.properties.
|
|
18
|
+
* @param moduleVersions - Map of module IDs to new version strings
|
|
19
|
+
* @throws {Error} If the file cannot be read or written
|
|
20
|
+
*/
|
|
21
|
+
writeVersionUpdates(moduleVersions: Map<string, string>): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=gradle-version-update-strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gradle-version-update-strategy.d.ts","sourceRoot":"","sources":["../../../../src/adapters/gradle/services/gradle-version-update-strategy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AAGrF,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAEtE;;;GAGG;AACH,qBAAa,2BAA4B,YAAW,qBAAqB;IAQzC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAP7D,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC;;;OAGG;gBACS,QAAQ,EAAE,MAAM,EAAmB,cAAc,EAAE,cAAc;IAI7E;;;;OAIG;IACG,mBAAmB,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAe9E"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
import { upsertProperties } from '../../../utils/properties.js';
|
|
3
|
+
import { GRADLE_PROPERTIES_FILE } from '../constants.js';
|
|
4
|
+
/**
|
|
5
|
+
* Gradle-specific implementation for version update operations.
|
|
6
|
+
* Updates module versions by modifying gradle.properties file.
|
|
7
|
+
*/
|
|
8
|
+
export class GradleVersionUpdateStrategy {
|
|
9
|
+
moduleRegistry;
|
|
10
|
+
/** Absolute path to the gradle.properties file. */
|
|
11
|
+
versionFilePath;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new Gradle version update strategy.
|
|
14
|
+
* @param repoRoot - Absolute path to the repository root directory
|
|
15
|
+
*/
|
|
16
|
+
constructor(repoRoot, moduleRegistry) {
|
|
17
|
+
this.moduleRegistry = moduleRegistry;
|
|
18
|
+
this.versionFilePath = join(repoRoot, GRADLE_PROPERTIES_FILE);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Writes version updates for multiple modules to gradle.properties.
|
|
22
|
+
* @param moduleVersions - Map of module IDs to new version strings
|
|
23
|
+
* @throws {Error} If the file cannot be read or written
|
|
24
|
+
*/
|
|
25
|
+
async writeVersionUpdates(moduleVersions) {
|
|
26
|
+
// Convert module IDs to property names
|
|
27
|
+
// Example: ':app' → 'app.version', ':' → 'version'
|
|
28
|
+
const propertyUpdates = new Map();
|
|
29
|
+
for (const [moduleId, versionString] of moduleVersions) {
|
|
30
|
+
const module = this.moduleRegistry.getModule(moduleId);
|
|
31
|
+
const propertyName = module['versionProperty'];
|
|
32
|
+
propertyUpdates.set(propertyName, versionString);
|
|
33
|
+
}
|
|
34
|
+
// Write all properties to gradle.properties file in one atomic operation
|
|
35
|
+
// This ensures consistency and prevents partial updates
|
|
36
|
+
await upsertProperties(this.versionFilePath, propertyUpdates);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { SemVer } from "semver";
|
|
2
|
+
/**
|
|
3
|
+
* Represents a module within a project, containing metadata, version, and dependency information.
|
|
4
|
+
*/
|
|
5
|
+
export type Module = {
|
|
6
|
+
/** Unique identifier for the module within the project (e.g., ':', ':app', ':lib:core'). */
|
|
7
|
+
readonly id: string;
|
|
8
|
+
/** Human-readable name of the module. */
|
|
9
|
+
readonly name: string;
|
|
10
|
+
/** Relative path from the repository root to this module's directory. */
|
|
11
|
+
readonly path: string;
|
|
12
|
+
/** Type of the module: 'root' for top-level project or 'module' for subprojects. */
|
|
13
|
+
readonly type: "module" | "root";
|
|
14
|
+
/** Set of module IDs that are affected when this module changes. */
|
|
15
|
+
readonly affectedModules: Set<string>;
|
|
16
|
+
/** Current semantic version of the module. */
|
|
17
|
+
readonly version: SemVer;
|
|
18
|
+
/** Whether the version is explicitly declared in build configuration (vs inherited). */
|
|
19
|
+
readonly declaredVersion: boolean;
|
|
20
|
+
} & Record<string, unknown>;
|
|
21
|
+
/**
|
|
22
|
+
* Structured representation of project information after processing.
|
|
23
|
+
* Provides efficient access to module information through arrays and maps.
|
|
24
|
+
*/
|
|
25
|
+
export type ProjectInformation = {
|
|
26
|
+
/** Array of all module identifiers in the project. */
|
|
27
|
+
readonly moduleIds: string[];
|
|
28
|
+
/** Map of module IDs to their complete module information (O(1) lookup). */
|
|
29
|
+
readonly modules: ReadonlyMap<string, Module>;
|
|
30
|
+
/** The module ID of the root project (typically ':' for Gradle). */
|
|
31
|
+
readonly rootModule: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Base module data structure without the module ID and with version as a string.
|
|
35
|
+
*/
|
|
36
|
+
export type BaseModule = {
|
|
37
|
+
/** Human-readable name of the module. */
|
|
38
|
+
readonly name: string;
|
|
39
|
+
/** Relative path from repository root to the module directory. */
|
|
40
|
+
readonly path: string;
|
|
41
|
+
/** Array of module IDs affected when this module changes. */
|
|
42
|
+
readonly affectedModules: string[];
|
|
43
|
+
/** Version string if the module has a version (optional). */
|
|
44
|
+
readonly version?: string;
|
|
45
|
+
/** Type of the module in the project hierarchy. */
|
|
46
|
+
readonly type: "module" | "root";
|
|
47
|
+
/** Whether the version is explicitly declared in build configuration. */
|
|
48
|
+
readonly declaredVersion: boolean;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Raw module data as extracted from the build system before processing.
|
|
52
|
+
* Similar to Module but with arrays instead of Sets and optional string version.
|
|
53
|
+
*/
|
|
54
|
+
export type RawModule = BaseModule & Record<string, unknown>;
|
|
55
|
+
/**
|
|
56
|
+
* Raw project structure information as extracted from the build system.
|
|
57
|
+
* Maps module IDs to their raw module data.
|
|
58
|
+
*/
|
|
59
|
+
export type RawProjectInformation = {
|
|
60
|
+
readonly [id: string]: RawModule;
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=project-information.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-information.d.ts","sourceRoot":"","sources":["../../src/adapters/project-information.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IAEjC,oEAAoE;IACpE,QAAQ,CAAC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAEtC,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,wFAAwF;IACxF,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5B;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAE7B,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE9C,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,6DAA6D;IAC7D,QAAQ,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC;IAEnC,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAE1B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IAEjC,yEAAyE;IACzE,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE7D;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ModuleChangeResult } from "../services/version-applier.js";
|
|
2
|
+
import { Commit } from "conventional-commits-parser";
|
|
3
|
+
/** Update or create a changelog file for a module. */
|
|
4
|
+
export declare function updateChangelogFile(changelogContent: string, changelogPath: string, prependPlaceholder: string): Promise<void>;
|
|
5
|
+
/** Generate changelog for multiple modules. */
|
|
6
|
+
export declare function generateChangelogsForModules(moduleResults: ModuleChangeResult[], getCommitsForModule: (moduleId: string) => Promise<{
|
|
7
|
+
commits: Commit[];
|
|
8
|
+
lastTag: string | null;
|
|
9
|
+
}>, repoRoot: string): Promise<string[]>;
|
|
10
|
+
export declare function generateRootChangelog(moduleResults: ModuleChangeResult[], getCommitsForModule: (moduleId: string) => Promise<{
|
|
11
|
+
commits: Commit[];
|
|
12
|
+
lastTag: string | null;
|
|
13
|
+
}>, repoRoot: string): Promise<string | undefined>;
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/changelog/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAKrD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACvC,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,MAAM,EACrB,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC,CAWf;AAsBD,+CAA+C;AAC/C,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,kBAAkB,EAAE,EACnC,mBAAmB,EAAE,CACnB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,EAC3D,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,EAAE,CAAC,CAiFnB;AAED,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,kBAAkB,EAAE,EACnC,mBAAmB,EAAE,CACnB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,EAC3D,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAmF7B"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
import path, { join } from "path";
|
|
3
|
+
import { writeChangelogString } from "conventional-changelog-writer";
|
|
4
|
+
import { logger } from "../utils/logger.js";
|
|
5
|
+
import { exists } from "../utils/file.js";
|
|
6
|
+
import { getCurrentRepoUrl, parseRepoUrl } from "../git/index.js";
|
|
7
|
+
import { isReleaseVersion } from "../semver/index.js";
|
|
8
|
+
/** Update or create a changelog file for a module. */
|
|
9
|
+
export async function updateChangelogFile(changelogContent, changelogPath, prependPlaceholder) {
|
|
10
|
+
let fileContent = changelogContent;
|
|
11
|
+
if (await exists(changelogPath)) {
|
|
12
|
+
logger.info(`Updating existing changelog at ${changelogPath}...`);
|
|
13
|
+
// Try to read existing changelog
|
|
14
|
+
const existingContent = await fs.readFile(changelogPath, "utf8");
|
|
15
|
+
const newContent = `${prependPlaceholder}\n\n${changelogContent.trimEnd()}`;
|
|
16
|
+
fileContent = existingContent.replace(prependPlaceholder, newContent);
|
|
17
|
+
}
|
|
18
|
+
await fs.writeFile(changelogPath, fileContent, "utf8");
|
|
19
|
+
}
|
|
20
|
+
async function buildContextRepository(options = {}) {
|
|
21
|
+
const repoUrl = await getCurrentRepoUrl(options);
|
|
22
|
+
const { host, owner, repo } = parseRepoUrl(repoUrl);
|
|
23
|
+
return {
|
|
24
|
+
repoUrl: `https://${host}/${owner}/${repo}`,
|
|
25
|
+
host: `https://${host}`,
|
|
26
|
+
owner,
|
|
27
|
+
repository: repo,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Generate changelog for multiple modules. */
|
|
31
|
+
export async function generateChangelogsForModules(moduleResults, getCommitsForModule, repoRoot) {
|
|
32
|
+
const changelogPaths = [];
|
|
33
|
+
const configPath = path.resolve(repoRoot, "changelog.config.js");
|
|
34
|
+
if (!(await exists(configPath))) {
|
|
35
|
+
throw new Error(`Missing required changelog configuration file at ${configPath}`);
|
|
36
|
+
}
|
|
37
|
+
logger.info(`Loading changelog configuration from ${configPath}...`);
|
|
38
|
+
const userConfig = (await import(configPath)).default.module;
|
|
39
|
+
const prependPlaceholder = userConfig.context.prependPlaceholder;
|
|
40
|
+
if (!prependPlaceholder) {
|
|
41
|
+
throw new Error("Missing required context property 'prependPlaceholder' in changelog.config.js");
|
|
42
|
+
}
|
|
43
|
+
const contextRepository = await buildContextRepository({ cwd: repoRoot });
|
|
44
|
+
for (const moduleResult of moduleResults) {
|
|
45
|
+
if (!moduleResult.declaredVersion) {
|
|
46
|
+
logger.info(`Module ${moduleResult.id} has no declared version, skipping changelog generation...`);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const { commits, lastTag } = await getCommitsForModule(moduleResult.id);
|
|
50
|
+
if (commits.length === 0) {
|
|
51
|
+
logger.info(`No commits to include in changelog for module ${moduleResult.id}, skipping...`);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const changelogPath = join(repoRoot, moduleResult.path, "CHANGELOG.md");
|
|
55
|
+
let prepend = true;
|
|
56
|
+
if (await exists(changelogPath)) {
|
|
57
|
+
prepend = false;
|
|
58
|
+
}
|
|
59
|
+
const isRelease = isReleaseVersion(moduleResult.to);
|
|
60
|
+
const version = isRelease ? moduleResult.to : undefined;
|
|
61
|
+
const currentTag = isRelease
|
|
62
|
+
? `${moduleResult.name}@${moduleResult.to}`
|
|
63
|
+
: undefined;
|
|
64
|
+
const previousTag = lastTag || undefined;
|
|
65
|
+
const changelogContent = await writeChangelogString(commits, {
|
|
66
|
+
version: version,
|
|
67
|
+
previousTag: previousTag,
|
|
68
|
+
currentTag: currentTag,
|
|
69
|
+
linkCompare: previousTag && currentTag ? true : false,
|
|
70
|
+
...contextRepository,
|
|
71
|
+
...userConfig.context,
|
|
72
|
+
prepend,
|
|
73
|
+
}, userConfig.options);
|
|
74
|
+
logger.info(changelogContent);
|
|
75
|
+
await updateChangelogFile(changelogContent, changelogPath, prependPlaceholder);
|
|
76
|
+
changelogPaths.push(changelogPath);
|
|
77
|
+
}
|
|
78
|
+
return changelogPaths;
|
|
79
|
+
}
|
|
80
|
+
export async function generateRootChangelog(moduleResults, getCommitsForModule, repoRoot) {
|
|
81
|
+
const moduleResult = moduleResults.find((result) => result.type === "root");
|
|
82
|
+
if (!moduleResult) {
|
|
83
|
+
logger.info("No root module found, skipping root changelog generation...");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const configPath = path.resolve(repoRoot, "changelog.config.js");
|
|
87
|
+
if (!(await exists(configPath))) {
|
|
88
|
+
throw new Error(`Missing required changelog configuration file at ${configPath}`);
|
|
89
|
+
}
|
|
90
|
+
logger.info(`Loading root changelog configuration from ${configPath}...`);
|
|
91
|
+
const userConfig = (await import(configPath)).default.root;
|
|
92
|
+
const prependPlaceholder = userConfig.context.prependPlaceholder;
|
|
93
|
+
if (!prependPlaceholder) {
|
|
94
|
+
throw new Error("Missing required context property 'prependPlaceholder' in changelog.config.js");
|
|
95
|
+
}
|
|
96
|
+
const contextRepository = await buildContextRepository({ cwd: repoRoot });
|
|
97
|
+
/*if (!moduleResult.declaredVersion) {
|
|
98
|
+
logger.info(
|
|
99
|
+
`Module ${moduleResult.id} has no declared version, skipping changelog generation...`,
|
|
100
|
+
);
|
|
101
|
+
return;
|
|
102
|
+
}*/
|
|
103
|
+
const { commits, lastTag } = await getCommitsForModule(moduleResult.id);
|
|
104
|
+
if (commits.length === 0) {
|
|
105
|
+
logger.info(`No commits to include in changelog for module ${moduleResult.id}, skipping...`);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const changelogPath = join(repoRoot, moduleResult.path, "CHANGELOG.md");
|
|
109
|
+
let prepend = true;
|
|
110
|
+
if (await exists(changelogPath)) {
|
|
111
|
+
prepend = false;
|
|
112
|
+
}
|
|
113
|
+
const isRelease = isReleaseVersion(moduleResult.to);
|
|
114
|
+
const version = isRelease ? moduleResult.to : undefined;
|
|
115
|
+
const currentTag = isRelease
|
|
116
|
+
? `${moduleResult.name}@${moduleResult.to}`
|
|
117
|
+
: undefined;
|
|
118
|
+
const previousTag = lastTag || undefined;
|
|
119
|
+
const changelogContent = await writeChangelogString(commits, {
|
|
120
|
+
moduleResults,
|
|
121
|
+
version: version,
|
|
122
|
+
previousTag: previousTag,
|
|
123
|
+
currentTag: currentTag,
|
|
124
|
+
linkCompare: previousTag && currentTag ? true : false,
|
|
125
|
+
...contextRepository,
|
|
126
|
+
...userConfig.context,
|
|
127
|
+
prepend,
|
|
128
|
+
}, userConfig.options);
|
|
129
|
+
logger.info(changelogContent);
|
|
130
|
+
await updateChangelogFile(changelogContent, changelogPath, prependPlaceholder);
|
|
131
|
+
return changelogPath;
|
|
132
|
+
}
|