@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.
Files changed (98) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +158 -0
  3. package/bin/get-metadata.js +11 -0
  4. package/bin/git-node.js +30 -0
  5. package/bin/ncu-ci.js +600 -0
  6. package/bin/ncu-config.js +101 -0
  7. package/bin/ncu-team.js +76 -0
  8. package/components/git/backport.js +70 -0
  9. package/components/git/epilogue.js +18 -0
  10. package/components/git/land.js +223 -0
  11. package/components/git/metadata.js +94 -0
  12. package/components/git/release.js +99 -0
  13. package/components/git/security.js +35 -0
  14. package/components/git/status.js +32 -0
  15. package/components/git/sync.js +24 -0
  16. package/components/git/v8.js +121 -0
  17. package/components/git/vote.js +84 -0
  18. package/components/git/wpt.js +87 -0
  19. package/components/metadata.js +49 -0
  20. package/lib/auth.js +133 -0
  21. package/lib/backport_session.js +302 -0
  22. package/lib/cache.js +107 -0
  23. package/lib/cherry_pick.js +304 -0
  24. package/lib/ci/build-types/benchmark_run.js +72 -0
  25. package/lib/ci/build-types/citgm_build.js +194 -0
  26. package/lib/ci/build-types/citgm_comparison_build.js +174 -0
  27. package/lib/ci/build-types/commit_build.js +112 -0
  28. package/lib/ci/build-types/daily_build.js +24 -0
  29. package/lib/ci/build-types/fanned_build.js +87 -0
  30. package/lib/ci/build-types/health_build.js +63 -0
  31. package/lib/ci/build-types/job.js +114 -0
  32. package/lib/ci/build-types/linter_build.js +35 -0
  33. package/lib/ci/build-types/normal_build.js +89 -0
  34. package/lib/ci/build-types/pr_build.js +101 -0
  35. package/lib/ci/build-types/test_build.js +186 -0
  36. package/lib/ci/build-types/test_run.js +41 -0
  37. package/lib/ci/ci_failure_parser.js +325 -0
  38. package/lib/ci/ci_type_parser.js +203 -0
  39. package/lib/ci/ci_utils.js +106 -0
  40. package/lib/ci/failure_aggregator.js +152 -0
  41. package/lib/ci/jenkins_constants.js +28 -0
  42. package/lib/ci/run_ci.js +120 -0
  43. package/lib/cli.js +192 -0
  44. package/lib/collaborators.js +140 -0
  45. package/lib/config.js +72 -0
  46. package/lib/figures.js +7 -0
  47. package/lib/file.js +43 -0
  48. package/lib/github/templates/next-security-release.md +97 -0
  49. package/lib/github/tree.js +162 -0
  50. package/lib/landing_session.js +506 -0
  51. package/lib/links.js +123 -0
  52. package/lib/mergeable_state.js +3 -0
  53. package/lib/metadata_gen.js +61 -0
  54. package/lib/pr_checker.js +605 -0
  55. package/lib/pr_data.js +115 -0
  56. package/lib/pr_summary.js +62 -0
  57. package/lib/prepare_release.js +772 -0
  58. package/lib/prepare_security.js +117 -0
  59. package/lib/proxy.js +21 -0
  60. package/lib/queries/DefaultBranchRef.gql +8 -0
  61. package/lib/queries/LastCommit.gql +16 -0
  62. package/lib/queries/PR.gql +37 -0
  63. package/lib/queries/PRComments.gql +27 -0
  64. package/lib/queries/PRCommits.gql +45 -0
  65. package/lib/queries/PRs.gql +25 -0
  66. package/lib/queries/Reviews.gql +23 -0
  67. package/lib/queries/SearchIssue.gql +51 -0
  68. package/lib/queries/Team.gql +22 -0
  69. package/lib/queries/TreeEntries.gql +12 -0
  70. package/lib/queries/VotePRInfo.gql +28 -0
  71. package/lib/release/utils.js +53 -0
  72. package/lib/request.js +185 -0
  73. package/lib/review_state.js +5 -0
  74. package/lib/reviews.js +178 -0
  75. package/lib/run.js +106 -0
  76. package/lib/session.js +415 -0
  77. package/lib/sync_session.js +15 -0
  78. package/lib/team_info.js +95 -0
  79. package/lib/update-v8/applyNodeChanges.js +49 -0
  80. package/lib/update-v8/backport.js +258 -0
  81. package/lib/update-v8/commitUpdate.js +26 -0
  82. package/lib/update-v8/common.js +35 -0
  83. package/lib/update-v8/constants.js +86 -0
  84. package/lib/update-v8/index.js +56 -0
  85. package/lib/update-v8/majorUpdate.js +171 -0
  86. package/lib/update-v8/minorUpdate.js +105 -0
  87. package/lib/update-v8/updateMaintainingDependencies.js +34 -0
  88. package/lib/update-v8/updateV8Clone.js +53 -0
  89. package/lib/update-v8/updateVersionNumbers.js +122 -0
  90. package/lib/update-v8/util.js +62 -0
  91. package/lib/user.js +4 -0
  92. package/lib/user_status.js +5 -0
  93. package/lib/utils.js +66 -0
  94. package/lib/verbosity.js +26 -0
  95. package/lib/voting_session.js +136 -0
  96. package/lib/wpt/index.js +243 -0
  97. package/lib/wpt/templates/README.md +16 -0
  98. 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
@@ -0,0 +1,4 @@
1
+ export function isTheSamePerson(actor, b) {
2
+ if (!actor || !actor.login) return false; // ghost
3
+ return actor.login.toLowerCase() === b.toLowerCase();
4
+ }
@@ -0,0 +1,5 @@
1
+ export const FIRST_TIME_CONTRIBUTOR = 'FIRST_TIME_CONTRIBUTOR';
2
+ export const NONE = 'NONE';
3
+ export const OWNER = 'OWNER'; // TSC
4
+ export const FIRST_TIMER = 'FIRST_TIMER'; // New to Github
5
+ export const COLLABORATOR = 'COLLABORATOR';
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
+ };
@@ -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
+ };