nx 20.0.0-beta.5 → 20.0.0-beta.7
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/.eslintrc.json +12 -2
- package/migrations.json +0 -37
- package/package.json +11 -11
- package/release/changelog-renderer/index.d.ts +60 -38
- package/release/changelog-renderer/index.js +260 -236
- package/src/command-line/add/add.js +2 -2
- package/src/command-line/nx-commands.js +31 -10
- package/src/command-line/release/changelog.d.ts +2 -2
- package/src/command-line/release/changelog.js +28 -29
- package/src/command-line/release/index.d.ts +5 -2
- package/src/command-line/release/publish.d.ts +6 -1
- package/src/command-line/release/publish.js +31 -25
- package/src/command-line/release/utils/print-changes.js +6 -4
- package/src/command-line/release/utils/resolve-changelog-renderer.d.ts +2 -2
- package/src/command-line/release/utils/resolve-changelog-renderer.js +3 -3
- package/src/command-line/release/utils/resolve-nx-json-error-message.js +4 -3
- package/src/command-line/release/version.d.ts +3 -3
- package/src/command-line/yargs-utils/shared-options.js +2 -2
- package/src/config/nx-json.d.ts +2 -1
- package/src/config/workspace-json-project-json.d.ts +14 -0
- package/src/core/graph/main.js +1 -1
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/nx-cloud/utilities/axios.js +1 -2
- package/src/nx-cloud/utilities/onboarding.js +2 -2
- package/src/nx-cloud/utilities/url-shorten.js +5 -5
- package/src/project-graph/file-utils.d.ts +2 -2
- package/src/project-graph/file-utils.js +2 -2
- package/src/tasks-runner/cache.d.ts +2 -1
- package/src/tasks-runner/cache.js +10 -6
- package/src/tasks-runner/create-task-graph.d.ts +2 -0
- package/src/tasks-runner/create-task-graph.js +39 -5
- package/src/tasks-runner/run-command.js +15 -2
- package/src/tasks-runner/task-orchestrator.js +1 -1
- package/src/utils/command-line-utils.d.ts +3 -0
- package/src/utils/git-utils.js +2 -2
- package/src/migrations/update-15-0-0/prefix-outputs.d.ts +0 -2
- package/src/migrations/update-15-0-0/prefix-outputs.js +0 -49
- package/src/migrations/update-16-0-0/remove-nrwl-cli.d.ts +0 -2
- package/src/migrations/update-16-0-0/remove-nrwl-cli.js +0 -16
- package/src/migrations/update-16-0-0/update-depends-on-to-tokens.d.ts +0 -2
- package/src/migrations/update-16-0-0/update-depends-on-to-tokens.js +0 -97
- package/src/migrations/update-16-0-0/update-nx-cloud-runner.d.ts +0 -2
- package/src/migrations/update-16-0-0/update-nx-cloud-runner.js +0 -29
- package/src/migrations/update-16-2-0/remove-run-commands-output-path.d.ts +0 -2
- package/src/migrations/update-16-2-0/remove-run-commands-output-path.js +0 -45
- package/src/migrations/update-16-8-0/escape-dollar-sign-env-variables.d.ts +0 -12
- package/src/migrations/update-16-8-0/escape-dollar-sign-env-variables.js +0 -67
@@ -6,182 +6,239 @@ const github_1 = require("../../src/command-line/release/utils/github");
|
|
6
6
|
// axios types and values don't seem to match
|
7
7
|
const _axios = require("axios");
|
8
8
|
const axios = _axios;
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
9
|
+
class DefaultChangelogRenderer {
|
10
|
+
/**
|
11
|
+
* A ChangelogRenderer class takes in the determined changes and other relevant metadata
|
12
|
+
* and returns a string, or a Promise of a string of changelog contents (usually markdown).
|
13
|
+
*
|
14
|
+
* @param {Object} config The configuration object for the ChangelogRenderer
|
15
|
+
* @param {ChangelogChange[]} config.changes The collection of changes to show in the changelog
|
16
|
+
* @param {string} config.changelogEntryVersion The version for which we are rendering the current changelog entry
|
17
|
+
* @param {string | null} config.project The name of specific project to generate a changelog entry for, or `null` if the overall workspace changelog
|
18
|
+
* @param {string | false} config.entryWhenNoChanges The (already interpolated) string to use as the changelog entry when there are no changes, or `false` if no entry should be generated
|
19
|
+
* @param {boolean} config.isVersionPlans Whether or not Nx release version plans are the source of truth for the changelog entry
|
20
|
+
* @param {ChangelogRenderOptions} config.changelogRenderOptions The options specific to the ChangelogRenderer implementation
|
21
|
+
* @param {DependencyBump[]} config.dependencyBumps Optional list of additional dependency bumps that occurred as part of the release, outside of the change data
|
22
|
+
* @param {GithubRepoData} config.repoData Resolved data for the current GitHub repository
|
23
|
+
* @param {NxReleaseConfig['conventionalCommits'] | null} config.conventionalCommitsConfig The configuration for conventional commits, or null if version plans are being used
|
24
|
+
*/
|
25
|
+
constructor(config) {
|
26
|
+
this.changes = this.filterChanges(config.changes, config.project);
|
27
|
+
this.changelogEntryVersion = config.changelogEntryVersion;
|
28
|
+
this.project = config.project;
|
29
|
+
this.entryWhenNoChanges = config.entryWhenNoChanges;
|
30
|
+
this.isVersionPlans = config.isVersionPlans;
|
31
|
+
this.changelogRenderOptions = config.changelogRenderOptions;
|
32
|
+
this.dependencyBumps = config.dependencyBumps;
|
33
|
+
this.repoData = config.repoData;
|
34
|
+
this.conventionalCommitsConfig = config.conventionalCommitsConfig;
|
35
|
+
this.relevantChanges = [];
|
36
|
+
this.breakingChanges = [];
|
37
|
+
this.additionalChangesForAuthorsSection = [];
|
38
|
+
}
|
39
|
+
filterChanges(changes, project) {
|
40
|
+
if (project === null) {
|
41
|
+
return changes;
|
25
42
|
}
|
43
|
+
return changes.filter((c) => c.affectedProjects &&
|
44
|
+
(c.affectedProjects === '*' || c.affectedProjects.includes(project)));
|
26
45
|
}
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
// but keep track of the changes for the purposes of the authors section
|
44
|
-
// TODO(v20): Clean this abstraction up as part of the larger overall refactor of changelog rendering
|
45
|
-
for (let i = 0; i < relevantChanges.length; i++) {
|
46
|
-
if (relevantChanges[i].isBreaking) {
|
47
|
-
const change = relevantChanges[i];
|
48
|
-
additionalChangesForAuthorsSection.push(change);
|
49
|
-
const line = formatChange(change, changelogRenderOptions, isVersionPlans, repoData);
|
50
|
-
breakingChanges.push(line);
|
51
|
-
relevantChanges.splice(i, 1);
|
52
|
-
}
|
46
|
+
async render() {
|
47
|
+
const sections = [];
|
48
|
+
this.preprocessChanges();
|
49
|
+
if (this.shouldRenderEmptyEntry()) {
|
50
|
+
return this.renderEmptyEntry();
|
51
|
+
}
|
52
|
+
sections.push([this.renderVersionTitle()]);
|
53
|
+
const changesByType = this.renderChangesByType();
|
54
|
+
if (changesByType.length > 0) {
|
55
|
+
sections.push(changesByType);
|
56
|
+
}
|
57
|
+
if (this.hasBreakingChanges()) {
|
58
|
+
sections.push(this.renderBreakingChanges());
|
59
|
+
}
|
60
|
+
if (this.hasDependencyBumps()) {
|
61
|
+
sections.push(this.renderDependencyBumps());
|
53
62
|
}
|
63
|
+
if (this.shouldRenderAuthors()) {
|
64
|
+
sections.push(await this.renderAuthors());
|
65
|
+
}
|
66
|
+
// Join sections with double newlines, and trim any extra whitespace
|
67
|
+
return sections
|
68
|
+
.filter((section) => section.length > 0)
|
69
|
+
.map((section) => section.join('\n').trim())
|
70
|
+
.join('\n\n')
|
71
|
+
.trim();
|
54
72
|
}
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
73
|
+
preprocessChanges() {
|
74
|
+
this.relevantChanges = [...this.changes];
|
75
|
+
this.breakingChanges = [];
|
76
|
+
this.additionalChangesForAuthorsSection = [];
|
77
|
+
// Filter out reverted changes
|
78
|
+
for (let i = this.relevantChanges.length - 1; i >= 0; i--) {
|
79
|
+
const change = this.relevantChanges[i];
|
80
|
+
if (change.type === 'revert' && change.revertedHashes) {
|
81
|
+
for (const revertedHash of change.revertedHashes) {
|
82
|
+
const revertedCommitIndex = this.relevantChanges.findIndex((c) => c.shortHash && revertedHash.startsWith(c.shortHash));
|
83
|
+
if (revertedCommitIndex !== -1) {
|
84
|
+
this.relevantChanges.splice(revertedCommitIndex, 1);
|
85
|
+
this.relevantChanges.splice(i, 1);
|
86
|
+
i--;
|
87
|
+
break;
|
88
|
+
}
|
89
|
+
}
|
70
90
|
}
|
71
|
-
return markdownLines.join('\n').trim();
|
72
91
|
}
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
92
|
+
if (this.isVersionPlans) {
|
93
|
+
this.conventionalCommitsConfig = {
|
94
|
+
types: {
|
95
|
+
feat: conventional_commits_1.DEFAULT_CONVENTIONAL_COMMITS_CONFIG.types.feat,
|
96
|
+
fix: conventional_commits_1.DEFAULT_CONVENTIONAL_COMMITS_CONFIG.types.fix,
|
97
|
+
},
|
98
|
+
};
|
99
|
+
for (let i = this.relevantChanges.length - 1; i >= 0; i--) {
|
100
|
+
if (this.relevantChanges[i].isBreaking) {
|
101
|
+
const change = this.relevantChanges[i];
|
102
|
+
this.additionalChangesForAuthorsSection.push(change);
|
103
|
+
const line = this.formatChange(change);
|
104
|
+
this.breakingChanges.push(line);
|
105
|
+
this.relevantChanges.splice(i, 1);
|
106
|
+
}
|
79
107
|
}
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
const scopesSortedAlphabetically = Object.keys(changesGroupedByScope).sort();
|
89
|
-
for (const scope of scopesSortedAlphabetically) {
|
90
|
-
const changes = changesGroupedByScope[scope];
|
91
|
-
for (const change of changes) {
|
92
|
-
const line = formatChange(change, changelogRenderOptions, isVersionPlans, repoData);
|
93
|
-
markdownLines.push(line);
|
94
|
-
if (change.isBreaking) {
|
95
|
-
const breakingChangeExplanation = extractBreakingChangeExplanation(change.body);
|
96
|
-
breakingChanges.push(breakingChangeExplanation
|
97
|
-
? `- ${change.scope ? `**${change.scope.trim()}:** ` : ''}${breakingChangeExplanation}`
|
98
|
-
: line);
|
99
|
-
}
|
108
|
+
}
|
109
|
+
else {
|
110
|
+
for (const change of this.relevantChanges) {
|
111
|
+
if (change.isBreaking) {
|
112
|
+
const breakingChangeExplanation = this.extractBreakingChangeExplanation(change.body);
|
113
|
+
this.breakingChanges.push(breakingChangeExplanation
|
114
|
+
? `- ${change.scope ? `**${change.scope.trim()}:** ` : ''}${breakingChangeExplanation}`
|
115
|
+
: this.formatChange(change));
|
100
116
|
}
|
101
117
|
}
|
102
118
|
}
|
103
119
|
}
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
markdownLines.push('', `${createVersionTitle(releaseVersion, changelogRenderOptions)}\n\n${entryWhenNoChanges}`, '');
|
120
|
-
}
|
121
|
-
return markdownLines.join('\n').trim();
|
120
|
+
shouldRenderEmptyEntry() {
|
121
|
+
return (this.relevantChanges.length === 0 &&
|
122
|
+
this.breakingChanges.length === 0 &&
|
123
|
+
!this.hasDependencyBumps());
|
124
|
+
}
|
125
|
+
renderEmptyEntry() {
|
126
|
+
if (this.hasDependencyBumps()) {
|
127
|
+
return [
|
128
|
+
this.renderVersionTitle(),
|
129
|
+
'',
|
130
|
+
...this.renderDependencyBumps(),
|
131
|
+
].join('\n');
|
132
|
+
}
|
133
|
+
else if (this.entryWhenNoChanges) {
|
134
|
+
return `${this.renderVersionTitle()}\n\n${this.entryWhenNoChanges}`;
|
122
135
|
}
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
136
|
+
return '';
|
137
|
+
}
|
138
|
+
renderVersionTitle() {
|
139
|
+
const isMajorVersion = `${(0, semver_1.major)(this.changelogEntryVersion)}.0.0` ===
|
140
|
+
this.changelogEntryVersion.replace(/^v/, '');
|
141
|
+
let maybeDateStr = '';
|
142
|
+
if (this.changelogRenderOptions.versionTitleDate) {
|
143
|
+
const dateStr = new Date().toISOString().slice(0, 10);
|
144
|
+
maybeDateStr = ` (${dateStr})`;
|
145
|
+
}
|
146
|
+
return isMajorVersion
|
147
|
+
? `# ${this.changelogEntryVersion}${maybeDateStr}`
|
148
|
+
: `## ${this.changelogEntryVersion}${maybeDateStr}`;
|
149
|
+
}
|
150
|
+
renderChangesByType() {
|
151
|
+
const markdownLines = [];
|
152
|
+
const typeGroups = this.groupChangesByType();
|
153
|
+
const changeTypes = this.conventionalCommitsConfig.types;
|
127
154
|
for (const type of Object.keys(changeTypes)) {
|
128
155
|
const group = typeGroups[type];
|
129
156
|
if (!group || group.length === 0) {
|
130
157
|
continue;
|
131
158
|
}
|
132
159
|
markdownLines.push('', `### ${changeTypes[type].changelog.title}`, '');
|
133
|
-
|
134
|
-
|
135
|
-
const
|
136
|
-
|
137
|
-
|
138
|
-
const
|
139
|
-
|
140
|
-
|
141
|
-
|
160
|
+
if (this.project === null) {
|
161
|
+
const changesGroupedByScope = this.groupChangesByScope(group);
|
162
|
+
const scopesSortedAlphabetically = Object.keys(changesGroupedByScope).sort();
|
163
|
+
for (const scope of scopesSortedAlphabetically) {
|
164
|
+
const changes = changesGroupedByScope[scope];
|
165
|
+
for (const change of changes.reverse()) {
|
166
|
+
const line = this.formatChange(change);
|
167
|
+
markdownLines.push(line);
|
168
|
+
if (change.isBreaking && !this.isVersionPlans) {
|
169
|
+
const breakingChangeExplanation = this.extractBreakingChangeExplanation(change.body);
|
170
|
+
this.breakingChanges.push(breakingChangeExplanation
|
171
|
+
? `- ${change.scope ? `**${change.scope.trim()}:** ` : ''}${breakingChangeExplanation}`
|
172
|
+
: line);
|
173
|
+
}
|
174
|
+
}
|
175
|
+
}
|
176
|
+
}
|
177
|
+
else {
|
178
|
+
// For project-specific changelogs, maintain the original order
|
179
|
+
for (const change of group) {
|
180
|
+
const line = this.formatChange(change);
|
181
|
+
markdownLines.push(line);
|
182
|
+
if (change.isBreaking && !this.isVersionPlans) {
|
183
|
+
const breakingChangeExplanation = this.extractBreakingChangeExplanation(change.body);
|
184
|
+
this.breakingChanges.push(breakingChangeExplanation
|
185
|
+
? `- ${change.scope ? `**${change.scope.trim()}:** ` : ''}${breakingChangeExplanation}`
|
186
|
+
: line);
|
187
|
+
}
|
142
188
|
}
|
143
189
|
}
|
144
190
|
}
|
191
|
+
return markdownLines;
|
192
|
+
}
|
193
|
+
hasBreakingChanges() {
|
194
|
+
return this.breakingChanges.length > 0;
|
145
195
|
}
|
146
|
-
|
147
|
-
|
196
|
+
renderBreakingChanges() {
|
197
|
+
const uniqueBreakingChanges = Array.from(new Set(this.breakingChanges));
|
198
|
+
return ['### ⚠️ Breaking Changes', '', ...uniqueBreakingChanges];
|
148
199
|
}
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
200
|
+
hasDependencyBumps() {
|
201
|
+
return this.dependencyBumps && this.dependencyBumps.length > 0;
|
202
|
+
}
|
203
|
+
renderDependencyBumps() {
|
204
|
+
const markdownLines = ['', '### 🧱 Updated Dependencies', ''];
|
205
|
+
this.dependencyBumps.forEach(({ dependencyName, newVersion }) => {
|
206
|
+
markdownLines.push(`- Updated ${dependencyName} to ${newVersion}`);
|
155
207
|
});
|
208
|
+
return markdownLines;
|
209
|
+
}
|
210
|
+
shouldRenderAuthors() {
|
211
|
+
return this.changelogRenderOptions.authors;
|
156
212
|
}
|
157
|
-
|
213
|
+
async renderAuthors() {
|
214
|
+
const markdownLines = [];
|
158
215
|
const _authors = new Map();
|
159
216
|
for (const change of [
|
160
|
-
...relevantChanges,
|
161
|
-
...additionalChangesForAuthorsSection,
|
217
|
+
...this.relevantChanges,
|
218
|
+
...this.additionalChangesForAuthorsSection,
|
162
219
|
]) {
|
163
|
-
if (!change.
|
220
|
+
if (!change.authors) {
|
164
221
|
continue;
|
165
222
|
}
|
166
|
-
const
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
223
|
+
for (const author of change.authors) {
|
224
|
+
const name = this.formatName(author.name);
|
225
|
+
if (!name || name.includes('[bot]')) {
|
226
|
+
continue;
|
227
|
+
}
|
228
|
+
if (_authors.has(name)) {
|
229
|
+
const entry = _authors.get(name);
|
230
|
+
entry.email.add(author.email);
|
231
|
+
}
|
232
|
+
else {
|
233
|
+
_authors.set(name, { email: new Set([author.email]) });
|
234
|
+
}
|
176
235
|
}
|
177
236
|
}
|
178
|
-
|
179
|
-
|
237
|
+
if (this.repoData &&
|
238
|
+
this.changelogRenderOptions.mapAuthorsToGitHubUsernames) {
|
180
239
|
await Promise.all([..._authors.keys()].map(async (authorName) => {
|
181
240
|
const meta = _authors.get(authorName);
|
182
241
|
for (const email of meta.email) {
|
183
|
-
// For these pseudo-anonymized emails we can just extract the Github username from before the @
|
184
|
-
// It could either be in the format: username@ or github_id+username@
|
185
242
|
if (email.endsWith('@users.noreply.github.com')) {
|
186
243
|
const match = email.match(/^(\d+\+)?([^@]+)@users\.noreply\.github\.com$/);
|
187
244
|
if (match && match[2]) {
|
@@ -189,7 +246,6 @@ const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion,
|
|
189
246
|
break;
|
190
247
|
}
|
191
248
|
}
|
192
|
-
// Look up any other emails against the ungh.cc API
|
193
249
|
const { data } = await axios
|
194
250
|
.get(`https://ungh.cc/users/find/${email}`)
|
195
251
|
.catch(() => ({ data: { user: null } }));
|
@@ -206,110 +262,78 @@ const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion,
|
|
206
262
|
}));
|
207
263
|
if (authors.length > 0) {
|
208
264
|
markdownLines.push('', '### ' + '❤️ Thank You', '', ...authors
|
209
|
-
// Sort the contributors by name
|
210
265
|
.sort((a, b) => a.name.localeCompare(b.name))
|
211
266
|
.map((i) => {
|
212
|
-
// Tag the author's Github username if we were able to resolve it so that Github adds them as a contributor
|
213
267
|
const github = i.github ? ` @${i.github}` : '';
|
214
268
|
return `- ${i.name}${github}`;
|
215
269
|
}));
|
216
270
|
}
|
271
|
+
return markdownLines;
|
217
272
|
}
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
}
|
234
|
-
|
235
|
-
|
236
|
-
.
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
groups[item[key]] = groups[item[key]] || [];
|
244
|
-
groups[item[key]].push(item);
|
245
|
-
}
|
246
|
-
return groups;
|
247
|
-
}
|
248
|
-
function formatChange(change, changelogRenderOptions, isVersionPlans, repoData) {
|
249
|
-
let description = change.description;
|
250
|
-
let extraLines = [];
|
251
|
-
let extraLinesStr = '';
|
252
|
-
if (description.includes('\n')) {
|
253
|
-
[description, ...extraLines] = description.split('\n');
|
254
|
-
// Align the extra lines with the start of the description for better readability
|
255
|
-
const indentation = ' ';
|
256
|
-
extraLinesStr = extraLines
|
257
|
-
.filter((l) => l.trim().length > 0)
|
258
|
-
.map((l) => `${indentation}${l}`)
|
259
|
-
.join('\n');
|
260
|
-
}
|
261
|
-
/**
|
262
|
-
* In version plans changelogs:
|
263
|
-
* - don't repeat the breaking change icon
|
264
|
-
* - don't render the scope
|
265
|
-
*/
|
266
|
-
let changeLine = '- ' +
|
267
|
-
(!isVersionPlans && change.isBreaking ? '⚠️ ' : '') +
|
268
|
-
(!isVersionPlans && change.scope ? `**${change.scope.trim()}:** ` : '') +
|
269
|
-
description;
|
270
|
-
if (repoData && changelogRenderOptions.commitReferences) {
|
271
|
-
changeLine += (0, github_1.formatReferences)(change.githubReferences, repoData);
|
272
|
-
}
|
273
|
-
if (extraLinesStr) {
|
274
|
-
changeLine += '\n\n' + extraLinesStr;
|
275
|
-
}
|
276
|
-
return changeLine;
|
277
|
-
}
|
278
|
-
/**
|
279
|
-
* It is common to add further information about a breaking change in the commit body,
|
280
|
-
* and it is naturally that information that should be included in the BREAKING CHANGES
|
281
|
-
* section of changelog, rather than repeating the commit title/description.
|
282
|
-
*/
|
283
|
-
function extractBreakingChangeExplanation(message) {
|
284
|
-
if (!message) {
|
285
|
-
return null;
|
273
|
+
formatChange(change) {
|
274
|
+
let description = change.description;
|
275
|
+
let extraLines = [];
|
276
|
+
let extraLinesStr = '';
|
277
|
+
if (description.includes('\n')) {
|
278
|
+
[description, ...extraLines] = description.split('\n');
|
279
|
+
const indentation = ' ';
|
280
|
+
extraLinesStr = extraLines
|
281
|
+
.filter((l) => l.trim().length > 0)
|
282
|
+
.map((l) => `${indentation}${l}`)
|
283
|
+
.join('\n');
|
284
|
+
}
|
285
|
+
let changeLine = '- ' +
|
286
|
+
(!this.isVersionPlans && change.isBreaking ? '⚠️ ' : '') +
|
287
|
+
(!this.isVersionPlans && change.scope
|
288
|
+
? `**${change.scope.trim()}:** `
|
289
|
+
: '') +
|
290
|
+
description;
|
291
|
+
if (this.repoData && this.changelogRenderOptions.commitReferences) {
|
292
|
+
changeLine += (0, github_1.formatReferences)(change.githubReferences, this.repoData);
|
293
|
+
}
|
294
|
+
if (extraLinesStr) {
|
295
|
+
changeLine += '\n\n' + extraLinesStr;
|
296
|
+
}
|
297
|
+
return changeLine;
|
286
298
|
}
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
299
|
+
groupChangesByType() {
|
300
|
+
const typeGroups = {};
|
301
|
+
for (const change of this.relevantChanges) {
|
302
|
+
typeGroups[change.type] = typeGroups[change.type] || [];
|
303
|
+
typeGroups[change.type].push(change);
|
304
|
+
}
|
305
|
+
return typeGroups;
|
292
306
|
}
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
307
|
+
groupChangesByScope(changes) {
|
308
|
+
const scopeGroups = {};
|
309
|
+
for (const change of changes) {
|
310
|
+
const scope = change.scope || '';
|
311
|
+
scopeGroups[scope] = scopeGroups[scope] || [];
|
312
|
+
scopeGroups[scope].push(change);
|
313
|
+
}
|
314
|
+
return scopeGroups;
|
298
315
|
}
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
const
|
309
|
-
|
316
|
+
extractBreakingChangeExplanation(message) {
|
317
|
+
if (!message) {
|
318
|
+
return null;
|
319
|
+
}
|
320
|
+
const breakingChangeIdentifier = 'BREAKING CHANGE:';
|
321
|
+
const startIndex = message.indexOf(breakingChangeIdentifier);
|
322
|
+
if (startIndex === -1) {
|
323
|
+
return null;
|
324
|
+
}
|
325
|
+
const startOfBreakingChange = startIndex + breakingChangeIdentifier.length;
|
326
|
+
const endOfBreakingChange = message.indexOf('\n', startOfBreakingChange);
|
327
|
+
if (endOfBreakingChange === -1) {
|
328
|
+
return message.substring(startOfBreakingChange).trim();
|
329
|
+
}
|
330
|
+
return message.substring(startOfBreakingChange, endOfBreakingChange).trim();
|
310
331
|
}
|
311
|
-
|
312
|
-
return
|
332
|
+
formatName(name = '') {
|
333
|
+
return name
|
334
|
+
.split(' ')
|
335
|
+
.map((p) => p.trim())
|
336
|
+
.join(' ');
|
313
337
|
}
|
314
|
-
return `## ${version}${maybeDateStr}`;
|
315
338
|
}
|
339
|
+
exports.default = DefaultChangelogRenderer;
|
@@ -103,8 +103,8 @@ async function initializePlugin(pkgName, options, nxJson) {
|
|
103
103
|
if (options.__overrides_unparsed__.length) {
|
104
104
|
args.push(...options.__overrides_unparsed__);
|
105
105
|
}
|
106
|
-
|
107
|
-
|
106
|
+
(0, child_process_2.runNxSync)(`g ${pkgName}:${initGenerator} ${args.join(' ')}`, {
|
107
|
+
stdio: [0, 1, 2],
|
108
108
|
});
|
109
109
|
}
|
110
110
|
catch (e) {
|
@@ -29,6 +29,7 @@ const command_object_23 = require("./login/command-object");
|
|
29
29
|
const command_object_24 = require("./logout/command-object");
|
30
30
|
const command_objects_1 = require("./deprecated/command-objects");
|
31
31
|
const command_object_25 = require("./sync/command-object");
|
32
|
+
const output_1 = require("../utils/output");
|
32
33
|
// Ensure that the output takes up the available width of the terminal.
|
33
34
|
yargs.wrap(yargs.terminalWidth());
|
34
35
|
exports.parserConfiguration = {
|
@@ -82,26 +83,46 @@ exports.commandsObject = yargs
|
|
82
83
|
.command(command_object_23.yargsLoginCommand)
|
83
84
|
.command(command_object_24.yargsLogoutCommand)
|
84
85
|
.command(resolveConformanceCommandObject())
|
86
|
+
.command(resolveConformanceCheckCommandObject())
|
85
87
|
.scriptName('nx')
|
86
88
|
.help()
|
87
89
|
// NOTE: we handle --version in nx.ts, this just tells yargs that the option exists
|
88
90
|
// so that it shows up in help. The default yargs implementation of --version is not
|
89
91
|
// hit, as the implementation in nx.ts is hit first and calls process.exit(0).
|
90
92
|
.version();
|
93
|
+
function createMissingConformanceCommand(command) {
|
94
|
+
return {
|
95
|
+
command,
|
96
|
+
// Hide from --help output in the common case of not having the plugin installed
|
97
|
+
describe: false,
|
98
|
+
handler: () => {
|
99
|
+
output_1.output.error({
|
100
|
+
title: `${command} is not available`,
|
101
|
+
bodyLines: [
|
102
|
+
`In order to use the \`nx ${command}\` command you must have an active Powerpack license and the \`@nx/powerpack-conformance\` plugin installed.`,
|
103
|
+
'',
|
104
|
+
'To learn more, visit https://nx.dev/features/powerpack/conformance',
|
105
|
+
],
|
106
|
+
});
|
107
|
+
process.exit(1);
|
108
|
+
},
|
109
|
+
};
|
110
|
+
}
|
91
111
|
function resolveConformanceCommandObject() {
|
92
112
|
try {
|
93
113
|
const { yargsConformanceCommand } = require('@nx/powerpack-conformance');
|
94
114
|
return yargsConformanceCommand;
|
95
115
|
}
|
96
|
-
catch
|
97
|
-
return
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
116
|
+
catch {
|
117
|
+
return createMissingConformanceCommand('conformance');
|
118
|
+
}
|
119
|
+
}
|
120
|
+
function resolveConformanceCheckCommandObject() {
|
121
|
+
try {
|
122
|
+
const { yargsConformanceCheckCommand, } = require('@nx/powerpack-conformance');
|
123
|
+
return yargsConformanceCheckCommand;
|
124
|
+
}
|
125
|
+
catch {
|
126
|
+
return createMissingConformanceCommand('conformance:check');
|
106
127
|
}
|
107
128
|
}
|