@node-core/utils 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/README.md +158 -0
- package/bin/get-metadata.js +11 -0
- package/bin/git-node.js +30 -0
- package/bin/ncu-ci.js +600 -0
- package/bin/ncu-config.js +101 -0
- package/bin/ncu-team.js +76 -0
- package/components/git/backport.js +70 -0
- package/components/git/epilogue.js +18 -0
- package/components/git/land.js +223 -0
- package/components/git/metadata.js +94 -0
- package/components/git/release.js +99 -0
- package/components/git/security.js +35 -0
- package/components/git/status.js +32 -0
- package/components/git/sync.js +24 -0
- package/components/git/v8.js +121 -0
- package/components/git/vote.js +84 -0
- package/components/git/wpt.js +87 -0
- package/components/metadata.js +49 -0
- package/lib/auth.js +133 -0
- package/lib/backport_session.js +302 -0
- package/lib/cache.js +107 -0
- package/lib/cherry_pick.js +304 -0
- package/lib/ci/build-types/benchmark_run.js +72 -0
- package/lib/ci/build-types/citgm_build.js +194 -0
- package/lib/ci/build-types/citgm_comparison_build.js +174 -0
- package/lib/ci/build-types/commit_build.js +112 -0
- package/lib/ci/build-types/daily_build.js +24 -0
- package/lib/ci/build-types/fanned_build.js +87 -0
- package/lib/ci/build-types/health_build.js +63 -0
- package/lib/ci/build-types/job.js +114 -0
- package/lib/ci/build-types/linter_build.js +35 -0
- package/lib/ci/build-types/normal_build.js +89 -0
- package/lib/ci/build-types/pr_build.js +101 -0
- package/lib/ci/build-types/test_build.js +186 -0
- package/lib/ci/build-types/test_run.js +41 -0
- package/lib/ci/ci_failure_parser.js +325 -0
- package/lib/ci/ci_type_parser.js +203 -0
- package/lib/ci/ci_utils.js +106 -0
- package/lib/ci/failure_aggregator.js +152 -0
- package/lib/ci/jenkins_constants.js +28 -0
- package/lib/ci/run_ci.js +120 -0
- package/lib/cli.js +192 -0
- package/lib/collaborators.js +140 -0
- package/lib/config.js +72 -0
- package/lib/figures.js +7 -0
- package/lib/file.js +43 -0
- package/lib/github/templates/next-security-release.md +97 -0
- package/lib/github/tree.js +162 -0
- package/lib/landing_session.js +506 -0
- package/lib/links.js +123 -0
- package/lib/mergeable_state.js +3 -0
- package/lib/metadata_gen.js +61 -0
- package/lib/pr_checker.js +605 -0
- package/lib/pr_data.js +115 -0
- package/lib/pr_summary.js +62 -0
- package/lib/prepare_release.js +772 -0
- package/lib/prepare_security.js +117 -0
- package/lib/proxy.js +21 -0
- package/lib/queries/DefaultBranchRef.gql +8 -0
- package/lib/queries/LastCommit.gql +16 -0
- package/lib/queries/PR.gql +37 -0
- package/lib/queries/PRComments.gql +27 -0
- package/lib/queries/PRCommits.gql +45 -0
- package/lib/queries/PRs.gql +25 -0
- package/lib/queries/Reviews.gql +23 -0
- package/lib/queries/SearchIssue.gql +51 -0
- package/lib/queries/Team.gql +22 -0
- package/lib/queries/TreeEntries.gql +12 -0
- package/lib/queries/VotePRInfo.gql +28 -0
- package/lib/release/utils.js +53 -0
- package/lib/request.js +185 -0
- package/lib/review_state.js +5 -0
- package/lib/reviews.js +178 -0
- package/lib/run.js +106 -0
- package/lib/session.js +415 -0
- package/lib/sync_session.js +15 -0
- package/lib/team_info.js +95 -0
- package/lib/update-v8/applyNodeChanges.js +49 -0
- package/lib/update-v8/backport.js +258 -0
- package/lib/update-v8/commitUpdate.js +26 -0
- package/lib/update-v8/common.js +35 -0
- package/lib/update-v8/constants.js +86 -0
- package/lib/update-v8/index.js +56 -0
- package/lib/update-v8/majorUpdate.js +171 -0
- package/lib/update-v8/minorUpdate.js +105 -0
- package/lib/update-v8/updateMaintainingDependencies.js +34 -0
- package/lib/update-v8/updateV8Clone.js +53 -0
- package/lib/update-v8/updateVersionNumbers.js +122 -0
- package/lib/update-v8/util.js +62 -0
- package/lib/user.js +4 -0
- package/lib/user_status.js +5 -0
- package/lib/utils.js +66 -0
- package/lib/verbosity.js +26 -0
- package/lib/voting_session.js +136 -0
- package/lib/wpt/index.js +243 -0
- package/lib/wpt/templates/README.md +16 -0
- package/package.json +69 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
|
|
4
|
+
import Enquirer from 'enquirer';
|
|
5
|
+
import { Listr } from 'listr2';
|
|
6
|
+
|
|
7
|
+
import { getCurrentV8Version } from './common.js';
|
|
8
|
+
import {
|
|
9
|
+
getNodeV8Version,
|
|
10
|
+
filterForVersion,
|
|
11
|
+
addToGitignore,
|
|
12
|
+
replaceGitignore,
|
|
13
|
+
removeDirectory,
|
|
14
|
+
isVersionString
|
|
15
|
+
} from './util.js';
|
|
16
|
+
import applyNodeChanges from './applyNodeChanges.js';
|
|
17
|
+
import { chromiumGit, v8Deps } from './constants.js';
|
|
18
|
+
import { runAsync } from '../run.js';
|
|
19
|
+
|
|
20
|
+
export default function majorUpdate() {
|
|
21
|
+
return {
|
|
22
|
+
title: 'Major V8 update',
|
|
23
|
+
task: () => {
|
|
24
|
+
return new Listr([
|
|
25
|
+
getCurrentV8Version(),
|
|
26
|
+
checkoutBranch(),
|
|
27
|
+
removeDepsV8(),
|
|
28
|
+
cloneLocalV8(),
|
|
29
|
+
removeDepsV8Git(),
|
|
30
|
+
addDepsV8(),
|
|
31
|
+
updateV8Deps(),
|
|
32
|
+
applyNodeChanges()
|
|
33
|
+
], {
|
|
34
|
+
injectWrapper: {
|
|
35
|
+
enquirer: new Enquirer()
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
function checkoutBranch() {
|
|
43
|
+
return {
|
|
44
|
+
title: 'Checkout V8 branch',
|
|
45
|
+
task: async(ctx) => {
|
|
46
|
+
let version = ctx.branch;
|
|
47
|
+
await ctx.execGitV8('checkout', 'origin/main');
|
|
48
|
+
if (!isVersionString(version)) {
|
|
49
|
+
// try to get the latest tag
|
|
50
|
+
const res = await ctx.execGitV8(
|
|
51
|
+
'tag',
|
|
52
|
+
'--contains',
|
|
53
|
+
`origin/${version}`,
|
|
54
|
+
'--sort',
|
|
55
|
+
'version:refname'
|
|
56
|
+
);
|
|
57
|
+
const tags = res.split('\n').filter(isVersionString);
|
|
58
|
+
const lastTag = tags[tags.length - 1];
|
|
59
|
+
if (lastTag) version = lastTag;
|
|
60
|
+
if (version.split('.').length === 3) {
|
|
61
|
+
// Prerelease versions are branched and 'lkgr' does not include
|
|
62
|
+
// the version commit
|
|
63
|
+
ctx.branch = version;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (version === ctx.currentVersion.toString()) {
|
|
67
|
+
throw new Error(`Current version is already ${version}`);
|
|
68
|
+
}
|
|
69
|
+
ctx.newVersion = version.split('.').map((s) => parseInt(s, 10));
|
|
70
|
+
try {
|
|
71
|
+
await ctx.execGitV8('branch', '-D', ctx.branch);
|
|
72
|
+
} catch (e) {
|
|
73
|
+
// ignore
|
|
74
|
+
}
|
|
75
|
+
await ctx.execGitV8('branch', ctx.branch, `origin/${ctx.branch}`);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function removeDepsV8() {
|
|
81
|
+
return {
|
|
82
|
+
title: 'Remove deps/v8',
|
|
83
|
+
task: (ctx) => removeDirectory(path.join(ctx.nodeDir, 'deps/v8'))
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function cloneLocalV8() {
|
|
88
|
+
return {
|
|
89
|
+
title: 'Clone branch to deps/v8',
|
|
90
|
+
task: (ctx) =>
|
|
91
|
+
runAsync('git', ['clone', '-b', ctx.branch, ctx.v8Dir, 'deps/v8'], {
|
|
92
|
+
spawnArgs: { cwd: ctx.nodeDir, stdio: 'ignore' }
|
|
93
|
+
})
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function removeDepsV8Git() {
|
|
98
|
+
return {
|
|
99
|
+
title: 'Remove deps/v8/.git',
|
|
100
|
+
task: (ctx) => removeDirectory(path.join(ctx.nodeDir, 'deps/v8/.git'))
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function addDepsV8() {
|
|
105
|
+
return {
|
|
106
|
+
title: 'Track all files in deps/v8',
|
|
107
|
+
// Add all V8 files with --force before updating DEPS. We have to do this
|
|
108
|
+
// because some files are checked in by V8 despite .gitignore rules.
|
|
109
|
+
task: (ctx) => runAsync('git', ['add', '--force', 'deps/v8'], {
|
|
110
|
+
spawnArgs: { cwd: ctx.nodeDir, stdio: 'ignore' }
|
|
111
|
+
})
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function updateV8Deps() {
|
|
116
|
+
return {
|
|
117
|
+
title: 'Update V8 DEPS',
|
|
118
|
+
task: async(ctx) => {
|
|
119
|
+
const newV8Version = await getNodeV8Version(ctx.nodeDir);
|
|
120
|
+
const repoPrefix = newV8Version.majorMinor >= 86 ? '' : 'v8/';
|
|
121
|
+
const deps = filterForVersion(v8Deps.map((v8Dep) => ({
|
|
122
|
+
...v8Dep,
|
|
123
|
+
repo: `${repoPrefix}${v8Dep.repo}`,
|
|
124
|
+
path: v8Dep.repo
|
|
125
|
+
})), newV8Version);
|
|
126
|
+
if (deps.length === 0) return;
|
|
127
|
+
/* eslint-disable no-await-in-loop */
|
|
128
|
+
for (const dep of deps) {
|
|
129
|
+
if (dep.gitignore) {
|
|
130
|
+
if (typeof dep.gitignore === 'string') {
|
|
131
|
+
await addToGitignore(ctx.nodeDir, dep.gitignore);
|
|
132
|
+
} else {
|
|
133
|
+
await replaceGitignore(ctx.nodeDir, dep.gitignore);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const [repo, commit] = await readDeps(ctx.nodeDir, dep.repo);
|
|
137
|
+
const thePath = path.join(ctx.nodeDir, 'deps/v8', dep.path);
|
|
138
|
+
await fetchFromGit(thePath, repo, commit);
|
|
139
|
+
}
|
|
140
|
+
/* eslint-enable */
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async function readDeps(nodeDir, depName) {
|
|
146
|
+
const depsStr = await fs.readFile(path.join(nodeDir, 'deps/v8/DEPS'), 'utf8');
|
|
147
|
+
const start = depsStr.indexOf('deps = {');
|
|
148
|
+
const end = depsStr.indexOf('\n}', start) + 2;
|
|
149
|
+
const depsDeclaration = depsStr.substring(start, end).replace(/^ *#.*/gm, '');
|
|
150
|
+
const Var = () => chromiumGit; // eslint-disable-line no-unused-vars
|
|
151
|
+
let deps;
|
|
152
|
+
eval(depsDeclaration); // eslint-disable-line no-eval
|
|
153
|
+
const dep = deps[depName];
|
|
154
|
+
if (typeof dep === 'object') {
|
|
155
|
+
return dep.url.split('@');
|
|
156
|
+
}
|
|
157
|
+
return dep.split('@');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async function fetchFromGit(cwd, repo, commit) {
|
|
161
|
+
await fs.mkdir(cwd, { recursive: true });
|
|
162
|
+
await exec('init');
|
|
163
|
+
await exec('remote', 'add', 'origin', repo);
|
|
164
|
+
await exec('fetch', 'origin', commit);
|
|
165
|
+
await exec('reset', '--hard', 'FETCH_HEAD');
|
|
166
|
+
await removeDirectory(path.join(cwd, '.git'));
|
|
167
|
+
|
|
168
|
+
function exec(...options) {
|
|
169
|
+
return runAsync('git', options, { spawnArgs: { cwd, stdio: 'ignore' } });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { promises as fs } from 'node:fs';
|
|
4
|
+
|
|
5
|
+
import Enquirer from 'enquirer';
|
|
6
|
+
import { Listr } from 'listr2';
|
|
7
|
+
|
|
8
|
+
import { getCurrentV8Version } from './common.js';
|
|
9
|
+
import { isVersionString } from './util.js';
|
|
10
|
+
import { runAsync } from '../run.js';
|
|
11
|
+
|
|
12
|
+
export default function minorUpdate() {
|
|
13
|
+
return {
|
|
14
|
+
title: 'Minor V8 update',
|
|
15
|
+
task: () => {
|
|
16
|
+
return new Listr([
|
|
17
|
+
getCurrentV8Version(),
|
|
18
|
+
getLatestV8Version(),
|
|
19
|
+
doMinorUpdate()
|
|
20
|
+
], {
|
|
21
|
+
injectWrapper: {
|
|
22
|
+
enquirer: new Enquirer()
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function getLatestV8Version() {
|
|
30
|
+
return {
|
|
31
|
+
title: 'Get latest V8 version',
|
|
32
|
+
task: async(ctx) => {
|
|
33
|
+
const version = ctx.currentVersion;
|
|
34
|
+
const currentV8Tag = `${version.major}.${version.minor}.${version.build}`;
|
|
35
|
+
const result = await runAsync('git', ['tag', '-l', `${currentV8Tag}.*`], {
|
|
36
|
+
captureStdout: true,
|
|
37
|
+
spawnArgs: {
|
|
38
|
+
cwd: ctx.v8Dir,
|
|
39
|
+
stdio: ['ignore', 'pipe', 'ignore']
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
const tags = filterAndSortTags(result);
|
|
43
|
+
ctx.latestVersion = tags[0];
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function doMinorUpdate() {
|
|
49
|
+
return {
|
|
50
|
+
title: 'Do minor update',
|
|
51
|
+
task: (ctx, task) => {
|
|
52
|
+
if (ctx.latestVersion.length === 3) {
|
|
53
|
+
throw new Error('minor update can only be done on release branches');
|
|
54
|
+
}
|
|
55
|
+
const latestStr = ctx.latestVersion.join('.');
|
|
56
|
+
task.title = `Do minor update to ${latestStr}`;
|
|
57
|
+
return applyPatch(ctx, latestStr);
|
|
58
|
+
},
|
|
59
|
+
skip: (ctx) => {
|
|
60
|
+
if (ctx.currentVersion.patch >= ctx.latestVersion[3]) {
|
|
61
|
+
ctx.skipped = 'V8 is up-to-date';
|
|
62
|
+
return ctx.skipped;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function applyPatch(ctx, latestStr) {
|
|
70
|
+
const diff = spawn(
|
|
71
|
+
'git',
|
|
72
|
+
['format-patch', '--stdout', `${ctx.currentVersion}...${latestStr}`],
|
|
73
|
+
{ cwd: ctx.v8Dir, stdio: ['ignore', 'pipe', 'ignore'] }
|
|
74
|
+
);
|
|
75
|
+
try {
|
|
76
|
+
await runAsync('git', ['apply', '--directory', 'deps/v8'], {
|
|
77
|
+
spawnArgs: {
|
|
78
|
+
cwd: ctx.nodeDir,
|
|
79
|
+
stdio: [diff.stdout, 'ignore', 'ignore']
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
} catch (e) {
|
|
83
|
+
const file = path.join(ctx.nodeDir, `${latestStr}.diff`);
|
|
84
|
+
await fs.writeFile(file, diff);
|
|
85
|
+
throw new Error(`Could not apply patch.\n${e}\nDiff was stored in ${file}`);
|
|
86
|
+
}
|
|
87
|
+
if (diff.exitCode !== 0) {
|
|
88
|
+
const err = new Error(`git format-patch failed: ${diff.exitCode}`);
|
|
89
|
+
err.code = diff.exitCode;
|
|
90
|
+
err.messageOnly = true;
|
|
91
|
+
throw err;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function filterAndSortTags(tags) {
|
|
96
|
+
return tags
|
|
97
|
+
.split(/[\r\n]+/)
|
|
98
|
+
.filter(isVersionString)
|
|
99
|
+
.map((tag) => tag.split('.'))
|
|
100
|
+
.sort(sortVersions);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function sortVersions(v1, v2) {
|
|
104
|
+
return v2[3] - v1[3];
|
|
105
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import { getNodeV8Version } from './util.js';
|
|
3
|
+
|
|
4
|
+
export default function updateMaintainingDependencies() {
|
|
5
|
+
return {
|
|
6
|
+
title: 'Update V8 version in maintaining-dependencies.md',
|
|
7
|
+
task: async(ctx) => {
|
|
8
|
+
const path = `${ctx.nodeDir}/doc/contributing/maintaining/maintaining-dependencies.md`;
|
|
9
|
+
let maintainingDependenciesMd = await fs.readFile(path, 'utf8');
|
|
10
|
+
const v8Version = (await getNodeV8Version(ctx.nodeDir)).toString();
|
|
11
|
+
const v8VersionNoDots = v8Version.replaceAll('.', '');
|
|
12
|
+
// V8 itemlist link
|
|
13
|
+
maintainingDependenciesMd = maintainingDependenciesMd.replace(
|
|
14
|
+
/\* \[V8.*/,
|
|
15
|
+
`* [V8 ${v8Version}][]`
|
|
16
|
+
);
|
|
17
|
+
// V8 link to section
|
|
18
|
+
maintainingDependenciesMd = maintainingDependenciesMd.replace(
|
|
19
|
+
/\[v8.*\]: #v8.*/,
|
|
20
|
+
`[v8 ${v8Version}]: #v8-${v8VersionNoDots}`
|
|
21
|
+
);
|
|
22
|
+
// V8 section title
|
|
23
|
+
maintainingDependenciesMd = maintainingDependenciesMd.replace(
|
|
24
|
+
/### V8.*/,
|
|
25
|
+
`### V8 ${v8Version}`
|
|
26
|
+
);
|
|
27
|
+
await fs.writeFile(path, maintainingDependenciesMd);
|
|
28
|
+
await ctx.execGitNode(
|
|
29
|
+
'add',
|
|
30
|
+
['doc/contributing/maintaining/maintaining-dependencies.md']
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
|
|
3
|
+
import Enquirer from 'enquirer';
|
|
4
|
+
import { Listr } from 'listr2';
|
|
5
|
+
|
|
6
|
+
import { v8Git } from './constants.js';
|
|
7
|
+
import { runAsync } from '../run.js';
|
|
8
|
+
|
|
9
|
+
export default function updateV8Clone() {
|
|
10
|
+
return {
|
|
11
|
+
title: 'Update local V8 clone',
|
|
12
|
+
task: () => {
|
|
13
|
+
return new Listr([fetchOrigin(), createClone()], {
|
|
14
|
+
injectWrapper: {
|
|
15
|
+
enquirer: new Enquirer()
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function fetchOrigin() {
|
|
23
|
+
return {
|
|
24
|
+
title: 'Fetch V8',
|
|
25
|
+
task: async(ctx, task) => {
|
|
26
|
+
try {
|
|
27
|
+
await runAsync('git', ['fetch', 'origin'], {
|
|
28
|
+
spawnArgs: { cwd: ctx.v8Dir, stdio: 'ignore' }
|
|
29
|
+
});
|
|
30
|
+
} catch (e) {
|
|
31
|
+
if (e.code === 'ENOENT') {
|
|
32
|
+
ctx.shouldClone = true;
|
|
33
|
+
task.skip('V8 clone not present, create it.');
|
|
34
|
+
} else {
|
|
35
|
+
throw e;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function createClone() {
|
|
43
|
+
return {
|
|
44
|
+
title: 'Clone V8',
|
|
45
|
+
task: async(ctx) => {
|
|
46
|
+
await fs.mkdir(ctx.baseDir, { recursive: true });
|
|
47
|
+
await runAsync('git', ['clone', v8Git], {
|
|
48
|
+
spawnArgs: { cwd: ctx.baseDir, stdio: 'ignore' }
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
enabled: (ctx) => ctx.shouldClone
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
|
|
4
|
+
import Enquirer from 'enquirer';
|
|
5
|
+
import { Listr } from 'listr2';
|
|
6
|
+
|
|
7
|
+
import { getNodeV8Version } from './util.js';
|
|
8
|
+
|
|
9
|
+
export default function updateVersionNumbers() {
|
|
10
|
+
return {
|
|
11
|
+
title: 'Update version numbers',
|
|
12
|
+
task: () => {
|
|
13
|
+
return new Listr([resetEmbedderString(), bumpNodeModule()], {
|
|
14
|
+
injectWrapper: {
|
|
15
|
+
enquirer: new Enquirer()
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function bumpNodeModule() {
|
|
23
|
+
return {
|
|
24
|
+
title: 'Bump NODE_MODULE_VERSION',
|
|
25
|
+
task: async(ctx) => {
|
|
26
|
+
const v8Version = await getNodeV8Version(ctx.nodeDir);
|
|
27
|
+
const newModuleVersion = await updateModuleVersionRegistry(
|
|
28
|
+
ctx.nodeDir,
|
|
29
|
+
v8Version,
|
|
30
|
+
ctx.nodeMajorVersion
|
|
31
|
+
);
|
|
32
|
+
await updateModuleVersion(ctx.nodeDir, newModuleVersion);
|
|
33
|
+
await ctx.execGitNode(
|
|
34
|
+
'add',
|
|
35
|
+
['doc/abi_version_registry.json', 'src/node_version.h']
|
|
36
|
+
);
|
|
37
|
+
await ctx.execGitNode(
|
|
38
|
+
'commit',
|
|
39
|
+
[
|
|
40
|
+
'-m',
|
|
41
|
+
getCommitTitle(newModuleVersion),
|
|
42
|
+
'-m',
|
|
43
|
+
getCommitBody(v8Version)
|
|
44
|
+
]
|
|
45
|
+
);
|
|
46
|
+
},
|
|
47
|
+
skip: (ctx) => !ctx.versionBump
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function updateModuleVersionRegistry(
|
|
52
|
+
nodeDir,
|
|
53
|
+
v8Version,
|
|
54
|
+
nodeMajorVersion
|
|
55
|
+
) {
|
|
56
|
+
const registryFile = `${nodeDir}/doc/abi_version_registry.json`;
|
|
57
|
+
const registryStr = await fs.readFile(registryFile, 'utf8');
|
|
58
|
+
const registry = JSON.parse(registryStr);
|
|
59
|
+
const newVersion = registry.NODE_MODULE_VERSION[0].modules + 1;
|
|
60
|
+
const newLine =
|
|
61
|
+
`{ "modules": ${newVersion}, "runtime": "node", ` +
|
|
62
|
+
`"variant": "v8_${v8Version.major}.${v8Version.minor}", ` +
|
|
63
|
+
`"versions": "${nodeMajorVersion}.0.0-pre" },\n `;
|
|
64
|
+
const firstLineIndex = registryStr.indexOf('{ "modules"');
|
|
65
|
+
const newRegistry =
|
|
66
|
+
registryStr.substring(0, firstLineIndex) +
|
|
67
|
+
newLine +
|
|
68
|
+
registryStr.substring(firstLineIndex);
|
|
69
|
+
await fs.writeFile(registryFile, newRegistry);
|
|
70
|
+
return newVersion;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function updateModuleVersion(nodeDir, newVersion) {
|
|
74
|
+
const path = `${nodeDir}/src/node_version.h`;
|
|
75
|
+
let nodeVersionH = await fs.readFile(path, 'utf8');
|
|
76
|
+
nodeVersionH = nodeVersionH.replace(
|
|
77
|
+
/NODE_MODULE_VERSION \d+/,
|
|
78
|
+
`NODE_MODULE_VERSION ${newVersion}`
|
|
79
|
+
);
|
|
80
|
+
await fs.writeFile(path, nodeVersionH);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getCommitTitle(moduleVersion) {
|
|
84
|
+
return `src: update NODE_MODULE_VERSION to ${moduleVersion}`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function getCommitBody(v8Version) {
|
|
88
|
+
return `Major V8 updates are usually API/ABI incompatible with previous
|
|
89
|
+
versions. This commit adapts NODE_MODULE_VERSION for V8 ${v8Version.major}.${
|
|
90
|
+
v8Version.minor
|
|
91
|
+
}.
|
|
92
|
+
|
|
93
|
+
Refs: https://github.com/nodejs/CTC/blob/master/meetings/2016-09-28.md`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const embedderRegex = /'v8_embedder_string': '-node\.(\d+)'/;
|
|
97
|
+
const embedderString = "'v8_embedder_string': '-node.0'";
|
|
98
|
+
function resetEmbedderString() {
|
|
99
|
+
return {
|
|
100
|
+
title: 'Reset V8 embedder version string',
|
|
101
|
+
task: async(ctx, task) => {
|
|
102
|
+
const commonGypiPath = path.join(ctx.nodeDir, 'common.gypi');
|
|
103
|
+
const commonGypi = await fs.readFile(commonGypiPath, 'utf8');
|
|
104
|
+
const embedderValue = embedderRegex.exec(commonGypi)[1];
|
|
105
|
+
if (embedderValue !== '0') {
|
|
106
|
+
await fs.writeFile(
|
|
107
|
+
commonGypiPath,
|
|
108
|
+
commonGypi.replace(embedderRegex, embedderString)
|
|
109
|
+
);
|
|
110
|
+
await ctx.execGitNode('add', ['common.gypi']);
|
|
111
|
+
await ctx.execGitNode(
|
|
112
|
+
'commit',
|
|
113
|
+
['-m', 'build: reset embedder string to "-node.0"']
|
|
114
|
+
);
|
|
115
|
+
} else {
|
|
116
|
+
return task.skip('Embedder version is already 0');
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
},
|
|
120
|
+
skip: (ctx) => ctx.nodeMajorVersion < 9
|
|
121
|
+
};
|
|
122
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
export async function getNodeV8Version(cwd) {
|
|
5
|
+
try {
|
|
6
|
+
const v8VersionH = await fs.readFile(
|
|
7
|
+
`${cwd}/deps/v8/include/v8-version.h`,
|
|
8
|
+
'utf8'
|
|
9
|
+
);
|
|
10
|
+
const major = parseInt(/V8_MAJOR_VERSION (\d+)/.exec(v8VersionH)[1], 10);
|
|
11
|
+
const minor = parseInt(/V8_MINOR_VERSION (\d+)/.exec(v8VersionH)[1], 10);
|
|
12
|
+
const build = parseInt(/V8_BUILD_NUMBER (\d+)/.exec(v8VersionH)[1], 10);
|
|
13
|
+
const patch = parseInt(/V8_PATCH_LEVEL (\d+)/.exec(v8VersionH)[1], 10);
|
|
14
|
+
return {
|
|
15
|
+
major,
|
|
16
|
+
minor,
|
|
17
|
+
build,
|
|
18
|
+
patch,
|
|
19
|
+
majorMinor: major * 10 + minor,
|
|
20
|
+
toString() {
|
|
21
|
+
return this.patch
|
|
22
|
+
? `${this.major}.${this.minor}.${this.build}.${this.patch}`
|
|
23
|
+
: `${this.major}.${this.minor}.${this.build}`;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
} catch (e) {
|
|
27
|
+
throw new Error('Could not find V8 version');
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export function filterForVersion(list, version) {
|
|
32
|
+
return list.filter((dep) => {
|
|
33
|
+
return dep.since <= version.majorMinor &&
|
|
34
|
+
(dep.until || Infinity) >= version.majorMinor;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function addToGitignore(nodeDir, value) {
|
|
39
|
+
const gitignorePath = path.join(nodeDir, 'deps/v8/.gitignore');
|
|
40
|
+
await fs.appendFile(gitignorePath, `${value}\n`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function replaceGitignore(nodeDir, options) {
|
|
44
|
+
const gitignorePath = path.join(nodeDir, 'deps/v8/.gitignore');
|
|
45
|
+
let gitignore = await fs.readFile(gitignorePath, 'utf8');
|
|
46
|
+
gitignore = gitignore.replace(options.match, options.replace);
|
|
47
|
+
await fs.writeFile(gitignorePath, gitignore);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function removeDirectory(path) {
|
|
51
|
+
if (typeof fs.rm !== 'undefined') {
|
|
52
|
+
return fs.rm(path, { recursive: true, force: true });
|
|
53
|
+
} else {
|
|
54
|
+
// Node.js 12 doesn't have `rm`, and `rmdir` emits a deprecation warning in
|
|
55
|
+
// Node.js 16+.
|
|
56
|
+
return fs.rmdir(path, { recursive: true });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function isVersionString(str) {
|
|
61
|
+
return /^\d+(\.\d+)+$/.test(str);
|
|
62
|
+
}
|
package/lib/user.js
ADDED
package/lib/utils.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import which from 'which';
|
|
2
|
+
|
|
3
|
+
import { forceRunAsync } from './run.js';
|
|
4
|
+
|
|
5
|
+
export function ascending(a, b) {
|
|
6
|
+
if (a === b) return 0;
|
|
7
|
+
return a < b ? -1 : 1;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export function descending(a, b) {
|
|
11
|
+
if (a === b) return 0;
|
|
12
|
+
return a > b ? -1 : 1;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function flatten(arr) {
|
|
16
|
+
let result = [];
|
|
17
|
+
for (const item of arr) {
|
|
18
|
+
if (Array.isArray(item)) {
|
|
19
|
+
result = result.concat(flatten(item));
|
|
20
|
+
} else {
|
|
21
|
+
result.push(item);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function shortSha(sha) {
|
|
28
|
+
return sha.slice(0, 12);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
let isGhAvailableCache;
|
|
32
|
+
export function isGhAvailable() {
|
|
33
|
+
if (isGhAvailableCache === undefined) {
|
|
34
|
+
isGhAvailableCache = which.sync('gh', { nothrow: true }) !== null;
|
|
35
|
+
}
|
|
36
|
+
return isGhAvailableCache;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Returns the user's preferred text editor command.
|
|
41
|
+
* @param {object} [options]
|
|
42
|
+
* @param {boolean} [options.git] - Whether to try the GIT_EDITOR environment
|
|
43
|
+
* variable or `git config`.
|
|
44
|
+
* @returns {Promise<string|null>}
|
|
45
|
+
*/
|
|
46
|
+
export async function getEditor(options = {}) {
|
|
47
|
+
const {
|
|
48
|
+
git = false
|
|
49
|
+
} = options;
|
|
50
|
+
|
|
51
|
+
if (git) {
|
|
52
|
+
if (process.env.GIT_EDITOR) {
|
|
53
|
+
return process.env.GIT_EDITOR;
|
|
54
|
+
}
|
|
55
|
+
const out = await forceRunAsync(
|
|
56
|
+
'git',
|
|
57
|
+
['config', 'core.editor'],
|
|
58
|
+
{ captureStdout: 'lines' }
|
|
59
|
+
);
|
|
60
|
+
if (out && out[0]) {
|
|
61
|
+
return out[0];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return process.env.VISUAL || process.env.EDITOR || null;
|
|
66
|
+
};
|
package/lib/verbosity.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import util from 'node:util';
|
|
2
|
+
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
|
|
5
|
+
const VERBOSITY = {
|
|
6
|
+
NONE: 0,
|
|
7
|
+
DEBUG: 2
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export let verbosity = VERBOSITY.NONE;
|
|
11
|
+
|
|
12
|
+
export function isDebugVerbosity() {
|
|
13
|
+
return verbosity === VERBOSITY.DEBUG;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function setVerbosityFromEnv() {
|
|
17
|
+
const env = (process.env.NCU_VERBOSITY || '').toUpperCase();
|
|
18
|
+
if (Object.keys(VERBOSITY).includes(env)) {
|
|
19
|
+
verbosity = VERBOSITY[env];
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export function debuglog(...args) {
|
|
24
|
+
// Prepend a line break in case it's logged while the spinner is running
|
|
25
|
+
console.error(chalk.green(util.format('\n[DEBUG]', ...args)));
|
|
26
|
+
};
|