@nx/js 22.0.0-canary.20251002-3bac124 → 22.0.0-canary.20251006-738b06b
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/generators.json +0 -6
- package/package.json +4 -7
- package/src/generators/library/library.d.ts.map +1 -1
- package/src/generators/library/library.js +1 -2
- package/src/generators/library/utils/add-release-config.d.ts +1 -1
- package/src/generators/library/utils/add-release-config.d.ts.map +1 -1
- package/src/generators/library/utils/add-release-config.js +10 -26
- package/src/generators/release-version/release-version.d.ts +0 -5
- package/src/generators/release-version/release-version.d.ts.map +1 -1
- package/src/generators/release-version/release-version.js +0 -785
- package/src/release/utils/update-lock-file.d.ts +1 -2
- package/src/release/utils/update-lock-file.d.ts.map +1 -1
- package/src/release/utils/update-lock-file.js +6 -9
- package/src/release/version-actions.d.ts.map +1 -1
- package/src/release/version-actions.js +2 -3
- package/spec/jest.config.d.ts +0 -13
- package/spec/jest.config.d.ts.map +0 -1
- package/spec/migrations.spec.d.ts +0 -2
- package/spec/migrations.spec.d.ts.map +0 -1
- package/spec/src/executors/node/lib/detect-module-format.spec.d.ts +0 -2
- package/spec/src/executors/node/lib/detect-module-format.spec.d.ts.map +0 -1
- package/spec/src/executors/node/lib/esm-loader.spec.d.ts +0 -2
- package/spec/src/executors/node/lib/esm-loader.spec.d.ts.map +0 -1
- package/spec/src/executors/release-publish/extract-npm-publish-json-data.spec.d.ts +0 -2
- package/spec/src/executors/release-publish/extract-npm-publish-json-data.spec.d.ts.map +0 -1
- package/spec/src/executors/release-publish/release-publish.impl.spec.d.ts +0 -2
- package/spec/src/executors/release-publish/release-publish.impl.spec.d.ts.map +0 -1
- package/spec/src/executors/tsc/tsc.impl.spec.d.ts +0 -2
- package/spec/src/executors/tsc/tsc.impl.spec.d.ts.map +0 -1
- package/spec/src/generators/convert-to-swc/convert-to-swc.spec.d.ts +0 -2
- package/spec/src/generators/convert-to-swc/convert-to-swc.spec.d.ts.map +0 -1
- package/spec/src/generators/init/init.spec.d.ts +0 -2
- package/spec/src/generators/init/init.spec.d.ts.map +0 -1
- package/spec/src/generators/library/library.spec.d.ts +0 -2
- package/spec/src/generators/library/library.spec.d.ts.map +0 -1
- package/spec/src/generators/library/utils/add-release-config.spec.d.ts +0 -2
- package/spec/src/generators/library/utils/add-release-config.spec.d.ts.map +0 -1
- package/spec/src/generators/release-version/release-version-workspace-root-project.spec.d.ts +0 -2
- package/spec/src/generators/release-version/release-version-workspace-root-project.spec.d.ts.map +0 -1
- package/spec/src/generators/release-version/release-version.spec.d.ts +0 -2
- package/spec/src/generators/release-version/release-version.spec.d.ts.map +0 -1
- package/spec/src/generators/release-version/utils/resolve-local-package-dependencies.spec.d.ts +0 -2
- package/spec/src/generators/release-version/utils/resolve-local-package-dependencies.spec.d.ts.map +0 -1
- package/spec/src/generators/release-version/utils/resolve-version-spec.spec.d.ts +0 -2
- package/spec/src/generators/release-version/utils/resolve-version-spec.spec.d.ts.map +0 -1
- package/spec/src/generators/release-version/utils/sort-projects-topologically.spec.d.ts +0 -2
- package/spec/src/generators/release-version/utils/sort-projects-topologically.spec.d.ts.map +0 -1
- package/spec/src/generators/setup-build/generator.spec.d.ts +0 -2
- package/spec/src/generators/setup-build/generator.spec.d.ts.map +0 -1
- package/spec/src/generators/setup-prettier/generator.spec.d.ts +0 -2
- package/spec/src/generators/setup-prettier/generator.spec.d.ts.map +0 -1
- package/spec/src/generators/setup-verdaccio/generator.spec.d.ts +0 -2
- package/spec/src/generators/setup-verdaccio/generator.spec.d.ts.map +0 -1
- package/spec/src/generators/typescript-sync/typescript-sync.spec.d.ts +0 -2
- package/spec/src/generators/typescript-sync/typescript-sync.spec.d.ts.map +0 -1
- package/spec/src/migrations/update-21-5-0/migrate-development-custom-condition.spec.d.ts +0 -2
- package/spec/src/migrations/update-21-5-0/migrate-development-custom-condition.spec.d.ts.map +0 -1
- package/spec/src/migrations/update-22-0-0/remove-external-options-from-js-executors.spec.d.ts +0 -2
- package/spec/src/migrations/update-22-0-0/remove-external-options-from-js-executors.spec.d.ts.map +0 -1
- package/spec/src/plugins/rollup/type-definitions.spec.d.ts +0 -2
- package/spec/src/plugins/rollup/type-definitions.spec.d.ts.map +0 -1
- package/spec/src/plugins/typescript/plugin.spec.d.ts +0 -2
- package/spec/src/plugins/typescript/plugin.spec.d.ts.map +0 -1
- package/spec/src/plugins/typescript/util.spec.d.ts +0 -2
- package/spec/src/plugins/typescript/util.spec.d.ts.map +0 -1
- package/spec/src/release/utils/semver.spec.d.ts +0 -2
- package/spec/src/release/utils/semver.spec.d.ts.map +0 -1
- package/spec/src/utils/add-local-registry-scripts.spec.d.ts +0 -2
- package/spec/src/utils/add-local-registry-scripts.spec.d.ts.map +0 -1
- package/spec/src/utils/assets/copy-assets-handler.spec.d.ts +0 -2
- package/spec/src/utils/assets/copy-assets-handler.spec.d.ts.map +0 -1
- package/spec/src/utils/buildable-libs-utils.spec.d.ts +0 -2
- package/spec/src/utils/buildable-libs-utils.spec.d.ts.map +0 -1
- package/spec/src/utils/compiler-helper-dependency.spec.d.ts +0 -2
- package/spec/src/utils/compiler-helper-dependency.spec.d.ts.map +0 -1
- package/spec/src/utils/find-npm-dependencies.spec.d.ts +0 -2
- package/spec/src/utils/find-npm-dependencies.spec.d.ts.map +0 -1
- package/spec/src/utils/get-import-path.spec.d.ts +0 -2
- package/spec/src/utils/get-import-path.spec.d.ts.map +0 -1
- package/spec/src/utils/npm-config.spec.d.ts +0 -2
- package/spec/src/utils/npm-config.spec.d.ts.map +0 -1
- package/spec/src/utils/package-json/update-package-json.spec.d.ts +0 -2
- package/spec/src/utils/package-json/update-package-json.spec.d.ts.map +0 -1
- package/spec/src/utils/typescript/create-ts-config.spec.d.ts +0 -2
- package/spec/src/utils/typescript/create-ts-config.spec.d.ts.map +0 -1
- package/spec/src/utils/typescript/load-ts-transformers.spec.d.ts +0 -2
- package/spec/src/utils/typescript/load-ts-transformers.spec.d.ts.map +0 -1
- package/spec/src/utils/typescript/plugin.spec.d.ts +0 -2
- package/spec/src/utils/typescript/plugin.spec.d.ts.map +0 -1
- package/spec/src/utils/typescript/run-type-check.spec.d.ts +0 -2
- package/spec/src/utils/typescript/run-type-check.spec.d.ts.map +0 -1
- package/spec/tsconfig.spec.tsbuildinfo +0 -1
- package/src/generators/release-version/schema.d.ts +0 -1
- package/src/generators/release-version/schema.json +0 -86
- package/src/generators/release-version/test-utils/create-workspace-with-package-dependencies.d.ts +0 -17
- package/src/generators/release-version/test-utils/create-workspace-with-package-dependencies.d.ts.map +0 -1
- package/src/generators/release-version/test-utils/create-workspace-with-package-dependencies.js +0 -39
- package/src/generators/release-version/utils/package.d.ts +0 -13
- package/src/generators/release-version/utils/package.d.ts.map +0 -1
- package/src/generators/release-version/utils/package.js +0 -34
- package/src/generators/release-version/utils/resolve-local-package-dependencies.d.ts +0 -12
- package/src/generators/release-version/utils/resolve-local-package-dependencies.d.ts.map +0 -1
- package/src/generators/release-version/utils/resolve-local-package-dependencies.js +0 -77
- package/src/generators/release-version/utils/resolve-version-spec.d.ts +0 -2
- package/src/generators/release-version/utils/resolve-version-spec.d.ts.map +0 -1
- package/src/generators/release-version/utils/resolve-version-spec.js +0 -28
- package/src/generators/release-version/utils/sort-projects-topologically.d.ts +0 -3
- package/src/generators/release-version/utils/sort-projects-topologically.d.ts.map +0 -1
- package/src/generators/release-version/utils/sort-projects-topologically.js +0 -47
|
@@ -1,785 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.releaseVersionGenerator = releaseVersionGenerator;
|
|
4
|
-
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
const chalk = require("chalk");
|
|
6
|
-
const enquirer_1 = require("enquirer");
|
|
7
|
-
const node_child_process_1 = require("node:child_process");
|
|
8
|
-
const promises_1 = require("node:fs/promises");
|
|
9
|
-
const node_path_1 = require("node:path");
|
|
10
|
-
const config_1 = require("nx/src/command-line/release/config/config");
|
|
11
|
-
const git_1 = require("nx/src/command-line/release/utils/git");
|
|
12
|
-
const resolve_semver_specifier_1 = require("nx/src/command-line/release/utils/resolve-semver-specifier");
|
|
13
|
-
const semver_1 = require("nx/src/command-line/release/utils/semver");
|
|
14
|
-
const version_legacy_1 = require("nx/src/command-line/release/version-legacy");
|
|
15
|
-
const utils_1 = require("nx/src/tasks-runner/utils");
|
|
16
|
-
const ora = require("ora");
|
|
17
|
-
const semver_2 = require("semver");
|
|
18
|
-
const update_lock_file_1 = require("../../release/utils/update-lock-file");
|
|
19
|
-
const is_locally_linked_package_version_1 = require("../../utils/is-locally-linked-package-version");
|
|
20
|
-
const npm_config_1 = require("../../utils/npm-config");
|
|
21
|
-
const resolve_local_package_dependencies_1 = require("./utils/resolve-local-package-dependencies");
|
|
22
|
-
const sort_projects_topologically_1 = require("./utils/sort-projects-topologically");
|
|
23
|
-
function resolvePreidSpecifier(currentSpecifier, preid) {
|
|
24
|
-
if (!currentSpecifier.startsWith('pre') && preid) {
|
|
25
|
-
return `pre${currentSpecifier}`;
|
|
26
|
-
}
|
|
27
|
-
return currentSpecifier;
|
|
28
|
-
}
|
|
29
|
-
async function releaseVersionGenerator(tree, options) {
|
|
30
|
-
let logger;
|
|
31
|
-
try {
|
|
32
|
-
const versionData = {};
|
|
33
|
-
// If the user provided a specifier, validate that it is valid semver or a relative semver keyword
|
|
34
|
-
if (options.specifier) {
|
|
35
|
-
if (!(0, semver_1.isValidSemverSpecifier)(options.specifier)) {
|
|
36
|
-
throw new Error(`The given version specifier "${options.specifier}" is not valid. You provide an exact version or a valid semver keyword such as "major", "minor", "patch", etc.`);
|
|
37
|
-
}
|
|
38
|
-
// The node semver library classes a leading `v` as valid, but we want to ensure it is not present in the final version
|
|
39
|
-
options.specifier = options.specifier.replace(/^v/, '');
|
|
40
|
-
}
|
|
41
|
-
if (options.versionPrefix &&
|
|
42
|
-
version_legacy_1.validReleaseVersionPrefixes.indexOf(options.versionPrefix) === -1) {
|
|
43
|
-
throw new Error(`Invalid value for version.generatorOptions.versionPrefix: "${options.versionPrefix}"
|
|
44
|
-
|
|
45
|
-
Valid values are: ${version_legacy_1.validReleaseVersionPrefixes
|
|
46
|
-
.map((s) => `"${s}"`)
|
|
47
|
-
.join(', ')}`);
|
|
48
|
-
}
|
|
49
|
-
if (options.firstRelease) {
|
|
50
|
-
// always use disk as a fallback for the first release
|
|
51
|
-
options.fallbackCurrentVersionResolver = 'disk';
|
|
52
|
-
}
|
|
53
|
-
// Set default for updateDependents
|
|
54
|
-
const updateDependents = options.updateDependents ?? 'auto';
|
|
55
|
-
const updateDependentsBump = resolvePreidSpecifier('patch', options.preid);
|
|
56
|
-
// Sort the projects topologically if update dependents is enabled
|
|
57
|
-
const projects = updateDependents === 'never' ||
|
|
58
|
-
options.releaseGroup.projectsRelationship !== 'independent'
|
|
59
|
-
? options.projects
|
|
60
|
-
: (0, sort_projects_topologically_1.sortProjectsTopologically)(options.projectGraph, options.projects);
|
|
61
|
-
const projectToDependencyBumps = new Map();
|
|
62
|
-
const resolvePackageRoot = createResolvePackageRoot(options.packageRoot);
|
|
63
|
-
// Resolve any custom package roots for each project upfront as they will need to be reused during dependency resolution
|
|
64
|
-
const projectNameToPackageRootMap = new Map();
|
|
65
|
-
for (const project of projects) {
|
|
66
|
-
projectNameToPackageRootMap.set(project.name, resolvePackageRoot(project));
|
|
67
|
-
}
|
|
68
|
-
let currentVersion = undefined;
|
|
69
|
-
let currentVersionResolvedFromFallback = false;
|
|
70
|
-
// only used for options.currentVersionResolver === 'git-tag', but
|
|
71
|
-
// must be declared here in order to reuse it for additional projects
|
|
72
|
-
let latestMatchingGitTag = undefined;
|
|
73
|
-
// if specifier is undefined, then we haven't resolved it yet
|
|
74
|
-
// if specifier is null, then it has been resolved and no changes are necessary
|
|
75
|
-
let specifier = options.specifier
|
|
76
|
-
? options.specifier
|
|
77
|
-
: undefined;
|
|
78
|
-
const deleteVersionPlanCallbacks = [];
|
|
79
|
-
// If the user has set the logUnchangedProjects option to false, we will not print any logs for projects that have no changes.
|
|
80
|
-
const logUnchangedProjects = options.logUnchangedProjects ?? true;
|
|
81
|
-
for (const project of projects) {
|
|
82
|
-
const projectName = project.name;
|
|
83
|
-
const packageRoot = projectNameToPackageRootMap.get(projectName);
|
|
84
|
-
if (!packageRoot) {
|
|
85
|
-
throw new Error(`The project "${projectName}" does not have a packageRoot available. Please report this issue on https://github.com/nrwl/nx`);
|
|
86
|
-
}
|
|
87
|
-
const packageJsonPath = (0, devkit_1.joinPathFragments)(packageRoot, 'package.json');
|
|
88
|
-
if (!tree.exists(packageJsonPath)) {
|
|
89
|
-
throw new Error(`The project "${projectName}" does not have a package.json available at ${packageJsonPath}.
|
|
90
|
-
|
|
91
|
-
To fix this you will either need to add a package.json file at that location, or configure "release" within your nx.json to exclude "${projectName}" from the current release group, or amend the packageRoot configuration to point to where the package.json should be.`);
|
|
92
|
-
}
|
|
93
|
-
const color = getColor(projectName);
|
|
94
|
-
logger = new ProjectLogger(projectName, color);
|
|
95
|
-
const packageJson = (0, devkit_1.readJson)(tree, packageJsonPath);
|
|
96
|
-
logger.buffer(`🔍 Reading data for package "${packageJson.name}" from ${packageJsonPath}`);
|
|
97
|
-
const { name: packageName, version: currentVersionFromDisk } = packageJson;
|
|
98
|
-
switch (options.currentVersionResolver) {
|
|
99
|
-
case 'registry': {
|
|
100
|
-
const metadata = options.currentVersionResolverMetadata;
|
|
101
|
-
const registryArg = typeof metadata?.registry === 'string'
|
|
102
|
-
? metadata.registry
|
|
103
|
-
: undefined;
|
|
104
|
-
const tagArg = typeof metadata?.tag === 'string' ? metadata.tag : undefined;
|
|
105
|
-
const warnFn = (message) => {
|
|
106
|
-
console.log(chalk.keyword('orange')(message));
|
|
107
|
-
};
|
|
108
|
-
const { registry, tag, registryConfigKey } = await (0, npm_config_1.parseRegistryOptions)(devkit_1.workspaceRoot, {
|
|
109
|
-
packageRoot: (0, node_path_1.join)(devkit_1.workspaceRoot, packageRoot),
|
|
110
|
-
packageJson,
|
|
111
|
-
}, {
|
|
112
|
-
registry: registryArg,
|
|
113
|
-
tag: tagArg,
|
|
114
|
-
}, warnFn);
|
|
115
|
-
/**
|
|
116
|
-
* If the currentVersionResolver is set to registry, and the projects are not independent, we only want to make the request once for the whole batch of projects.
|
|
117
|
-
* For independent projects, we need to make a request for each project individually as they will most likely have different versions.
|
|
118
|
-
*/
|
|
119
|
-
if (!currentVersion ||
|
|
120
|
-
options.releaseGroup.projectsRelationship === 'independent') {
|
|
121
|
-
const spinner = ora(`${Array.from(new Array(projectName.length + 3)).join(' ')}Resolving the current version for tag "${tag}" on ${registry}`);
|
|
122
|
-
spinner.color =
|
|
123
|
-
color.spinnerColor;
|
|
124
|
-
spinner.start();
|
|
125
|
-
try {
|
|
126
|
-
// Must be non-blocking async to allow spinner to render
|
|
127
|
-
currentVersion = await new Promise((resolve, reject) => {
|
|
128
|
-
(0, node_child_process_1.exec)(`npm view ${packageName} version --"${registryConfigKey}=${registry}" --tag=${tag}`, {
|
|
129
|
-
windowsHide: false,
|
|
130
|
-
}, (error, stdout, stderr) => {
|
|
131
|
-
if (error) {
|
|
132
|
-
return reject(error);
|
|
133
|
-
}
|
|
134
|
-
if (stderr) {
|
|
135
|
-
return reject(stderr);
|
|
136
|
-
}
|
|
137
|
-
return resolve(stdout.trim());
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
spinner.stop();
|
|
141
|
-
logger.buffer(`📄 Resolved the current version as ${currentVersion} for tag "${tag}" from registry ${registry}`);
|
|
142
|
-
}
|
|
143
|
-
catch (e) {
|
|
144
|
-
spinner.stop();
|
|
145
|
-
if (options.fallbackCurrentVersionResolver === 'disk') {
|
|
146
|
-
if (!currentVersionFromDisk &&
|
|
147
|
-
(options.specifierSource === 'conventional-commits' ||
|
|
148
|
-
options.specifierSource === 'version-plans')) {
|
|
149
|
-
currentVersion = await handleNoAvailableDiskFallback({
|
|
150
|
-
logger,
|
|
151
|
-
projectName,
|
|
152
|
-
packageJsonPath,
|
|
153
|
-
specifierSource: options.specifierSource,
|
|
154
|
-
currentVersionSourceMessage: `from the registry ${registry}`,
|
|
155
|
-
resolutionSuggestion: `you should publish an initial version to the registry`,
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
logger.buffer(`📄 Unable to resolve the current version from the registry ${registry}. Falling back to the version on disk of ${currentVersionFromDisk}`);
|
|
160
|
-
currentVersion = currentVersionFromDisk;
|
|
161
|
-
currentVersionResolvedFromFallback = true;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
throw new Error(`Unable to resolve the current version from the registry ${registry}. Please ensure that the package exists in the registry in order to use the "registry" currentVersionResolver. Alternatively, you can use the --first-release option or set "release.version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when the registry lookup fails.`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
if (currentVersionResolvedFromFallback) {
|
|
171
|
-
logger.buffer(`📄 Using the current version ${currentVersion} already resolved from disk fallback.`);
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
logger.buffer(`📄 Using the current version ${currentVersion} already resolved from the registry ${registry}`);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
break;
|
|
178
|
-
}
|
|
179
|
-
case 'disk':
|
|
180
|
-
currentVersion = currentVersionFromDisk;
|
|
181
|
-
if (!currentVersion) {
|
|
182
|
-
throw new Error(`Unable to determine the current version for project "${project.name}" from ${packageJsonPath}, please ensure that the "version" field is set within the file`);
|
|
183
|
-
}
|
|
184
|
-
logger.buffer(`📄 Resolved the current version as ${currentVersion} from ${packageJsonPath}`);
|
|
185
|
-
break;
|
|
186
|
-
case 'git-tag': {
|
|
187
|
-
if (!currentVersion ||
|
|
188
|
-
// We always need to independently resolve the current version from git tag per project if the projects are independent
|
|
189
|
-
options.releaseGroup.projectsRelationship === 'independent') {
|
|
190
|
-
const releaseTagPattern = options.releaseGroup.releaseTagPattern;
|
|
191
|
-
const releaseTagPatternRequireSemver = options.releaseGroup.releaseTagPatternRequireSemver;
|
|
192
|
-
latestMatchingGitTag = await (0, git_1.getLatestGitTagForPattern)(releaseTagPattern, {
|
|
193
|
-
projectName: project.name,
|
|
194
|
-
}, {
|
|
195
|
-
checkAllBranchesWhen: options.releaseGroup.releaseTagPatternCheckAllBranchesWhen,
|
|
196
|
-
preid: options.preid,
|
|
197
|
-
releaseTagPatternRequireSemver: releaseTagPatternRequireSemver,
|
|
198
|
-
releaseTagPatternStrictPreid: options.releaseGroup.releaseTagPatternStrictPreid,
|
|
199
|
-
});
|
|
200
|
-
if (!latestMatchingGitTag) {
|
|
201
|
-
if (options.fallbackCurrentVersionResolver === 'disk') {
|
|
202
|
-
if (!currentVersionFromDisk &&
|
|
203
|
-
(options.specifierSource === 'conventional-commits' ||
|
|
204
|
-
options.specifierSource === 'version-plans')) {
|
|
205
|
-
currentVersion = await handleNoAvailableDiskFallback({
|
|
206
|
-
logger,
|
|
207
|
-
projectName,
|
|
208
|
-
packageJsonPath,
|
|
209
|
-
specifierSource: options.specifierSource,
|
|
210
|
-
currentVersionSourceMessage: `from git tag using pattern "${releaseTagPattern}"`,
|
|
211
|
-
resolutionSuggestion: `you should set an initial git tag on a relevant commit`,
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
logger.buffer(`📄 Unable to resolve the current version from git tag using pattern "${releaseTagPattern}". Falling back to the version on disk of ${currentVersionFromDisk}`);
|
|
216
|
-
currentVersion = currentVersionFromDisk;
|
|
217
|
-
currentVersionResolvedFromFallback = true;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
throw new Error(`No git tags matching pattern "${releaseTagPattern}" for project "${project.name}" were found. You will need to create an initial matching tag to use as a base for determining the next version. Alternatively, you can use the --first-release option or set "release.version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when no matching git tags are found.`);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
currentVersion = latestMatchingGitTag.extractedVersion;
|
|
226
|
-
logger.buffer(`📄 Resolved the current version as ${currentVersion} from git tag "${latestMatchingGitTag.tag}".`);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
if (currentVersionResolvedFromFallback) {
|
|
231
|
-
logger.buffer(`📄 Using the current version ${currentVersion} already resolved from disk fallback.`);
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
logger.buffer(
|
|
235
|
-
// In this code path we know that latestMatchingGitTag is defined, because we are not relying on the fallbackCurrentVersionResolver, so we can safely use the non-null assertion operator
|
|
236
|
-
`📄 Using the current version ${currentVersion} already resolved from git tag "${latestMatchingGitTag.tag}".`);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
break;
|
|
240
|
-
}
|
|
241
|
-
default:
|
|
242
|
-
throw new Error(`Invalid value for options.currentVersionResolver: ${options.currentVersionResolver}`);
|
|
243
|
-
}
|
|
244
|
-
if (options.specifier) {
|
|
245
|
-
logger.buffer(`📄 Using the provided version specifier "${options.specifier}".`);
|
|
246
|
-
// The user is forcibly overriding whatever specifierSource they had otherwise set by imperatively providing a specifier
|
|
247
|
-
options.specifierSource = 'prompt';
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* If we are versioning independently then we always need to determine the specifier for each project individually, except
|
|
251
|
-
* for the case where the user has provided an explicit specifier on the command.
|
|
252
|
-
*
|
|
253
|
-
* Otherwise, if versioning the projects together we only need to perform this logic if the specifier is still unset from
|
|
254
|
-
* previous iterations of the loop.
|
|
255
|
-
*
|
|
256
|
-
* NOTE: In the case that we have previously determined via conventional commits that no changes are necessary, the specifier
|
|
257
|
-
* will be explicitly set to `null`, so that is why we only check for `undefined` explicitly here.
|
|
258
|
-
*/
|
|
259
|
-
if (specifier === undefined ||
|
|
260
|
-
(options.releaseGroup.projectsRelationship === 'independent' &&
|
|
261
|
-
!options.specifier)) {
|
|
262
|
-
const specifierSource = options.specifierSource;
|
|
263
|
-
switch (specifierSource) {
|
|
264
|
-
case 'conventional-commits': {
|
|
265
|
-
if (options.currentVersionResolver !== 'git-tag') {
|
|
266
|
-
throw new Error(`Invalid currentVersionResolver "${options.currentVersionResolver}" provided for release group "${options.releaseGroup.name}". Must be "git-tag" when "specifierSource" is "conventional-commits"`);
|
|
267
|
-
}
|
|
268
|
-
const affectedProjects = options.releaseGroup.projectsRelationship === 'independent'
|
|
269
|
-
? [projectName]
|
|
270
|
-
: projects.map((p) => p.name);
|
|
271
|
-
// latestMatchingGitTag will be undefined if the current version was resolved from the disk fallback.
|
|
272
|
-
// In this case, we want to use the first commit as the ref to be consistent with the changelog command.
|
|
273
|
-
const previousVersionRef = latestMatchingGitTag
|
|
274
|
-
? latestMatchingGitTag.tag
|
|
275
|
-
: options.fallbackCurrentVersionResolver === 'disk'
|
|
276
|
-
? await (0, git_1.getFirstGitCommit)()
|
|
277
|
-
: undefined;
|
|
278
|
-
if (!previousVersionRef) {
|
|
279
|
-
// This should never happen since the checks above should catch if the current version couldn't be resolved
|
|
280
|
-
throw new Error(`Unable to determine previous version ref for the projects ${affectedProjects.join(', ')}. This is likely a bug in Nx.`);
|
|
281
|
-
}
|
|
282
|
-
specifier = await (0, resolve_semver_specifier_1.resolveSemverSpecifierFromConventionalCommits)(previousVersionRef, options.projectGraph, affectedProjects, options.conventionalCommitsConfig);
|
|
283
|
-
if (!specifier) {
|
|
284
|
-
if (updateDependents !== 'never' &&
|
|
285
|
-
options.releaseGroup.projectsRelationship === 'independent' &&
|
|
286
|
-
projectToDependencyBumps.has(projectName)) {
|
|
287
|
-
// No applicable changes to the project directly by the user, but one or more dependencies have been bumped and updateDependents is enabled
|
|
288
|
-
specifier = updateDependentsBump;
|
|
289
|
-
logger.buffer(`📄 Resolved the specifier as "${specifier}" because "release.version.generatorOptions.updateDependents" is enabled`);
|
|
290
|
-
break;
|
|
291
|
-
}
|
|
292
|
-
logger.buffer(`🚫 No changes were detected using git history and the conventional commits standard.`);
|
|
293
|
-
break;
|
|
294
|
-
}
|
|
295
|
-
// Always assume that if the current version is a prerelease, then the next version should be a prerelease.
|
|
296
|
-
// Users must manually graduate from a prerelease to a release by providing an explicit specifier.
|
|
297
|
-
if ((0, semver_2.prerelease)(currentVersion ?? '')) {
|
|
298
|
-
specifier = 'prerelease';
|
|
299
|
-
logger.buffer(`📄 Resolved the specifier as "${specifier}" since the current version is a prerelease.`);
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
let extraText = '';
|
|
303
|
-
const prereleaseSpecifier = resolvePreidSpecifier(specifier, options.preid);
|
|
304
|
-
if (prereleaseSpecifier !== specifier) {
|
|
305
|
-
specifier = prereleaseSpecifier;
|
|
306
|
-
extraText = `, combined with your given preid "${options.preid}"`;
|
|
307
|
-
}
|
|
308
|
-
logger.buffer(`📄 Resolved the specifier as "${specifier}" using git history and the conventional commits standard${extraText}.`);
|
|
309
|
-
}
|
|
310
|
-
break;
|
|
311
|
-
}
|
|
312
|
-
case 'prompt': {
|
|
313
|
-
// Only add the release group name to the log if it is one set by the user, otherwise it is useless noise
|
|
314
|
-
const maybeLogReleaseGroup = (log) => {
|
|
315
|
-
if (options.releaseGroup.name === config_1.IMPLICIT_DEFAULT_RELEASE_GROUP) {
|
|
316
|
-
return log;
|
|
317
|
-
}
|
|
318
|
-
return `${log} within release group "${options.releaseGroup.name}"`;
|
|
319
|
-
};
|
|
320
|
-
if (options.releaseGroup.projectsRelationship === 'independent') {
|
|
321
|
-
specifier = await (0, resolve_semver_specifier_1.resolveSemverSpecifierFromPrompt)(`${maybeLogReleaseGroup(`What kind of change is this for project "${projectName}"`)}?`, `${maybeLogReleaseGroup(`What is the exact version for project "${projectName}"`)}?`);
|
|
322
|
-
}
|
|
323
|
-
else {
|
|
324
|
-
specifier = await (0, resolve_semver_specifier_1.resolveSemverSpecifierFromPrompt)(`${maybeLogReleaseGroup(`What kind of change is this for the ${projects.length} matched projects(s)`)}?`, `${maybeLogReleaseGroup(`What is the exact version for the ${projects.length} matched project(s)`)}?`);
|
|
325
|
-
}
|
|
326
|
-
break;
|
|
327
|
-
}
|
|
328
|
-
case 'version-plans': {
|
|
329
|
-
if (!options.releaseGroup.versionPlans) {
|
|
330
|
-
if (options.releaseGroup.name === config_1.IMPLICIT_DEFAULT_RELEASE_GROUP) {
|
|
331
|
-
throw new Error(`Invalid specifierSource "version-plans" provided. To enable version plans, set the "release.versionPlans" configuration option to "true" in nx.json.`);
|
|
332
|
-
}
|
|
333
|
-
else {
|
|
334
|
-
throw new Error(`Invalid specifierSource "version-plans" provided. To enable version plans for release group "${options.releaseGroup.name}", set the "versionPlans" configuration option to "true" within the release group configuration in nx.json.`);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
if (options.releaseGroup.projectsRelationship === 'independent') {
|
|
338
|
-
specifier = options.releaseGroup
|
|
339
|
-
.resolvedVersionPlans.reduce((spec, plan) => {
|
|
340
|
-
if (!spec) {
|
|
341
|
-
return plan.projectVersionBumps[projectName];
|
|
342
|
-
}
|
|
343
|
-
if (plan.projectVersionBumps[projectName]) {
|
|
344
|
-
const prevNewVersion = (0, semver_2.inc)(currentVersion, spec);
|
|
345
|
-
const nextNewVersion = (0, semver_2.inc)(currentVersion, plan.projectVersionBumps[projectName]);
|
|
346
|
-
return (0, semver_2.gt)(nextNewVersion, prevNewVersion)
|
|
347
|
-
? plan.projectVersionBumps[projectName]
|
|
348
|
-
: spec;
|
|
349
|
-
}
|
|
350
|
-
return spec;
|
|
351
|
-
}, null);
|
|
352
|
-
}
|
|
353
|
-
else {
|
|
354
|
-
specifier = options.releaseGroup.resolvedVersionPlans.reduce((spec, plan) => {
|
|
355
|
-
if (!spec) {
|
|
356
|
-
return plan.groupVersionBump;
|
|
357
|
-
}
|
|
358
|
-
const prevNewVersion = (0, semver_2.inc)(currentVersion, spec);
|
|
359
|
-
const nextNewVersion = (0, semver_2.inc)(currentVersion, plan.groupVersionBump);
|
|
360
|
-
return (0, semver_2.gt)(nextNewVersion, prevNewVersion)
|
|
361
|
-
? plan.groupVersionBump
|
|
362
|
-
: spec;
|
|
363
|
-
}, null);
|
|
364
|
-
}
|
|
365
|
-
if (!specifier) {
|
|
366
|
-
if (updateDependents !== 'never' &&
|
|
367
|
-
options.releaseGroup.projectsRelationship === 'independent' &&
|
|
368
|
-
projectToDependencyBumps.has(projectName)) {
|
|
369
|
-
// No applicable changes to the project directly by the user, but one or more dependencies have been bumped and updateDependents is enabled
|
|
370
|
-
specifier = updateDependentsBump;
|
|
371
|
-
logger.buffer(`📄 Resolved the specifier as "${specifier}" because "release.version.generatorOptions.updateDependents" is enabled`);
|
|
372
|
-
}
|
|
373
|
-
else {
|
|
374
|
-
specifier = null;
|
|
375
|
-
logger.buffer(`🚫 No changes were detected within version plans.`);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
else {
|
|
379
|
-
logger.buffer(`📄 Resolved the specifier as "${specifier}" using version plans.`);
|
|
380
|
-
}
|
|
381
|
-
if (options.deleteVersionPlans) {
|
|
382
|
-
(options.releaseGroup.resolvedVersionPlans || []).forEach((p) => {
|
|
383
|
-
deleteVersionPlanCallbacks.push(async (dryRun) => {
|
|
384
|
-
if (!dryRun) {
|
|
385
|
-
await (0, promises_1.rm)(p.absolutePath, { recursive: true, force: true });
|
|
386
|
-
// the relative path is easier to digest, so use that for
|
|
387
|
-
// git operations and logging
|
|
388
|
-
return [p.relativePath];
|
|
389
|
-
}
|
|
390
|
-
else {
|
|
391
|
-
return [];
|
|
392
|
-
}
|
|
393
|
-
});
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
break;
|
|
397
|
-
}
|
|
398
|
-
default:
|
|
399
|
-
throw new Error(`Invalid specifierSource "${specifierSource}" provided. Must be one of "prompt", "conventional-commits" or "version-plans".`);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
// Resolve any local package dependencies for this project (before applying the new version or updating the versionData)
|
|
403
|
-
const localPackageDependencies = (0, resolve_local_package_dependencies_1.resolveLocalPackageDependencies)(tree, options.projectGraph, projects, projectNameToPackageRootMap, resolvePackageRoot,
|
|
404
|
-
// includeAll when the release group is independent, as we may be filtering to a specific subset of projects, but we still want to update their dependents
|
|
405
|
-
options.releaseGroup.projectsRelationship === 'independent');
|
|
406
|
-
// list of projects that depend on the current package
|
|
407
|
-
const allDependentProjects = Object.values(localPackageDependencies)
|
|
408
|
-
.flat()
|
|
409
|
-
.filter((localPackageDependency) => {
|
|
410
|
-
return localPackageDependency.target === projectName;
|
|
411
|
-
});
|
|
412
|
-
const includeTransitiveDependents = updateDependents !== 'never' &&
|
|
413
|
-
options.releaseGroup.projectsRelationship === 'independent';
|
|
414
|
-
const transitiveLocalPackageDependents = [];
|
|
415
|
-
if (includeTransitiveDependents) {
|
|
416
|
-
for (const directDependent of allDependentProjects) {
|
|
417
|
-
// Look through localPackageDependencies to find any which have a target on the current dependent
|
|
418
|
-
for (const localPackageDependency of Object.values(localPackageDependencies).flat()) {
|
|
419
|
-
if (localPackageDependency.target === directDependent.source) {
|
|
420
|
-
transitiveLocalPackageDependents.push(localPackageDependency);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
const dependentProjectsInCurrentBatch = [];
|
|
426
|
-
const dependentProjectsOutsideCurrentBatch = [];
|
|
427
|
-
// Track circular dependencies using value of project1:project2
|
|
428
|
-
const circularDependencies = new Set();
|
|
429
|
-
const projectsDependOnCurrentProject = localPackageDependencies[projectName]?.map((localPackageDependencies) => localPackageDependencies.target) ?? [];
|
|
430
|
-
for (const dependentProject of allDependentProjects) {
|
|
431
|
-
// Track circular dependencies (add both directions for easy look up)
|
|
432
|
-
if (projectsDependOnCurrentProject.includes(dependentProject.source)) {
|
|
433
|
-
circularDependencies.add(`${dependentProject.source}:${dependentProject.target}`);
|
|
434
|
-
circularDependencies.add(`${dependentProject.target}:${dependentProject.source}`);
|
|
435
|
-
}
|
|
436
|
-
let isInCurrentBatch = options.projects.some((project) => project.name === dependentProject.source);
|
|
437
|
-
// For version-plans, we don't just need to consider the current batch of projects, but also the ones that are actually being updated as part of the plan file(s)
|
|
438
|
-
if (isInCurrentBatch && options.specifierSource === 'version-plans') {
|
|
439
|
-
isInCurrentBatch = (options.releaseGroup.resolvedVersionPlans || []).some((plan) => {
|
|
440
|
-
if ('projectVersionBumps' in plan) {
|
|
441
|
-
return plan.projectVersionBumps[dependentProject.source];
|
|
442
|
-
}
|
|
443
|
-
return true;
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
if (!isInCurrentBatch) {
|
|
447
|
-
dependentProjectsOutsideCurrentBatch.push(dependentProject);
|
|
448
|
-
}
|
|
449
|
-
else {
|
|
450
|
-
dependentProjectsInCurrentBatch.push(dependentProject);
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
// If not always updating dependents (when they don't already appear in the batch itself), print a warning to the user about what is being skipped and how to change it
|
|
454
|
-
if (updateDependents === 'never' ||
|
|
455
|
-
options.releaseGroup.projectsRelationship !== 'independent') {
|
|
456
|
-
if (dependentProjectsOutsideCurrentBatch.length > 0) {
|
|
457
|
-
let logMsg = `⚠️ Warning, the following packages depend on "${project.name}"`;
|
|
458
|
-
const reason = options.specifierSource === 'version-plans'
|
|
459
|
-
? 'because they are not referenced in any version plans'
|
|
460
|
-
: 'via --projects';
|
|
461
|
-
if (options.releaseGroup.name === config_1.IMPLICIT_DEFAULT_RELEASE_GROUP) {
|
|
462
|
-
logMsg += ` but have been filtered out ${reason}, and therefore will not be updated:`;
|
|
463
|
-
}
|
|
464
|
-
else {
|
|
465
|
-
logMsg += ` but are either not part of the current release group "${options.releaseGroup.name}", or have been filtered out ${reason}, and therefore will not be updated:`;
|
|
466
|
-
}
|
|
467
|
-
const indent = Array.from(new Array(projectName.length + 4))
|
|
468
|
-
.map(() => ' ')
|
|
469
|
-
.join('');
|
|
470
|
-
logMsg += `\n${dependentProjectsOutsideCurrentBatch
|
|
471
|
-
.map((dependentProject) => `${indent}- ${dependentProject.source}`)
|
|
472
|
-
.join('\n')}`;
|
|
473
|
-
logMsg += `\n${indent}=> You can adjust this behavior by removing the usage of \`version.generatorOptions.updateDependents\` with "never"`;
|
|
474
|
-
logger.buffer(logMsg);
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
if (!currentVersion) {
|
|
478
|
-
throw new Error(`The current version for project "${project.name}" could not be resolved. Please report this on https://github.com/nrwl/nx`);
|
|
479
|
-
}
|
|
480
|
-
versionData[projectName] = {
|
|
481
|
-
currentVersion,
|
|
482
|
-
newVersion: null, // will stay as null in the final result in the case that no changes are detected
|
|
483
|
-
dependentProjects: updateDependents === 'auto' &&
|
|
484
|
-
options.releaseGroup.projectsRelationship === 'independent'
|
|
485
|
-
? allDependentProjects
|
|
486
|
-
: dependentProjectsInCurrentBatch,
|
|
487
|
-
};
|
|
488
|
-
if (!specifier) {
|
|
489
|
-
logger.buffer(`🚫 Skipping versioning "${packageJson.name}" as no changes were detected.`);
|
|
490
|
-
// Print the buffered logs for this unchanged project, as long as the user has not explicitly disabled this behavior
|
|
491
|
-
if (logUnchangedProjects) {
|
|
492
|
-
logger.flush();
|
|
493
|
-
}
|
|
494
|
-
continue;
|
|
495
|
-
}
|
|
496
|
-
const newVersion = (0, version_legacy_1.deriveNewSemverVersion)(currentVersion, specifier, options.preid);
|
|
497
|
-
versionData[projectName].newVersion = newVersion;
|
|
498
|
-
(0, devkit_1.writeJson)(tree, packageJsonPath, {
|
|
499
|
-
...packageJson,
|
|
500
|
-
version: newVersion,
|
|
501
|
-
});
|
|
502
|
-
logger.buffer(`✍️ New version ${newVersion} written to ${packageJsonPath}`);
|
|
503
|
-
if (allDependentProjects.length > 0) {
|
|
504
|
-
const totalProjectsToUpdate = updateDependents === 'auto' &&
|
|
505
|
-
options.releaseGroup.projectsRelationship === 'independent'
|
|
506
|
-
? allDependentProjects.length +
|
|
507
|
-
// Only count transitive dependents that aren't already direct dependents
|
|
508
|
-
transitiveLocalPackageDependents.filter((transitive) => !allDependentProjects.some((direct) => direct.source === transitive.source)).length -
|
|
509
|
-
// There are two entries per circular dep
|
|
510
|
-
circularDependencies.size / 2
|
|
511
|
-
: dependentProjectsInCurrentBatch.length;
|
|
512
|
-
if (totalProjectsToUpdate > 0) {
|
|
513
|
-
logger.buffer(`✍️ Applying new version ${newVersion} to ${totalProjectsToUpdate} ${totalProjectsToUpdate > 1
|
|
514
|
-
? 'packages which depend'
|
|
515
|
-
: 'package which depends'} on ${project.name}`);
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
const updateDependentProjectAndAddToVersionData = ({ dependentProject, dependencyPackageName, newDependencyVersion, forceVersionBump, }) => {
|
|
519
|
-
const updatedFilePath = (0, devkit_1.joinPathFragments)(projectNameToPackageRootMap.get(dependentProject.source), 'package.json');
|
|
520
|
-
(0, devkit_1.updateJson)(tree, updatedFilePath, (json) => {
|
|
521
|
-
// Auto (i.e.infer existing) by default
|
|
522
|
-
let versionPrefix = options.versionPrefix ?? 'auto';
|
|
523
|
-
const currentDependencyVersion = json[dependentProject.dependencyCollection][dependencyPackageName];
|
|
524
|
-
// Depending on the package manager, locally linked packages could reference packages with `"private": true` and no version field at all
|
|
525
|
-
const currentPackageVersion = json.version ?? null;
|
|
526
|
-
if (!currentPackageVersion &&
|
|
527
|
-
(0, is_locally_linked_package_version_1.isLocallyLinkedPackageVersion)(currentDependencyVersion)) {
|
|
528
|
-
if (forceVersionBump) {
|
|
529
|
-
// Look up any dependent projects from the transitiveLocalPackageDependents list
|
|
530
|
-
const transitiveDependentProjects = transitiveLocalPackageDependents.filter((localPackageDependency) => localPackageDependency.target === dependentProject.source);
|
|
531
|
-
versionData[dependentProject.source] = {
|
|
532
|
-
currentVersion: currentPackageVersion,
|
|
533
|
-
newVersion: currentDependencyVersion,
|
|
534
|
-
dependentProjects: transitiveDependentProjects,
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
|
-
return json;
|
|
538
|
-
}
|
|
539
|
-
// For auto, we infer the prefix based on the current version of the dependent
|
|
540
|
-
if (versionPrefix === 'auto') {
|
|
541
|
-
versionPrefix = ''; // we don't want to end up printing auto
|
|
542
|
-
if (currentDependencyVersion) {
|
|
543
|
-
const prefixMatch = currentDependencyVersion.match(/^[~^]/);
|
|
544
|
-
if (prefixMatch) {
|
|
545
|
-
versionPrefix = prefixMatch[0];
|
|
546
|
-
}
|
|
547
|
-
else {
|
|
548
|
-
versionPrefix = '';
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
// Apply the new version of the dependency to the dependent (if not preserving locally linked package protocols)
|
|
553
|
-
const shouldUpdateDependency = !((0, is_locally_linked_package_version_1.isLocallyLinkedPackageVersion)(currentDependencyVersion) &&
|
|
554
|
-
options.preserveLocalDependencyProtocols);
|
|
555
|
-
if (shouldUpdateDependency) {
|
|
556
|
-
const newDepVersion = `${versionPrefix}${newDependencyVersion}`;
|
|
557
|
-
json[dependentProject.dependencyCollection][dependencyPackageName] =
|
|
558
|
-
newDepVersion;
|
|
559
|
-
}
|
|
560
|
-
// Bump the dependent's version if applicable and record it in the version data
|
|
561
|
-
if (forceVersionBump) {
|
|
562
|
-
const newPackageVersion = (0, version_legacy_1.deriveNewSemverVersion)(currentPackageVersion, forceVersionBump, options.preid);
|
|
563
|
-
json.version = newPackageVersion;
|
|
564
|
-
// Look up any dependent projects from the transitiveLocalPackageDependents list
|
|
565
|
-
const transitiveDependentProjects = transitiveLocalPackageDependents.filter((localPackageDependency) => localPackageDependency.target === dependentProject.source);
|
|
566
|
-
versionData[dependentProject.source] = {
|
|
567
|
-
currentVersion: currentPackageVersion,
|
|
568
|
-
newVersion: newPackageVersion,
|
|
569
|
-
dependentProjects: transitiveDependentProjects,
|
|
570
|
-
};
|
|
571
|
-
}
|
|
572
|
-
return json;
|
|
573
|
-
});
|
|
574
|
-
};
|
|
575
|
-
for (const dependentProject of dependentProjectsInCurrentBatch) {
|
|
576
|
-
if (projectToDependencyBumps.has(dependentProject.source)) {
|
|
577
|
-
const dependencyBumps = projectToDependencyBumps.get(dependentProject.source);
|
|
578
|
-
dependencyBumps.add(projectName);
|
|
579
|
-
}
|
|
580
|
-
else {
|
|
581
|
-
projectToDependencyBumps.set(dependentProject.source, new Set([projectName]));
|
|
582
|
-
}
|
|
583
|
-
updateDependentProjectAndAddToVersionData({
|
|
584
|
-
dependentProject,
|
|
585
|
-
dependencyPackageName: packageName,
|
|
586
|
-
newDependencyVersion: newVersion,
|
|
587
|
-
// We don't force bump because we know they will come later in the topologically sorted projects loop and may have their own version update logic to take into account
|
|
588
|
-
forceVersionBump: false,
|
|
589
|
-
});
|
|
590
|
-
}
|
|
591
|
-
if (updateDependents === 'auto' &&
|
|
592
|
-
options.releaseGroup.projectsRelationship === 'independent') {
|
|
593
|
-
for (const dependentProject of dependentProjectsOutsideCurrentBatch) {
|
|
594
|
-
if (options.specifierSource === 'version-plans' &&
|
|
595
|
-
!projectToDependencyBumps.has(dependentProject.source)) {
|
|
596
|
-
projectToDependencyBumps.set(dependentProject.source, new Set([projectName]));
|
|
597
|
-
}
|
|
598
|
-
updateDependentProjectAndAddToVersionData({
|
|
599
|
-
dependentProject,
|
|
600
|
-
dependencyPackageName: packageName,
|
|
601
|
-
newDependencyVersion: newVersion,
|
|
602
|
-
// For these additional dependents, we need to update their package.json version as well because we know they will not come later in the topologically sorted projects loop
|
|
603
|
-
// (Unless using version plans and the dependent is not filtered out by --projects)
|
|
604
|
-
forceVersionBump: options.specifierSource === 'version-plans' &&
|
|
605
|
-
projects.find((p) => p.name === dependentProject.source)
|
|
606
|
-
? false
|
|
607
|
-
: updateDependentsBump,
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
for (const transitiveDependentProject of transitiveLocalPackageDependents) {
|
|
612
|
-
const isAlreadyDirectDependent = allDependentProjects.some((dep) => dep.source === transitiveDependentProject.source);
|
|
613
|
-
if (isAlreadyDirectDependent) {
|
|
614
|
-
// Don't continue directly in this scenario - we still need to update the dependency version
|
|
615
|
-
// but we don't want to bump the project's own version as it will end up being double patched
|
|
616
|
-
const dependencyProjectName = transitiveDependentProject.target;
|
|
617
|
-
const dependencyPackageRoot = projectNameToPackageRootMap.get(dependencyProjectName);
|
|
618
|
-
if (!dependencyPackageRoot) {
|
|
619
|
-
throw new Error(`The project "${dependencyProjectName}" does not have a packageRoot available. Please report this issue on https://github.com/nrwl/nx`);
|
|
620
|
-
}
|
|
621
|
-
const dependencyPackageJsonPath = (0, devkit_1.joinPathFragments)(dependencyPackageRoot, 'package.json');
|
|
622
|
-
const dependencyPackageJson = (0, devkit_1.readJson)(tree, dependencyPackageJsonPath);
|
|
623
|
-
updateDependentProjectAndAddToVersionData({
|
|
624
|
-
dependentProject: transitiveDependentProject,
|
|
625
|
-
dependencyPackageName: dependencyPackageJson.name,
|
|
626
|
-
newDependencyVersion: dependencyPackageJson.version,
|
|
627
|
-
forceVersionBump: false, // Never bump version for direct dependents
|
|
628
|
-
});
|
|
629
|
-
continue;
|
|
630
|
-
}
|
|
631
|
-
// Check if the transitive dependent originates from a circular dependency
|
|
632
|
-
const isFromCircularDependency = circularDependencies.has(`${transitiveDependentProject.source}:${transitiveDependentProject.target}`);
|
|
633
|
-
const dependencyProjectName = transitiveDependentProject.target;
|
|
634
|
-
const dependencyPackageRoot = projectNameToPackageRootMap.get(dependencyProjectName);
|
|
635
|
-
if (!dependencyPackageRoot) {
|
|
636
|
-
throw new Error(`The project "${dependencyProjectName}" does not have a packageRoot available. Please report this issue on https://github.com/nrwl/nx`);
|
|
637
|
-
}
|
|
638
|
-
const dependencyPackageJsonPath = (0, devkit_1.joinPathFragments)(dependencyPackageRoot, 'package.json');
|
|
639
|
-
const dependencyPackageJson = (0, devkit_1.readJson)(tree, dependencyPackageJsonPath);
|
|
640
|
-
updateDependentProjectAndAddToVersionData({
|
|
641
|
-
dependentProject: transitiveDependentProject,
|
|
642
|
-
dependencyPackageName: dependencyPackageJson.name,
|
|
643
|
-
newDependencyVersion: dependencyPackageJson.version,
|
|
644
|
-
/**
|
|
645
|
-
* For these additional dependents, we need to update their package.json version as well because we know they will not come later in the topologically sorted projects loop.
|
|
646
|
-
* The one exception being if the dependent is part of a circular dependency, in which case we don't want to force a version bump as this would come in addition to the one
|
|
647
|
-
* already applied.
|
|
648
|
-
*/
|
|
649
|
-
forceVersionBump: isFromCircularDependency
|
|
650
|
-
? false
|
|
651
|
-
: updateDependentsBump,
|
|
652
|
-
});
|
|
653
|
-
}
|
|
654
|
-
// Print the logs that have been buffered for this project
|
|
655
|
-
logger.flush();
|
|
656
|
-
}
|
|
657
|
-
/**
|
|
658
|
-
* Ensure that formatting is applied so that version bump diffs are as minimal as possible
|
|
659
|
-
* within the context of the user's workspace.
|
|
660
|
-
*/
|
|
661
|
-
await (0, devkit_1.formatFiles)(tree);
|
|
662
|
-
// Return the version data so that it can be leveraged by the overall version command
|
|
663
|
-
return {
|
|
664
|
-
data: versionData,
|
|
665
|
-
callback: async (tree, { generatorOptions, ...opts }) => {
|
|
666
|
-
const changedFiles = [];
|
|
667
|
-
const deletedFiles = [];
|
|
668
|
-
for (const cb of deleteVersionPlanCallbacks) {
|
|
669
|
-
deletedFiles.push(...(await cb(opts.dryRun)));
|
|
670
|
-
}
|
|
671
|
-
const cwd = tree.root;
|
|
672
|
-
changedFiles.push(...(await (0, update_lock_file_1.updateLockFile)(cwd, {
|
|
673
|
-
...opts,
|
|
674
|
-
useLegacyVersioning: true,
|
|
675
|
-
options: generatorOptions,
|
|
676
|
-
})));
|
|
677
|
-
return { changedFiles, deletedFiles };
|
|
678
|
-
},
|
|
679
|
-
};
|
|
680
|
-
}
|
|
681
|
-
catch (e) {
|
|
682
|
-
// Flush any pending logs before printing the error to make troubleshooting easier
|
|
683
|
-
logger?.flush();
|
|
684
|
-
if (process.env.NX_VERBOSE_LOGGING === 'true') {
|
|
685
|
-
devkit_1.output.error({
|
|
686
|
-
title: e.message,
|
|
687
|
-
});
|
|
688
|
-
// Dump the full stack trace in verbose mode
|
|
689
|
-
console.error(e);
|
|
690
|
-
}
|
|
691
|
-
else {
|
|
692
|
-
devkit_1.output.error({
|
|
693
|
-
title: e.message,
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
|
-
process.exit(1);
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
exports.default = releaseVersionGenerator;
|
|
700
|
-
function createResolvePackageRoot(customPackageRoot) {
|
|
701
|
-
return (projectNode) => {
|
|
702
|
-
// Default to the project root if no custom packageRoot
|
|
703
|
-
if (!customPackageRoot) {
|
|
704
|
-
return projectNode.data.root;
|
|
705
|
-
}
|
|
706
|
-
if (projectNode.data.root === '.') {
|
|
707
|
-
// This is a temporary workaround to fix NXC-574 until NXC-573 is resolved.
|
|
708
|
-
// This has been fixed in "versioning v2"
|
|
709
|
-
return projectNode.data.root;
|
|
710
|
-
}
|
|
711
|
-
return (0, utils_1.interpolate)(customPackageRoot, {
|
|
712
|
-
workspaceRoot: '',
|
|
713
|
-
projectRoot: projectNode.data.root,
|
|
714
|
-
projectName: projectNode.name,
|
|
715
|
-
});
|
|
716
|
-
};
|
|
717
|
-
}
|
|
718
|
-
const colors = [
|
|
719
|
-
{ instance: chalk.green, spinnerColor: 'green' },
|
|
720
|
-
{ instance: chalk.greenBright, spinnerColor: 'green' },
|
|
721
|
-
{ instance: chalk.red, spinnerColor: 'red' },
|
|
722
|
-
{ instance: chalk.redBright, spinnerColor: 'red' },
|
|
723
|
-
{ instance: chalk.cyan, spinnerColor: 'cyan' },
|
|
724
|
-
{ instance: chalk.cyanBright, spinnerColor: 'cyan' },
|
|
725
|
-
{ instance: chalk.yellow, spinnerColor: 'yellow' },
|
|
726
|
-
{ instance: chalk.yellowBright, spinnerColor: 'yellow' },
|
|
727
|
-
{ instance: chalk.magenta, spinnerColor: 'magenta' },
|
|
728
|
-
{ instance: chalk.magentaBright, spinnerColor: 'magenta' },
|
|
729
|
-
];
|
|
730
|
-
function getColor(projectName) {
|
|
731
|
-
let code = 0;
|
|
732
|
-
for (let i = 0; i < projectName.length; ++i) {
|
|
733
|
-
code += projectName.charCodeAt(i);
|
|
734
|
-
}
|
|
735
|
-
const colorIndex = code % colors.length;
|
|
736
|
-
return colors[colorIndex];
|
|
737
|
-
}
|
|
738
|
-
class ProjectLogger {
|
|
739
|
-
constructor(projectName, color) {
|
|
740
|
-
this.projectName = projectName;
|
|
741
|
-
this.color = color;
|
|
742
|
-
this.logs = [];
|
|
743
|
-
}
|
|
744
|
-
buffer(msg) {
|
|
745
|
-
this.logs.push(msg);
|
|
746
|
-
}
|
|
747
|
-
flush() {
|
|
748
|
-
devkit_1.output.logSingleLine(`Running release version for project: ${this.color.instance.bold(this.projectName)}`);
|
|
749
|
-
this.logs.forEach((msg) => {
|
|
750
|
-
console.log(this.color.instance.bold(this.projectName) + ' ' + msg);
|
|
751
|
-
});
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
/**
|
|
755
|
-
* Allow users to be unblocked when locally running releases for the very first time with certain combinations that require an initial
|
|
756
|
-
* version in order to function (e.g. a relative semver bump derived via conventional commits or version plans) by providing an interactive
|
|
757
|
-
* prompt to let them opt into using 0.0.0 as the implied current version.
|
|
758
|
-
*/
|
|
759
|
-
async function handleNoAvailableDiskFallback({ logger, projectName, packageJsonPath, specifierSource, currentVersionSourceMessage, resolutionSuggestion, }) {
|
|
760
|
-
const unresolvableCurrentVersionError = new Error(`Unable to resolve the current version ${currentVersionSourceMessage} and there is no version on disk to fall back to. This is invalid with ${specifierSource} because the new version is determined by relatively bumping the current version. To resolve this, ${resolutionSuggestion}, or set an appropriate value for "version" in ${packageJsonPath}`);
|
|
761
|
-
if (process.env.CI === 'true') {
|
|
762
|
-
// We can't prompt in CI, so error immediately
|
|
763
|
-
throw unresolvableCurrentVersionError;
|
|
764
|
-
}
|
|
765
|
-
try {
|
|
766
|
-
const reply = await (0, enquirer_1.prompt)([
|
|
767
|
-
{
|
|
768
|
-
name: 'useZero',
|
|
769
|
-
message: `\n${chalk.yellow(`Warning: Unable to resolve the current version for "${projectName}" ${currentVersionSourceMessage} and there is no version on disk to fall back to. This is invalid with ${specifierSource} because the new version is determined by relatively bumping the current version.\n\nTo resolve this, ${resolutionSuggestion}, or set an appropriate value for "version" in ${packageJsonPath}`)}. \n\nAlternatively, would you like to continue now by using 0.0.0 as the current version?`,
|
|
770
|
-
type: 'confirm',
|
|
771
|
-
initial: false,
|
|
772
|
-
},
|
|
773
|
-
]);
|
|
774
|
-
if (!reply.useZero) {
|
|
775
|
-
// Throw any error to skip the fallback to 0.0.0, may as well use the one we already have
|
|
776
|
-
throw unresolvableCurrentVersionError;
|
|
777
|
-
}
|
|
778
|
-
const currentVersion = '0.0.0';
|
|
779
|
-
logger.buffer(`📄 Forcibly resolved the current version as "${currentVersion}" based on your response to the prompt above.`);
|
|
780
|
-
return currentVersion;
|
|
781
|
-
}
|
|
782
|
-
catch {
|
|
783
|
-
throw unresolvableCurrentVersionError;
|
|
784
|
-
}
|
|
785
|
-
}
|