nx 19.7.0-beta.2 → 19.7.0-beta.4
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +12 -12
- package/release/changelog-renderer/index.d.ts +1 -1
- package/release/changelog-renderer/index.js +46 -11
- package/schemas/nx-schema.json +12 -0
- package/src/command-line/add/command-object.js +2 -2
- package/src/command-line/affected/command-object.js +1 -1
- package/src/command-line/connect/command-object.js +11 -4
- package/src/command-line/connect/connect-to-nx-cloud.d.ts +3 -1
- package/src/command-line/connect/connect-to-nx-cloud.js +7 -4
- package/src/command-line/daemon/command-object.js +1 -1
- package/src/command-line/deprecated/command-objects.js +2 -2
- package/src/command-line/exec/command-object.js +1 -1
- package/src/command-line/format/command-object.js +4 -4
- package/src/command-line/generate/command-object.js +4 -4
- package/src/command-line/graph/command-object.js +6 -6
- package/src/command-line/import/command-object.js +9 -5
- package/src/command-line/import/import.d.ts +4 -0
- package/src/command-line/import/import.js +147 -12
- package/src/command-line/import/utils/prepare-source-repo.d.ts +1 -1
- package/src/command-line/import/utils/prepare-source-repo.js +31 -85
- package/src/command-line/list/command-object.js +1 -1
- package/src/command-line/login/command-object.js +1 -1
- package/src/command-line/logout/command-object.js +1 -1
- package/src/command-line/migrate/command-object.js +9 -9
- package/src/command-line/new/command-object.js +2 -2
- package/src/command-line/release/changelog.js +53 -12
- package/src/command-line/release/command-object.d.ts +2 -0
- package/src/command-line/release/command-object.js +37 -33
- package/src/command-line/release/config/version-plans.d.ts +14 -1
- package/src/command-line/release/config/version-plans.js +33 -1
- package/src/command-line/release/index.d.ts +6 -4
- package/src/command-line/release/plan-check.js +8 -61
- package/src/command-line/release/plan.js +131 -37
- package/src/command-line/release/publish.js +3 -0
- package/src/command-line/release/release.js +1 -1
- package/src/command-line/release/utils/get-touched-projects-for-group.d.ts +7 -0
- package/src/command-line/release/utils/get-touched-projects-for-group.js +78 -0
- package/src/command-line/release/utils/git.d.ts +1 -1
- package/src/command-line/release/utils/git.js +46 -19
- package/src/command-line/release/version.js +1 -1
- package/src/command-line/report/command-object.js +1 -1
- package/src/command-line/reset/command-object.js +1 -1
- package/src/command-line/run/command-object.js +1 -1
- package/src/command-line/run-many/command-object.js +1 -1
- package/src/command-line/show/command-object.js +10 -10
- package/src/command-line/sync/sync.js +12 -1
- package/src/command-line/watch/command-object.js +1 -1
- package/src/command-line/yargs-utils/shared-options.d.ts +2 -1
- package/src/command-line/yargs-utils/shared-options.js +26 -29
- package/src/config/nx-json.d.ts +5 -1
- package/src/core/graph/main.js +1 -1
- package/src/daemon/server/sync-generators.d.ts +4 -0
- package/src/daemon/server/sync-generators.js +183 -55
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.d.ts +2 -1
- package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +25 -23
- package/src/nx-cloud/generators/connect-to-nx-cloud/schema.json +4 -0
- package/src/nx-cloud/update-manager.d.ts +1 -1
- package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +8 -1
- package/src/project-graph/plugins/isolation/plugin-pool.js +1 -1
- package/src/tasks-runner/cache.d.ts +2 -0
- package/src/tasks-runner/cache.js +17 -3
- package/src/tasks-runner/run-command.js +5 -11
- package/src/tasks-runner/task-orchestrator.js +1 -10
- package/src/utils/command-line-utils.d.ts +1 -0
- package/src/utils/git-utils.d.ts +7 -10
- package/src/utils/git-utils.js +61 -44
- package/src/utils/sync-generators.d.ts +8 -5
- package/src/utils/sync-generators.js +27 -5
- package/src/utils/squash.d.ts +0 -1
- package/src/utils/squash.js +0 -12
@@ -10,6 +10,8 @@ const tmp_1 = require("tmp");
|
|
10
10
|
const nx_json_1 = require("../../config/nx-json");
|
11
11
|
const file_map_utils_1 = require("../../project-graph/file-map-utils");
|
12
12
|
const project_graph_1 = require("../../project-graph/project-graph");
|
13
|
+
const all_file_data_1 = require("../../utils/all-file-data");
|
14
|
+
const command_line_utils_1 = require("../../utils/command-line-utils");
|
13
15
|
const output_1 = require("../../utils/output");
|
14
16
|
const params_1 = require("../../utils/params");
|
15
17
|
const config_1 = require("./config/config");
|
@@ -17,6 +19,7 @@ const deep_merge_json_1 = require("./config/deep-merge-json");
|
|
17
19
|
const filter_release_groups_1 = require("./config/filter-release-groups");
|
18
20
|
const version_plans_1 = require("./config/version-plans");
|
19
21
|
const generate_version_plan_content_1 = require("./utils/generate-version-plan-content");
|
22
|
+
const get_touched_projects_for_group_1 = require("./utils/get-touched-projects-for-group");
|
20
23
|
const launch_editor_1 = require("./utils/launch-editor");
|
21
24
|
const print_changes_1 = require("./utils/print-changes");
|
22
25
|
const print_config_1 = require("./utils/print-config");
|
@@ -45,64 +48,155 @@ function createAPI(overrideReleaseConfig) {
|
|
45
48
|
output_1.output.error(filterError);
|
46
49
|
process.exit(1);
|
47
50
|
}
|
51
|
+
// If no release groups have version plans enabled, it doesn't make sense to use the plan command only to set yourself up for an error at release time
|
52
|
+
if (!releaseGroups.some((group) => group.versionPlans === true)) {
|
53
|
+
if (releaseGroups.length === 1) {
|
54
|
+
output_1.output.warn({
|
55
|
+
title: `Version plans are not enabled in your release configuration`,
|
56
|
+
bodyLines: [
|
57
|
+
'To enable version plans, set `"versionPlans": true` at the top level of your `"release"` configuration',
|
58
|
+
],
|
59
|
+
});
|
60
|
+
return 0;
|
61
|
+
}
|
62
|
+
output_1.output.warn({
|
63
|
+
title: 'No release groups have version plans enabled',
|
64
|
+
bodyLines: [
|
65
|
+
'To enable version plans, set `"versionPlans": true` at the top level of your `"release"` configuration to apply it to all groups, otherwise set it at the release group level',
|
66
|
+
],
|
67
|
+
});
|
68
|
+
return 0;
|
69
|
+
}
|
70
|
+
// Resolve the final values for base, head etc to use when resolving the changes to consider
|
71
|
+
const { nxArgs } = (0, command_line_utils_1.splitArgsIntoNxArgsAndOverrides)(args, 'affected', {
|
72
|
+
printWarnings: args.verbose,
|
73
|
+
}, nxJson);
|
48
74
|
const versionPlanBumps = {};
|
49
75
|
const setBumpIfNotNone = (projectOrGroup, version) => {
|
50
76
|
if (version !== 'none') {
|
51
77
|
versionPlanBumps[projectOrGroup] = version;
|
52
78
|
}
|
53
79
|
};
|
54
|
-
if
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
80
|
+
// Changed files are only relevant if considering touched projects
|
81
|
+
let changedFiles = [];
|
82
|
+
let getProjectsToVersionForGroup;
|
83
|
+
if (args.onlyTouched) {
|
84
|
+
changedFiles = (0, command_line_utils_1.parseFiles)(nxArgs).files;
|
85
|
+
if (nxArgs.verbose) {
|
86
|
+
if (changedFiles.length) {
|
87
|
+
output_1.output.log({
|
88
|
+
title: `Changed files based on resolved "base" (${nxArgs.base}) and "head" (${nxArgs.head ?? 'HEAD'})`,
|
89
|
+
bodyLines: changedFiles.map((file) => ` - ${file}`),
|
90
|
+
});
|
91
|
+
}
|
92
|
+
else {
|
93
|
+
output_1.output.warn({
|
94
|
+
title: 'No changed files found based on resolved "base" and "head"',
|
95
|
+
});
|
60
96
|
}
|
61
97
|
}
|
62
|
-
|
63
|
-
|
64
|
-
setBumpIfNotNone(group.name, args.bump ||
|
65
|
-
(await promptForVersion(`How do you want to bump the versions of all projects?`)));
|
66
|
-
}
|
98
|
+
const resolvedAllFileData = await (0, all_file_data_1.allFileData)();
|
99
|
+
getProjectsToVersionForGroup = (0, get_touched_projects_for_group_1.createGetTouchedProjectsForGroup)(nxArgs, projectGraph, changedFiles, resolvedAllFileData);
|
67
100
|
}
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
101
|
+
if (args.projects?.length) {
|
102
|
+
/**
|
103
|
+
* Run plan for all remaining release groups and filtered projects within them
|
104
|
+
*/
|
105
|
+
for (const releaseGroup of releaseGroups) {
|
106
|
+
const releaseGroupName = releaseGroup.name;
|
107
|
+
const releaseGroupProjectNames = Array.from(releaseGroupToFilteredProjects.get(releaseGroup));
|
108
|
+
let applicableProjects = releaseGroupProjectNames;
|
109
|
+
if (args.onlyTouched &&
|
110
|
+
typeof getProjectsToVersionForGroup === 'function') {
|
111
|
+
applicableProjects = await getProjectsToVersionForGroup(releaseGroup, releaseGroupProjectNames, true);
|
112
|
+
}
|
113
|
+
if (!applicableProjects.length) {
|
114
|
+
continue;
|
115
|
+
}
|
116
|
+
if (releaseGroup.projectsRelationship === 'independent') {
|
117
|
+
for (const project of applicableProjects) {
|
72
118
|
setBumpIfNotNone(project, args.bump ||
|
73
|
-
(await promptForVersion(`How do you want to bump the version of the project "${project}"
|
119
|
+
(await promptForVersion(`How do you want to bump the version of the project "${project}"${releaseGroupName === config_1.IMPLICIT_DEFAULT_RELEASE_GROUP
|
120
|
+
? ''
|
121
|
+
: ` within group "${releaseGroupName}"`}?`)));
|
74
122
|
}
|
75
123
|
}
|
76
124
|
else {
|
77
|
-
setBumpIfNotNone(
|
78
|
-
(await promptForVersion(`How do you want to bump the versions of
|
125
|
+
setBumpIfNotNone(releaseGroupName, args.bump ||
|
126
|
+
(await promptForVersion(`How do you want to bump the versions of ${releaseGroupName === config_1.IMPLICIT_DEFAULT_RELEASE_GROUP
|
127
|
+
? 'all projects'
|
128
|
+
: `the projects in the group "${releaseGroupName}"`}?`)));
|
79
129
|
}
|
80
130
|
}
|
81
|
-
|
82
|
-
|
83
|
-
output_1.output.warn({
|
84
|
-
title: 'No version bumps were selected so no version plan file was created.',
|
85
|
-
});
|
131
|
+
// Create a version plan file if applicable
|
132
|
+
await createVersionPlanFileForBumps(args, versionPlanBumps);
|
86
133
|
return 0;
|
87
134
|
}
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
const
|
92
|
-
|
93
|
-
|
94
|
-
(
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
(
|
99
|
-
|
100
|
-
|
101
|
-
|
135
|
+
/**
|
136
|
+
* Run plan for all remaining release groups
|
137
|
+
*/
|
138
|
+
for (const releaseGroup of releaseGroups) {
|
139
|
+
const releaseGroupName = releaseGroup.name;
|
140
|
+
let applicableProjects = releaseGroup.projects;
|
141
|
+
if (args.onlyTouched &&
|
142
|
+
typeof getProjectsToVersionForGroup === 'function') {
|
143
|
+
applicableProjects = await getProjectsToVersionForGroup(releaseGroup, releaseGroup.projects, false);
|
144
|
+
}
|
145
|
+
if (!applicableProjects.length) {
|
146
|
+
continue;
|
147
|
+
}
|
148
|
+
if (releaseGroup.projectsRelationship === 'independent') {
|
149
|
+
for (const project of applicableProjects) {
|
150
|
+
setBumpIfNotNone(project, args.bump ||
|
151
|
+
(await promptForVersion(`How do you want to bump the version of the project "${project}"${releaseGroupName === config_1.IMPLICIT_DEFAULT_RELEASE_GROUP
|
152
|
+
? ''
|
153
|
+
: ` within group "${releaseGroupName}"`}?`)));
|
154
|
+
}
|
155
|
+
}
|
156
|
+
else {
|
157
|
+
setBumpIfNotNone(releaseGroupName, args.bump ||
|
158
|
+
(await promptForVersion(`How do you want to bump the versions of ${releaseGroupName === config_1.IMPLICIT_DEFAULT_RELEASE_GROUP
|
159
|
+
? 'all projects'
|
160
|
+
: `the projects in the group "${releaseGroupName}"`}?`)));
|
161
|
+
}
|
102
162
|
}
|
163
|
+
// Create a version plan file if applicable
|
164
|
+
await createVersionPlanFileForBumps(args, versionPlanBumps);
|
103
165
|
return 0;
|
104
166
|
};
|
105
167
|
}
|
168
|
+
async function createVersionPlanFileForBumps(args, versionPlanBumps) {
|
169
|
+
if (!Object.keys(versionPlanBumps).length) {
|
170
|
+
let bodyLines = [];
|
171
|
+
if (args.onlyTouched) {
|
172
|
+
bodyLines = [
|
173
|
+
'This might be because no projects have been changed, or projects you expected to release have not been touched',
|
174
|
+
'To include all projects, not just those that have been changed, pass --only-touched=false',
|
175
|
+
'Alternatively, you can specify alternate --base and --head refs to include only changes from certain commits',
|
176
|
+
];
|
177
|
+
}
|
178
|
+
output_1.output.warn({
|
179
|
+
title: 'No version bumps were selected so no version plan file was created.',
|
180
|
+
bodyLines,
|
181
|
+
});
|
182
|
+
return 0;
|
183
|
+
}
|
184
|
+
const versionPlanName = `version-plan-${new Date().getTime()}`;
|
185
|
+
const versionPlanMessage = args.message || (await promptForMessage(versionPlanName));
|
186
|
+
const versionPlanFileContent = (0, generate_version_plan_content_1.generateVersionPlanContent)(versionPlanBumps, versionPlanMessage);
|
187
|
+
const versionPlanFileName = `${versionPlanName}.md`;
|
188
|
+
if (args.dryRun) {
|
189
|
+
output_1.output.logSingleLine(`Would create version plan file "${versionPlanFileName}", but --dry-run was set.`);
|
190
|
+
(0, print_changes_1.printDiff)('', versionPlanFileContent, 1);
|
191
|
+
}
|
192
|
+
else {
|
193
|
+
output_1.output.logSingleLine(`Creating version plan file "${versionPlanFileName}"`);
|
194
|
+
(0, print_changes_1.printDiff)('', versionPlanFileContent, 1);
|
195
|
+
const versionPlansAbsolutePath = (0, version_plans_1.getVersionPlansAbsolutePath)();
|
196
|
+
await (0, fs_extra_1.ensureDir)(versionPlansAbsolutePath);
|
197
|
+
await (0, fs_extra_1.writeFile)((0, node_path_1.join)(versionPlansAbsolutePath, versionPlanFileName), versionPlanFileContent);
|
198
|
+
}
|
199
|
+
}
|
106
200
|
async function promptForVersion(message) {
|
107
201
|
try {
|
108
202
|
const reply = await (0, enquirer_1.prompt)([
|
@@ -103,6 +103,9 @@ async function runPublishOnProjects(args, projectGraph, nxJson, projectNames, is
|
|
103
103
|
if (args.otp) {
|
104
104
|
overrides.otp = args.otp;
|
105
105
|
}
|
106
|
+
if (args.access) {
|
107
|
+
overrides.access = args.access;
|
108
|
+
}
|
106
109
|
if (args.dryRun) {
|
107
110
|
overrides.dryRun = args.dryRun;
|
108
111
|
/**
|
@@ -94,7 +94,7 @@ function createAPI(overrideReleaseConfig) {
|
|
94
94
|
output_1.output.error(filterError);
|
95
95
|
process.exit(1);
|
96
96
|
}
|
97
|
-
(0, version_plans_1.setResolvedVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes));
|
97
|
+
await (0, version_plans_1.setResolvedVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes), args.verbose);
|
98
98
|
const planFiles = new Set();
|
99
99
|
releaseGroups.forEach((group) => {
|
100
100
|
if (group.resolvedVersionPlans) {
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import { FileData, ProjectGraph } from '../../../config/project-graph';
|
2
|
+
import { NxArgs } from '../../../utils/command-line-utils';
|
3
|
+
import { ReleaseGroupWithName } from '../config/filter-release-groups';
|
4
|
+
/**
|
5
|
+
* Create a function that returns the touched projects for a given release group. Only relevant when version plans are enabled.
|
6
|
+
*/
|
7
|
+
export declare function createGetTouchedProjectsForGroup(nxArgs: NxArgs, projectGraph: ProjectGraph, changedFiles: string[], fileData: FileData[]): (releaseGroup: ReleaseGroupWithName, releaseGroupFilteredProjectNames: string[], hasProjectsFilter: boolean) => Promise<string[]>;
|
@@ -0,0 +1,78 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.createGetTouchedProjectsForGroup = createGetTouchedProjectsForGroup;
|
4
|
+
const workspace_projects_1 = require("../../../project-graph/affected/locators/workspace-projects");
|
5
|
+
const file_utils_1 = require("../../../project-graph/file-utils");
|
6
|
+
const ignore_1 = require("../../../utils/ignore");
|
7
|
+
const output_1 = require("../../../utils/output");
|
8
|
+
const config_1 = require("../config/config");
|
9
|
+
/**
|
10
|
+
* Create a function that returns the touched projects for a given release group. Only relevant when version plans are enabled.
|
11
|
+
*/
|
12
|
+
function createGetTouchedProjectsForGroup(nxArgs, projectGraph, changedFiles, fileData) {
|
13
|
+
/**
|
14
|
+
* Create a minimal subset of touched projects based on the configured ignore patterns, we only need
|
15
|
+
* to recompute when the ignorePatternsForPlanCheck differs between release groups.
|
16
|
+
*/
|
17
|
+
const serializedIgnorePatternsToTouchedProjects = new Map();
|
18
|
+
return async function getTouchedProjectsForGroup(releaseGroup,
|
19
|
+
// We don't access releaseGroups.projects directly, because we need to take the --projects filter into account
|
20
|
+
releaseGroupFilteredProjectNames, hasProjectsFilter) {
|
21
|
+
// The current release group doesn't leverage version plans
|
22
|
+
if (!releaseGroup.versionPlans) {
|
23
|
+
return [];
|
24
|
+
}
|
25
|
+
// Exclude patterns from .nxignore, .gitignore and explicit version plan config
|
26
|
+
let serializedIgnorePatterns = '[]';
|
27
|
+
const ignore = (0, ignore_1.getIgnoreObject)();
|
28
|
+
if (typeof releaseGroup.versionPlans !== 'boolean' &&
|
29
|
+
Array.isArray(releaseGroup.versionPlans.ignorePatternsForPlanCheck) &&
|
30
|
+
releaseGroup.versionPlans.ignorePatternsForPlanCheck.length) {
|
31
|
+
output_1.output.note({
|
32
|
+
title: `Applying configured ignore patterns to changed files${releaseGroup.name !== config_1.IMPLICIT_DEFAULT_RELEASE_GROUP
|
33
|
+
? ` for release group "${releaseGroup.name}"`
|
34
|
+
: ''}`,
|
35
|
+
bodyLines: [
|
36
|
+
...releaseGroup.versionPlans.ignorePatternsForPlanCheck.map((pattern) => ` - ${pattern}`),
|
37
|
+
],
|
38
|
+
});
|
39
|
+
ignore.add(releaseGroup.versionPlans.ignorePatternsForPlanCheck);
|
40
|
+
serializedIgnorePatterns = JSON.stringify(releaseGroup.versionPlans.ignorePatternsForPlanCheck);
|
41
|
+
}
|
42
|
+
let touchedProjects = {};
|
43
|
+
if (serializedIgnorePatternsToTouchedProjects.has(serializedIgnorePatterns)) {
|
44
|
+
touchedProjects = serializedIgnorePatternsToTouchedProjects.get(serializedIgnorePatterns);
|
45
|
+
}
|
46
|
+
else {
|
47
|
+
// We only care about directly touched projects, not implicitly affected ones etc
|
48
|
+
const touchedProjectsArr = await (0, workspace_projects_1.getTouchedProjects)((0, file_utils_1.calculateFileChanges)(changedFiles, fileData, nxArgs, undefined, ignore), projectGraph.nodes);
|
49
|
+
touchedProjects = touchedProjectsArr.reduce((acc, project) => ({ ...acc, [project]: true }), {});
|
50
|
+
serializedIgnorePatternsToTouchedProjects.set(serializedIgnorePatterns, touchedProjects);
|
51
|
+
}
|
52
|
+
const touchedProjectsUnderReleaseGroup = releaseGroupFilteredProjectNames.filter((project) => touchedProjects[project]);
|
53
|
+
if (touchedProjectsUnderReleaseGroup.length) {
|
54
|
+
output_1.output.log({
|
55
|
+
title: `Touched projects${hasProjectsFilter ? ` (after --projects filter applied)` : ''} based on changed files${releaseGroup.name !== config_1.IMPLICIT_DEFAULT_RELEASE_GROUP
|
56
|
+
? ` under release group "${releaseGroup.name}"`
|
57
|
+
: ''}`,
|
58
|
+
bodyLines: [
|
59
|
+
...touchedProjectsUnderReleaseGroup.map((project) => ` - ${project}`),
|
60
|
+
'',
|
61
|
+
'NOTE: You can adjust your "versionPlans.ignorePatternsForPlanCheck" config to stop certain files from resulting in projects being classed as touched for the purposes of this command.',
|
62
|
+
],
|
63
|
+
});
|
64
|
+
}
|
65
|
+
else {
|
66
|
+
output_1.output.log({
|
67
|
+
title: `No touched projects${hasProjectsFilter ? ` (after --projects filter applied)` : ''} found based on changed files${typeof releaseGroup.versionPlans !== 'boolean' &&
|
68
|
+
Array.isArray(releaseGroup.versionPlans.ignorePatternsForPlanCheck) &&
|
69
|
+
releaseGroup.versionPlans.ignorePatternsForPlanCheck.length
|
70
|
+
? ' combined with configured ignore patterns'
|
71
|
+
: ''}${releaseGroup.name !== config_1.IMPLICIT_DEFAULT_RELEASE_GROUP
|
72
|
+
? ` under release group "${releaseGroup.name}"`
|
73
|
+
: ''}`,
|
74
|
+
});
|
75
|
+
}
|
76
|
+
return touchedProjectsUnderReleaseGroup;
|
77
|
+
};
|
78
|
+
}
|
@@ -62,6 +62,6 @@ export declare function parseConventionalCommitsMessage(message: string): {
|
|
62
62
|
description: string;
|
63
63
|
breaking: boolean;
|
64
64
|
} | null;
|
65
|
-
export declare function parseGitCommit(commit: RawGitCommit): GitCommit | null;
|
65
|
+
export declare function parseGitCommit(commit: RawGitCommit, isVersionPlanCommit?: boolean): GitCommit | null;
|
66
66
|
export declare function getCommitHash(ref: string): Promise<string>;
|
67
67
|
export declare function getFirstGitCommit(): Promise<string>;
|
@@ -136,7 +136,7 @@ async function gitAdd({ changedFiles, deletedFiles, dryRun, verbose, logFn, cwd,
|
|
136
136
|
ignoredFiles.push(f);
|
137
137
|
// git add will fail if trying to add an untracked file that doesn't exist
|
138
138
|
}
|
139
|
-
else if (changedTrackedFiles.has(f)) {
|
139
|
+
else if (changedTrackedFiles.has(f) || dryRun) {
|
140
140
|
filesToAdd.push(f);
|
141
141
|
}
|
142
142
|
}
|
@@ -281,6 +281,30 @@ function parseConventionalCommitsMessage(message) {
|
|
281
281
|
breaking: Boolean(match.groups.breaking),
|
282
282
|
};
|
283
283
|
}
|
284
|
+
function extractReferencesFromCommitMessage(message, shortHash) {
|
285
|
+
const references = [];
|
286
|
+
for (const m of message.matchAll(PullRequestRE)) {
|
287
|
+
references.push({ type: 'pull-request', value: m[1] });
|
288
|
+
}
|
289
|
+
for (const m of message.matchAll(IssueRE)) {
|
290
|
+
if (!references.some((i) => i.value === m[1])) {
|
291
|
+
references.push({ type: 'issue', value: m[1] });
|
292
|
+
}
|
293
|
+
}
|
294
|
+
references.push({ value: shortHash, type: 'hash' });
|
295
|
+
return references;
|
296
|
+
}
|
297
|
+
function getAllAuthorsForCommit(commit) {
|
298
|
+
const authors = [commit.author];
|
299
|
+
// Additional authors can be specified in the commit body (depending on the VCS provider)
|
300
|
+
for (const match of commit.body.matchAll(CoAuthoredByRegex)) {
|
301
|
+
authors.push({
|
302
|
+
name: (match.groups.name || '').trim(),
|
303
|
+
email: (match.groups.email || '').trim(),
|
304
|
+
});
|
305
|
+
}
|
306
|
+
return authors;
|
307
|
+
}
|
284
308
|
// https://www.conventionalcommits.org/en/v1.0.0/
|
285
309
|
// https://regex101.com/r/FSfNvA/1
|
286
310
|
const ConventionalCommitRegex = /(?<type>[a-z]+)(\((?<scope>.+)\))?(?<breaking>!)?: (?<description>.+)/i;
|
@@ -289,7 +313,25 @@ const PullRequestRE = /\([ a-z]*(#\d+)\s*\)/gm;
|
|
289
313
|
const IssueRE = /(#\d+)/gm;
|
290
314
|
const ChangedFileRegex = /(A|M|D|R\d*|C\d*)\t([^\t\n]*)\t?(.*)?/gm;
|
291
315
|
const RevertHashRE = /This reverts commit (?<hash>[\da-f]{40})./gm;
|
292
|
-
function parseGitCommit(commit) {
|
316
|
+
function parseGitCommit(commit, isVersionPlanCommit = false) {
|
317
|
+
// For version plans, we do not require conventional commits and therefore cannot extract data based on that format
|
318
|
+
if (isVersionPlanCommit) {
|
319
|
+
return {
|
320
|
+
...commit,
|
321
|
+
description: commit.message,
|
322
|
+
type: '',
|
323
|
+
scope: '',
|
324
|
+
references: extractReferencesFromCommitMessage(commit.message, commit.shortHash),
|
325
|
+
// The commit message is not the source of truth for a breaking (major) change in version plans, so the value is not relevant
|
326
|
+
// TODO(v20): Make the current GitCommit interface more clearly tied to conventional commits
|
327
|
+
isBreaking: false,
|
328
|
+
authors: getAllAuthorsForCommit(commit),
|
329
|
+
// Not applicable to version plans
|
330
|
+
affectedFiles: [],
|
331
|
+
// Not applicable, a version plan cannot have been added in a commit that also reverts another commit
|
332
|
+
revertedHashes: [],
|
333
|
+
};
|
334
|
+
}
|
293
335
|
const parsedMessage = parseConventionalCommitsMessage(commit.message);
|
294
336
|
if (!parsedMessage) {
|
295
337
|
return null;
|
@@ -298,16 +340,7 @@ function parseGitCommit(commit) {
|
|
298
340
|
const isBreaking = parsedMessage.breaking || commit.body.includes('BREAKING CHANGE:');
|
299
341
|
let description = parsedMessage.description;
|
300
342
|
// Extract references from message
|
301
|
-
const references =
|
302
|
-
for (const m of description.matchAll(PullRequestRE)) {
|
303
|
-
references.push({ type: 'pull-request', value: m[1] });
|
304
|
-
}
|
305
|
-
for (const m of description.matchAll(IssueRE)) {
|
306
|
-
if (!references.some((i) => i.value === m[1])) {
|
307
|
-
references.push({ type: 'issue', value: m[1] });
|
308
|
-
}
|
309
|
-
}
|
310
|
-
references.push({ value: commit.shortHash, type: 'hash' });
|
343
|
+
const references = extractReferencesFromCommitMessage(description, commit.shortHash);
|
311
344
|
// Remove references and normalize
|
312
345
|
description = description.replace(PullRequestRE, '').trim();
|
313
346
|
let type = parsedMessage.type;
|
@@ -322,13 +355,7 @@ function parseGitCommit(commit) {
|
|
322
355
|
description = commit.message;
|
323
356
|
}
|
324
357
|
// Find all authors
|
325
|
-
const authors =
|
326
|
-
for (const match of commit.body.matchAll(CoAuthoredByRegex)) {
|
327
|
-
authors.push({
|
328
|
-
name: (match.groups.name || '').trim(),
|
329
|
-
email: (match.groups.email || '').trim(),
|
330
|
-
});
|
331
|
-
}
|
358
|
+
const authors = getAllAuthorsForCommit(commit);
|
332
359
|
// Extract file changes from commit body
|
333
360
|
const affectedFiles = Array.from(commit.body.matchAll(ChangedFileRegex)).reduce((prev, [fullLine, changeType, file1, file2]) =>
|
334
361
|
// file2 only exists for some change types, such as renames
|
@@ -82,7 +82,7 @@ function createAPI(overrideReleaseConfig) {
|
|
82
82
|
}
|
83
83
|
if (!args.specifier) {
|
84
84
|
const rawVersionPlans = await (0, version_plans_1.readRawVersionPlans)();
|
85
|
-
(0, version_plans_1.setResolvedVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes));
|
85
|
+
await (0, version_plans_1.setResolvedVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes), args.verbose);
|
86
86
|
}
|
87
87
|
else {
|
88
88
|
if (args.verbose && releaseGroups.some((g) => !!g.versionPlans)) {
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.yargsReportCommand = void 0;
|
4
4
|
exports.yargsReportCommand = {
|
5
5
|
command: 'report',
|
6
|
-
describe: 'Reports useful version numbers to copy into the Nx issue template',
|
6
|
+
describe: 'Reports useful version numbers to copy into the Nx issue template.',
|
7
7
|
handler: async () => {
|
8
8
|
await (await Promise.resolve().then(() => require('./report'))).reportHandler();
|
9
9
|
process.exit(0);
|
@@ -19,7 +19,7 @@ exports.yargsResetCommand = {
|
|
19
19
|
type: 'boolean',
|
20
20
|
})
|
21
21
|
.option('onlyWorkspaceData', {
|
22
|
-
description: 'Clears the workspace data directory. Used by Nx to store cached data about the current workspace (e.g. partial results, incremental data, etc)',
|
22
|
+
description: 'Clears the workspace data directory. Used by Nx to store cached data about the current workspace (e.g. partial results, incremental data, etc).',
|
23
23
|
type: 'boolean',
|
24
24
|
}),
|
25
25
|
handler: async (argv) => (await Promise.resolve().then(() => require('./reset'))).resetHandler(argv),
|
@@ -27,7 +27,7 @@ exports.yargsRunCommand = {
|
|
27
27
|
exports.yargsNxInfixCommand = {
|
28
28
|
...exports.yargsRunCommand,
|
29
29
|
command: '$0 <target> [project] [_..]',
|
30
|
-
describe: 'Run a target for a project',
|
30
|
+
describe: 'Run a target for a project.',
|
31
31
|
handler: async (args) => {
|
32
32
|
const exitCode = await (0, params_1.handleErrors)(args.verbose ?? process.env.NX_VERBOSE_LOGGING === 'true', async () => {
|
33
33
|
// Yargs parses <target> as 'undefined' if running just 'nx'
|
@@ -6,7 +6,7 @@ const shared_options_1 = require("../yargs-utils/shared-options");
|
|
6
6
|
const params_1 = require("../../utils/params");
|
7
7
|
exports.yargsRunManyCommand = {
|
8
8
|
command: 'run-many',
|
9
|
-
describe: 'Run target for multiple listed projects',
|
9
|
+
describe: 'Run target for multiple listed projects.',
|
10
10
|
builder: (yargs) => (0, documentation_1.linkToNxDevAndExamples)((0, shared_options_1.withRunManyOptions)((0, shared_options_1.withOutputStyleOption)((0, shared_options_1.withTargetAndConfigurationOption)((0, shared_options_1.withBatch)(yargs)))), 'run-many'),
|
11
11
|
handler: async (args) => {
|
12
12
|
const exitCode = await (0, params_1.handleErrors)(args.verbose ?? process.env.NX_VERBOSE_LOGGING === 'true', async () => {
|
@@ -6,14 +6,14 @@ const shared_options_1 = require("../yargs-utils/shared-options");
|
|
6
6
|
const params_1 = require("../../utils/params");
|
7
7
|
exports.yargsShowCommand = {
|
8
8
|
command: 'show',
|
9
|
-
describe: 'Show information about the workspace (e.g., list of projects)',
|
9
|
+
describe: 'Show information about the workspace (e.g., list of projects).',
|
10
10
|
builder: (yargs) => yargs
|
11
11
|
.command(showProjectsCommand)
|
12
12
|
.command(showProjectCommand)
|
13
13
|
.demandCommand()
|
14
14
|
.option('json', {
|
15
15
|
type: 'boolean',
|
16
|
-
description: 'Output JSON',
|
16
|
+
description: 'Output JSON.',
|
17
17
|
})
|
18
18
|
.example('$0 show projects', 'Show a list of all projects in the workspace')
|
19
19
|
.example('$0 show projects --with-target serve', 'Show a list of all projects in the workspace that have a "serve" target')
|
@@ -25,11 +25,11 @@ exports.yargsShowCommand = {
|
|
25
25
|
};
|
26
26
|
const showProjectsCommand = {
|
27
27
|
command: 'projects',
|
28
|
-
describe: 'Show a list of projects in the workspace',
|
28
|
+
describe: 'Show a list of projects in the workspace.',
|
29
29
|
builder: (yargs) => (0, shared_options_1.withVerbose)((0, shared_options_1.withAffectedOptions)(yargs))
|
30
30
|
.option('affected', {
|
31
31
|
type: 'boolean',
|
32
|
-
description: 'Show only affected projects',
|
32
|
+
description: 'Show only affected projects.',
|
33
33
|
})
|
34
34
|
.option('projects', {
|
35
35
|
type: 'string',
|
@@ -40,17 +40,17 @@ const showProjectsCommand = {
|
|
40
40
|
.option('withTarget', {
|
41
41
|
type: 'string',
|
42
42
|
alias: ['t'],
|
43
|
-
description: 'Show only projects that have a specific target',
|
43
|
+
description: 'Show only projects that have a specific target.',
|
44
44
|
coerce: shared_options_1.parseCSV,
|
45
45
|
})
|
46
46
|
.option('type', {
|
47
47
|
type: 'string',
|
48
|
-
description: 'Select only projects of the given type',
|
48
|
+
description: 'Select only projects of the given type.',
|
49
49
|
choices: ['app', 'lib', 'e2e'],
|
50
50
|
})
|
51
51
|
.option('sep', {
|
52
52
|
type: 'string',
|
53
|
-
description: 'Outputs projects with the specified seperator',
|
53
|
+
description: 'Outputs projects with the specified seperator.',
|
54
54
|
})
|
55
55
|
.implies('untracked', 'affected')
|
56
56
|
.implies('uncommitted', 'affected')
|
@@ -79,15 +79,15 @@ const showProjectCommand = {
|
|
79
79
|
.positional('projectName', {
|
80
80
|
type: 'string',
|
81
81
|
alias: 'p',
|
82
|
-
description: 'Which project should be viewed
|
82
|
+
description: 'Which project should be viewed?.',
|
83
83
|
})
|
84
84
|
.option('web', {
|
85
85
|
type: 'boolean',
|
86
|
-
description: 'Show project details in the browser. (default when interactive)',
|
86
|
+
description: 'Show project details in the browser. (default when interactive).',
|
87
87
|
})
|
88
88
|
.option('open', {
|
89
89
|
type: 'boolean',
|
90
|
-
description: 'Set to false to prevent the browser from opening when using --web',
|
90
|
+
description: 'Set to false to prevent the browser from opening when using --web.',
|
91
91
|
implies: 'web',
|
92
92
|
})
|
93
93
|
.check((argv) => {
|
@@ -2,6 +2,7 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.syncHandler = syncHandler;
|
4
4
|
const ora = require("ora");
|
5
|
+
const nx_json_1 = require("../../config/nx-json");
|
5
6
|
const project_graph_1 = require("../../project-graph/project-graph");
|
6
7
|
const output_1 = require("../../utils/output");
|
7
8
|
const params_1 = require("../../utils/params");
|
@@ -10,7 +11,17 @@ const chalk = require("chalk");
|
|
10
11
|
function syncHandler(options) {
|
11
12
|
return (0, params_1.handleErrors)(options.verbose, async () => {
|
12
13
|
const projectGraph = await (0, project_graph_1.createProjectGraphAsync)();
|
13
|
-
const
|
14
|
+
const nxJson = (0, nx_json_1.readNxJson)();
|
15
|
+
const syncGenerators = await (0, sync_generators_1.collectAllRegisteredSyncGenerators)(projectGraph, nxJson);
|
16
|
+
if (!syncGenerators.length) {
|
17
|
+
output_1.output.success({
|
18
|
+
title: options.check
|
19
|
+
? 'The workspace is up to date'
|
20
|
+
: 'The workspace is already up to date',
|
21
|
+
bodyLines: ['There are no sync generators to run.'],
|
22
|
+
});
|
23
|
+
return 0;
|
24
|
+
}
|
14
25
|
const results = await (0, sync_generators_1.getSyncGeneratorChanges)(syncGenerators);
|
15
26
|
if (!results.length) {
|
16
27
|
output_1.output.success({
|
@@ -5,7 +5,7 @@ const documentation_1 = require("../yargs-utils/documentation");
|
|
5
5
|
const shared_options_1 = require("../yargs-utils/shared-options");
|
6
6
|
exports.yargsWatchCommand = {
|
7
7
|
command: 'watch',
|
8
|
-
describe: 'Watch for changes within projects, and execute commands',
|
8
|
+
describe: 'Watch for changes within projects, and execute commands.',
|
9
9
|
builder: (yargs) => (0, documentation_1.linkToNxDevAndExamples)(withWatchOptions(yargs), 'watch'),
|
10
10
|
handler: async (args) => {
|
11
11
|
await Promise.resolve().then(() => require('./watch')).then((m) => m.watch(args));
|
@@ -3,7 +3,7 @@ interface ExcludeOptions {
|
|
3
3
|
exclude: string[];
|
4
4
|
}
|
5
5
|
export declare const defaultYargsParserConfiguration: Partial<ParserConfigurationOptions>;
|
6
|
-
export declare function withExcludeOption(yargs: Argv): Argv<ExcludeOptions>;
|
6
|
+
export declare function withExcludeOption<T>(yargs: Argv<T>): Argv<T & ExcludeOptions>;
|
7
7
|
export interface RunOptions {
|
8
8
|
exclude: string;
|
9
9
|
parallel: string;
|
@@ -20,6 +20,7 @@ export interface RunOptions {
|
|
20
20
|
batch: boolean;
|
21
21
|
useAgents: boolean;
|
22
22
|
excludeTaskDependencies: boolean;
|
23
|
+
skipSync: boolean;
|
23
24
|
}
|
24
25
|
export declare function withRunOptions<T>(yargs: Argv<T>): Argv<T & RunOptions>;
|
25
26
|
export declare function withTargetAndConfigurationOption(yargs: Argv, demandOption?: boolean): Argv<{
|