@flun/nodejs-mobile-gyp 1.2.1 → 1.2.3
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/CHANGELOG.md +9 -27
- package/bin/node-gyp.js +5 -9
- package/lib/build.js +135 -131
- package/lib/clean.js +12 -9
- package/lib/configure.js +10 -6
- package/lib/create-config-gypi.js +103 -92
- package/lib/download.js +32 -24
- package/lib/find-node-directory.js +39 -37
- package/lib/find-python.js +17 -37
- package/lib/find-visualstudio.js +10 -18
- package/lib/install.js +270 -267
- package/lib/list.js +21 -18
- package/lib/log.js +11 -3
- package/lib/node-gyp.js +12 -7
- package/lib/process-release.js +77 -76
- package/lib/rebuild.js +2 -1
- package/lib/remove.js +9 -5
- package/lib/util.js +82 -62
- package/package.json +76 -73
package/lib/log.js
CHANGED
|
@@ -105,6 +105,14 @@ class Logger {
|
|
|
105
105
|
// 用于测试时抑制日志
|
|
106
106
|
const NULL_LOGGER = !!process.env.NODE_GYP_NULL_LOGGER, logger = new Logger(NULL_LOGGER ? null : process.stderr),
|
|
107
107
|
stdout = NULL_LOGGER ? () => { } : (...args) => console.log(...args),
|
|
108
|
-
{
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
{ error, http, info, notice, pause, resume, silly, verbose, warn } = procLog.log; // 解构 proc-log 的函数,供末尾统一导出
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 日志模块:提供分级日志、带前缀 logger 与标准输出
|
|
112
|
+
* >查看定义:
|
|
113
|
+
* - 模块参数(proc-log 重导出):{@link error}、{@link http}、{@link info}、{@link notice}、{@link pause}、
|
|
114
|
+
* {@link resume}、{@link silly}、{@link verbose}、{@link warn}
|
|
115
|
+
* - 声明变量:{@link logger}
|
|
116
|
+
* - 声明函数:{@link stdout}、{@link withPrefix}
|
|
117
|
+
*/
|
|
118
|
+
export { error, http, info, notice, pause, resume, silly, verbose, warn, logger, stdout, withPrefix };
|
package/lib/node-gyp.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import nopt from 'nopt';
|
|
3
1
|
import chalk from 'chalk';
|
|
4
|
-
import * as log from './log.js';
|
|
5
2
|
import childProcess from 'child_process';
|
|
6
3
|
import { EventEmitter } from 'events';
|
|
7
4
|
import { readFileSync } from 'fs';
|
|
5
|
+
import nopt from 'nopt';
|
|
6
|
+
import path from 'path';
|
|
8
7
|
import { fileURLToPath } from 'url';
|
|
9
|
-
|
|
10
8
|
import { build } from './build.js';
|
|
11
9
|
import { clean } from './clean.js';
|
|
12
10
|
import { configure } from './configure.js';
|
|
13
|
-
import { rebuild } from './rebuild.js';
|
|
14
11
|
import { install } from './install.js';
|
|
15
12
|
import { list } from './list.js';
|
|
13
|
+
import * as log from './log.js';
|
|
14
|
+
import { rebuild } from './rebuild.js';
|
|
16
15
|
import { remove } from './remove.js';
|
|
17
16
|
|
|
18
17
|
const __dirname = path.dirname(fileURLToPath(import.meta.url)),
|
|
@@ -20,6 +19,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)),
|
|
|
20
19
|
commandModules = { build, clean, configure, rebuild, install, list, remove }, commands = Object.keys(commandModules);
|
|
21
20
|
|
|
22
21
|
/**
|
|
22
|
+
* >查看定义:@see {@link Gyp}
|
|
23
23
|
* node-gyp 主类:解析参数、分发命令、生成 usage
|
|
24
24
|
*/
|
|
25
25
|
class Gyp extends EventEmitter {
|
|
@@ -177,6 +177,11 @@ class Gyp extends EventEmitter {
|
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
/**
|
|
181
|
+
* 创建 Gyp 实例的工厂函数
|
|
182
|
+
* >查看定义:@see {@link createGyp}
|
|
183
|
+
* @returns {Gyp} 新建的 Gyp 实例
|
|
184
|
+
*/
|
|
180
185
|
const createGyp = () => new Gyp();
|
|
181
|
-
|
|
182
|
-
export { Gyp }
|
|
186
|
+
|
|
187
|
+
export { createGyp, createGyp as default, Gyp };
|
package/lib/process-release.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/* eslint-disable n/no-deprecated-api */
|
|
2
|
-
|
|
3
|
-
import semver from 'semver';
|
|
4
2
|
import path from 'path';
|
|
3
|
+
import semver from 'semver';
|
|
5
4
|
import * as log from './log.js';
|
|
6
5
|
|
|
7
6
|
// 开始发布 -headers.tar.gz 的版本(io.js v3.x.x 里用的是 "ia32",本应是 "x86")
|
|
8
|
-
const headersTarballRange = '>= 3.0.0 || ~0.12.10 || ~0.10.42', bitsre = /\/win-(x86|x64|arm64)
|
|
9
|
-
|
|
7
|
+
const headersTarballRange = '>= 3.0.0 || ~0.12.10 || ~0.10.42', bitsre = /\/win-(x86|x64|arm64)\//;
|
|
8
|
+
bitsreV3 = /\/win-(x86|ia32|x64)\//, normalizePath = (p) => path.normalize(p).replace(/\\/g, '/'), // 统一分隔符为 /
|
|
10
9
|
/**
|
|
11
10
|
* 根据名称、基础 URL、架构、主版本号解析 lib 下载地址
|
|
12
11
|
*/
|
|
@@ -23,83 +22,85 @@ const headersTarballRange = '>= 3.0.0 || ~0.12.10 || ~0.10.42', bitsre = /\/win-
|
|
|
23
22
|
}
|
|
24
23
|
// 否则传入的已经是 .lib 地址,只需保证架构正确
|
|
25
24
|
return defaultUrl.replace(versionMajor === 3 ? bitsreV3 : bitsre, '/win-' + arch + '/');
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* 负责确定下载 URL、本地目录和文件名;
|
|
29
|
-
* 输入来自命令行开关(--target、--dist-url)、process.version 和 process.release;
|
|
30
|
-
*/
|
|
31
|
-
processRelease = (argv, gyp, defaultVersion, defaultRelease) => {
|
|
32
|
-
let version = (semver.valid(argv[0]) && argv[0]) || gyp.opts.target || defaultVersion
|
|
33
|
-
const versionSemver = semver.parse(version)
|
|
34
|
-
let overrideDistUrl = gyp.opts['dist-url'] || gyp.opts.disturl, isNamedForLegacyIojs, name, distBaseUrl,
|
|
35
|
-
baseUrl, libUrl32, libUrl64, libUrlArm64, tarballUrl, canGetHeaders;
|
|
25
|
+
}
|
|
36
26
|
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
/**
|
|
28
|
+
* 计算当前 Node.js 发行版的下载信息与路径
|
|
29
|
+
* >查看定义:@see {@link processRelease}
|
|
30
|
+
* @param {*} argv
|
|
31
|
+
* @param {*} gyp
|
|
32
|
+
* @param {*} defaultVersion
|
|
33
|
+
* @param {*} defaultRelease
|
|
34
|
+
* @returns {*}
|
|
35
|
+
*/
|
|
36
|
+
const processRelease = (argv, gyp, defaultVersion, defaultRelease) => {
|
|
37
|
+
let version = (semver.valid(argv[0]) && argv[0]) || gyp.opts.target || defaultVersion
|
|
38
|
+
const versionSemver = semver.parse(version)
|
|
39
|
+
let overrideDistUrl = gyp.opts['dist-url'] || gyp.opts.disturl, isNamedForLegacyIojs, name, distBaseUrl,
|
|
40
|
+
baseUrl, libUrl32, libUrl64, libUrlArm64, tarballUrl, canGetHeaders;
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (!isDefaultVersion) defaultRelease = null; // 用了 --target=x.y.z 就不能用 process.release
|
|
43
|
-
if (defaultRelease) name = defaultRelease.name.replace(/io\.js/, 'iojs'); // 去掉 '.' 以便目录命名
|
|
44
|
-
else {
|
|
45
|
-
// 老版本 Node 或自定义 --target
|
|
46
|
-
// semver.satisfies() 不支持预发布标签,因此直接判断主版本
|
|
47
|
-
isNamedForLegacyIojs = versionSemver.major >= 1 && versionSemver.major < 4;
|
|
48
|
-
// isNamedForLegacyIojs 是为了支持 Electron < 4(特别是 Electron 3)
|
|
49
|
-
// 早期逻辑用它保证 iojs 版本下载 "iojs",Node 版本下载 "node";
|
|
50
|
-
// 但该逻辑过宽,导致 electron@3 的发布物命名为 "iojs" 才能让 node-gyp 正常工作;
|
|
51
|
-
// Electron@3 EOL 之后(2019 年底)应移除这个 hack;
|
|
52
|
-
name = isNamedForLegacyIojs ? 'iojs' : 'node';
|
|
53
|
-
}
|
|
42
|
+
if (!versionSemver) return { version }; // 如果 semver 不合法,那么原样返回 version
|
|
43
|
+
version = versionSemver.version; // 把 version 拍平为字符串
|
|
54
44
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
45
|
+
// defaultVersion 来自 process.version,应当是合法 semver
|
|
46
|
+
const isDefaultVersion = version === semver.parse(defaultVersion).version;
|
|
47
|
+
if (!isDefaultVersion) defaultRelease = null; // 用了 --target=x.y.z 就不能用 process.release
|
|
48
|
+
if (defaultRelease) name = defaultRelease.name.replace(/io\.js/, 'iojs'); // 去掉 '.' 以便目录命名
|
|
49
|
+
else {
|
|
50
|
+
// 老版本 Node 或自定义 --target
|
|
51
|
+
// semver.satisfies() 不支持预发布标签,因此直接判断主版本
|
|
52
|
+
isNamedForLegacyIojs = versionSemver.major >= 1 && versionSemver.major < 4;
|
|
53
|
+
// isNamedForLegacyIojs 是为了支持 Electron < 4(特别是 Electron 3)
|
|
54
|
+
// 早期逻辑用它保证 iojs 版本下载 "iojs",Node 版本下载 "node";
|
|
55
|
+
// 但该逻辑过宽,导致 electron@3 的发布物命名为 "iojs" 才能让 node-gyp 正常工作;
|
|
56
|
+
// Electron@3 EOL 之后(2019 年底)应移除这个 hack;
|
|
57
|
+
name = isNamedForLegacyIojs ? 'iojs' : 'node';
|
|
58
|
+
}
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
tarballUrl = defaultRelease.headersUrl;
|
|
69
|
-
} else {
|
|
70
|
-
// 没有 process.release 的老版本,需要做很多假设;
|
|
71
|
-
// 另外 --target=x.y.z 时也无法使用当前 process.release
|
|
72
|
-
baseUrl = distBaseUrl;
|
|
73
|
-
libUrl32 = resolveLibUrl(name, baseUrl, 'x86', versionSemver.major);
|
|
74
|
-
libUrl64 = resolveLibUrl(name, baseUrl, 'x64', versionSemver.major);
|
|
75
|
-
libUrlArm64 = resolveLibUrl(name, baseUrl, 'arm64', versionSemver.major);
|
|
60
|
+
// 检查 nvm.sh 标准镜像环境变量
|
|
61
|
+
if (!overrideDistUrl && process.env.NODEJS_ORG_MIRROR) overrideDistUrl = process.env.NODEJS_ORG_MIRROR;
|
|
62
|
+
if (overrideDistUrl) log.verbose('下载', '使用 dist-url', overrideDistUrl);
|
|
63
|
+
if (overrideDistUrl) distBaseUrl = overrideDistUrl.replace(/\/+$/, '');
|
|
64
|
+
else distBaseUrl = 'https://nodejs.org/dist';
|
|
65
|
+
distBaseUrl += '/v' + version + '/'
|
|
76
66
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
67
|
+
// 新式:基于 process.release,大部分数据已有
|
|
68
|
+
if (defaultRelease?.headersUrl && !overrideDistUrl) {
|
|
69
|
+
baseUrl = new URL('./', defaultRelease.headersUrl).href;
|
|
70
|
+
libUrl32 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x86', versionSemver.major);
|
|
71
|
+
libUrl64 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x64', versionSemver.major);
|
|
72
|
+
libUrlArm64 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'arm64', versionSemver.major);
|
|
73
|
+
tarballUrl = defaultRelease.headersUrl;
|
|
74
|
+
} else {
|
|
75
|
+
// 没有 process.release 的老版本,需要做很多假设;
|
|
76
|
+
// 另外 --target=x.y.z 时也无法使用当前 process.release
|
|
77
|
+
baseUrl = distBaseUrl;
|
|
78
|
+
libUrl32 = resolveLibUrl(name, baseUrl, 'x86', versionSemver.major);
|
|
79
|
+
libUrl64 = resolveLibUrl(name, baseUrl, 'x64', versionSemver.major);
|
|
80
|
+
libUrlArm64 = resolveLibUrl(name, baseUrl, 'arm64', versionSemver.major);
|
|
81
|
+
|
|
82
|
+
// 大胆假设:任何版本号 >3.0.0 的版本,其 dist 目录都有 *-headers.tar.gz
|
|
83
|
+
canGetHeaders = semver.satisfies(versionSemver, headersTarballRange);
|
|
84
|
+
tarballUrl = new URL(name + '-v' + version + (canGetHeaders ? '-headers' : '') + '.tar.gz', baseUrl).href;
|
|
85
|
+
}
|
|
81
86
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
},
|
|
98
|
-
arm64: {
|
|
99
|
-
libUrl: libUrlArm64,
|
|
100
|
-
libPath: normalizePath(path.relative(new URL(baseUrl).pathname, new URL(libUrlArm64).pathname))
|
|
101
|
-
}
|
|
87
|
+
return {
|
|
88
|
+
version, semver: versionSemver, name,
|
|
89
|
+
baseUrl, tarballUrl, shasumsUrl: new URL('SHASUMS256.txt', baseUrl).href,
|
|
90
|
+
versionDir: (name !== 'node' ? name + '-' : '') + version,
|
|
91
|
+
ia32: {
|
|
92
|
+
libUrl: libUrl32,
|
|
93
|
+
libPath: normalizePath(path.relative(new URL(baseUrl).pathname, new URL(libUrl32).pathname))
|
|
94
|
+
},
|
|
95
|
+
x64: {
|
|
96
|
+
libUrl: libUrl64,
|
|
97
|
+
libPath: normalizePath(path.relative(new URL(baseUrl).pathname, new URL(libUrl64).pathname))
|
|
98
|
+
},
|
|
99
|
+
arm64: {
|
|
100
|
+
libUrl: libUrlArm64,
|
|
101
|
+
libPath: normalizePath(path.relative(new URL(baseUrl).pathname, new URL(libUrlArm64).pathname))
|
|
102
102
|
}
|
|
103
|
-
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
104
105
|
|
|
105
|
-
export { processRelease }
|
|
106
|
+
export { processRelease };
|
package/lib/rebuild.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 依次执行 clean、configure、build
|
|
3
|
+
* >查看定义:@see {@link rebuild}
|
|
3
4
|
*/
|
|
4
5
|
const rebuild = async (gyp, argv) => {
|
|
5
6
|
gyp.todo.push({ name: 'clean', args: [] }, { name: 'configure', args: argv }, { name: 'build', args: [] });
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
rebuild.usage = '依次执行 "clean"、"configure" 和 "build"';
|
|
9
|
-
export { rebuild }
|
|
10
|
+
export { rebuild };
|
package/lib/remove.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import gracefulFs from 'graceful-fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import * as log from './log.js';
|
|
4
3
|
import semver from 'semver';
|
|
4
|
+
import * as log from './log.js';
|
|
5
5
|
|
|
6
|
-
const fs = gracefulFs.promises
|
|
6
|
+
const fs = gracefulFs.promises;
|
|
7
7
|
/**
|
|
8
8
|
* 删除指定版本的 Node 开发文件
|
|
9
|
+
* >查看定义:@see {@link remove}
|
|
10
|
+
* @param {object} gyp gyp 实例
|
|
11
|
+
* @param {string[]} argv 命令行参数
|
|
12
|
+
* @returns {Promise<void>}
|
|
9
13
|
*/
|
|
10
|
-
|
|
14
|
+
const remove = async (gyp, argv) => {
|
|
11
15
|
const devDir = gyp.devDir;
|
|
12
16
|
log.verbose('移除', '使用 node-gyp 目录:', devDir);
|
|
13
17
|
|
|
@@ -31,7 +35,7 @@ const fs = gracefulFs.promises,
|
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
await fs.rm(versionPath, { recursive: true, force: true });
|
|
34
|
-
|
|
38
|
+
};
|
|
35
39
|
|
|
36
40
|
remove.usage = '移除指定版本的 node 开发文件';
|
|
37
|
-
export { remove }
|
|
41
|
+
export { remove };
|
package/lib/util.js
CHANGED
|
@@ -1,73 +1,93 @@
|
|
|
1
1
|
import cp from 'child_process';
|
|
2
|
-
import path from 'path';
|
|
3
2
|
import gracefulFs from 'graceful-fs';
|
|
3
|
+
import path from 'path';
|
|
4
4
|
import * as log from './log.js';
|
|
5
5
|
|
|
6
|
-
const { openSync, closeSync } = gracefulFs
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
regGetValue = async (key, value, addOpts) => {
|
|
18
|
-
const outReValue = value.replace(/\W/g, '.'), outRe = new RegExp(`^\\s+${outReValue}\\s+REG_\\w+\\s+(\\S.*)$`, 'im'),
|
|
19
|
-
reg = path.join(process.env.SystemRoot, 'System32', 'reg.exe'),
|
|
20
|
-
regArgs = ['query', key, '/v', value].concat(addOpts);
|
|
6
|
+
const { openSync, closeSync } = gracefulFs;
|
|
7
|
+
/**
|
|
8
|
+
* 执行外部命令并返回 [err, stdout, stderr]
|
|
9
|
+
* >查看定义:@see {@link execFile}
|
|
10
|
+
* @param {*} ...args
|
|
11
|
+
* @returns {*}
|
|
12
|
+
*/
|
|
13
|
+
const execFile = async (...args) => new Promise(resolve => {
|
|
14
|
+
const child = cp.execFile(...args, (...a) => resolve(a));
|
|
15
|
+
child.stdin.end();
|
|
16
|
+
});
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
18
|
+
/**
|
|
19
|
+
* 返回候选列表中第一个当前用户可读的文件或目录,都不存在则返回 undefined
|
|
20
|
+
* >查看定义:@see {@link findAccessibleSync}
|
|
21
|
+
* @param {*} logprefix
|
|
22
|
+
* @param {*} dir
|
|
23
|
+
* @param {*} candidates
|
|
24
|
+
* @returns {*}
|
|
25
|
+
*/
|
|
26
|
+
const findAccessibleSync = (logprefix, dir, candidates) => {
|
|
27
|
+
for (let next = 0; next < candidates.length; next++) {
|
|
28
|
+
const candidate = path.resolve(dir, candidates[next]);
|
|
29
|
+
let fd;
|
|
30
|
+
try {
|
|
31
|
+
fd = openSync(candidate, 'r');
|
|
32
|
+
} catch (e) {
|
|
33
|
+
// 该候选文件不存在或不可读,继续检查下一个
|
|
34
|
+
log.silly(logprefix, '无法打开 %s: %s', candidate, e.message);
|
|
35
|
+
continue;
|
|
31
36
|
}
|
|
37
|
+
closeSync(fd), log.silly(logprefix, '可读取: %s', candidate);
|
|
38
|
+
return candidate;
|
|
39
|
+
}
|
|
32
40
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
log.silly('reg', '解析 stdout 出错');
|
|
36
|
-
throw new Error('无法解析 reg.exe 的输出');
|
|
37
|
-
}
|
|
41
|
+
return undefined;
|
|
42
|
+
};
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
44
|
+
/**
|
|
45
|
+
* 读取 Windows 注册表指定键的值
|
|
46
|
+
* >查看定义:@see {@link regGetValue}
|
|
47
|
+
* @param {*} key
|
|
48
|
+
* @param {*} value
|
|
49
|
+
* @param {*} addOpts
|
|
50
|
+
* @returns {*}
|
|
51
|
+
*/
|
|
52
|
+
const regGetValue = async (key, value, addOpts) => {
|
|
53
|
+
const outReValue = value.replace(/\W/g, '.'), outRe = new RegExp(`^\\s+${outReValue}\\s+REG_\\w+\\s+(\\S.*)$`, 'im'),
|
|
54
|
+
reg = path.join(process.env.SystemRoot, 'System32', 'reg.exe'), regArgs = ['query', key, '/v', value].concat(addOpts);
|
|
55
|
+
|
|
56
|
+
log.silly('reg', '正在执行', reg, regArgs);
|
|
57
|
+
const [err, stdout, stderr] = await execFile(reg, regArgs, { encoding: 'utf8' });
|
|
58
|
+
|
|
59
|
+
log.silly('reg', 'reg.exe stdout = %j', stdout);
|
|
60
|
+
if (err || stderr.trim() !== '') {
|
|
61
|
+
log.silly('reg', 'reg.exe err = %j', err && (err.stack || err));
|
|
62
|
+
log.silly('reg', 'reg.exe stderr = %j', stderr);
|
|
63
|
+
if (err) throw err;
|
|
64
|
+
throw new Error(stderr);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const result = outRe.exec(stdout)
|
|
68
|
+
if (!result) {
|
|
69
|
+
log.silly('reg', '解析 stdout 出错');
|
|
70
|
+
throw new Error('无法解析 reg.exe 的输出');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
log.silly('reg', '找到: %j', result[1]);
|
|
74
|
+
return result[1];
|
|
75
|
+
};
|
|
69
76
|
|
|
70
|
-
|
|
77
|
+
/**
|
|
78
|
+
* 依次搜索多个注册表键,返回第一个可读的值
|
|
79
|
+
* >查看定义:@see {@link regSearchKeys}
|
|
80
|
+
* @param {*} keys
|
|
81
|
+
* @param {*} value
|
|
82
|
+
* @param {*} addOpts
|
|
83
|
+
* @returns {*}
|
|
84
|
+
*/
|
|
85
|
+
const regSearchKeys = async (keys, value, addOpts) => {
|
|
86
|
+
for (const key of keys) {
|
|
87
|
+
try {
|
|
88
|
+
return await regGetValue(key, value, addOpts);
|
|
89
|
+
} catch { continue }
|
|
71
90
|
}
|
|
91
|
+
};
|
|
72
92
|
|
|
73
|
-
export { execFile, regGetValue, regSearchKeys
|
|
93
|
+
export { execFile, findAccessibleSync, regGetValue, regSearchKeys };
|
package/package.json
CHANGED
|
@@ -1,74 +1,77 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@flun/nodejs-mobile-gyp",
|
|
3
|
-
"description": "Node.js for Mobile Apps native addon build tool (flun fork)",
|
|
4
|
-
"keywords": [
|
|
5
|
-
"nodejs-mobile",
|
|
6
|
-
"native",
|
|
7
|
-
"addon",
|
|
8
|
-
"module",
|
|
9
|
-
"c",
|
|
10
|
-
"c++",
|
|
11
|
-
"bindings",
|
|
12
|
-
"gyp"
|
|
13
|
-
],
|
|
14
|
-
"version": "1.2.
|
|
15
|
-
"installVersion": 11,
|
|
16
|
-
"author": "flun <open@flun.top>",
|
|
17
|
-
"bin": {
|
|
18
|
-
"nodejs-mobile-gyp": "./bin/node-gyp.js"
|
|
19
|
-
},
|
|
20
|
-
"main": "./lib/node-gyp.js",
|
|
21
|
-
"files": [
|
|
22
|
-
"bin/",
|
|
23
|
-
"gyp/data/",
|
|
24
|
-
"gyp/pylib/gyp/",
|
|
25
|
-
"gyp/pylib/packaging/",
|
|
26
|
-
"!gyp/pylib/gyp/__pycache__/",
|
|
27
|
-
"!gyp/pylib/gyp/generator/__pycache__/",
|
|
28
|
-
"!gyp/pylib/gyp/**/*_test.py",
|
|
29
|
-
"!gyp/pylib/packaging/__pycache__/",
|
|
30
|
-
"gyp/gyp",
|
|
31
|
-
"gyp/gyp_main.py",
|
|
32
|
-
"gyp/gyp.bat",
|
|
33
|
-
"lib/",
|
|
34
|
-
"src/",
|
|
35
|
-
"addon.gypi",
|
|
36
|
-
"CHANGELOG.md",
|
|
37
|
-
"README.md",
|
|
38
|
-
"LICENSE"
|
|
39
|
-
],
|
|
40
|
-
"dependencies": {
|
|
41
|
-
"chalk": "^6.0.1",
|
|
42
|
-
"env-paths": "^4.0.0",
|
|
43
|
-
"exponential-backoff": "^3.1.3",
|
|
44
|
-
"glob": "^14.0.
|
|
45
|
-
"graceful-fs": "^4.2.11",
|
|
46
|
-
"make-fetch-happen": "^16.0.1",
|
|
47
|
-
"nopt": "^10.0.1",
|
|
48
|
-
"proc-log": "^7.0.0",
|
|
49
|
-
"semver": "^7.8.6",
|
|
50
|
-
"tar": "^7.5.22",
|
|
51
|
-
"which": "^7.0.0"
|
|
52
|
-
},
|
|
53
|
-
"allowScripts": {
|
|
54
|
-
"node": true
|
|
55
|
-
},
|
|
56
|
-
"engines": {
|
|
57
|
-
"node": ">=22.12.0"
|
|
58
|
-
},
|
|
59
|
-
"homepage": "https://github.com/OpenFlun/nodejs-mobile-gyp#readme",
|
|
60
|
-
"repository": {
|
|
61
|
-
"type": "git",
|
|
62
|
-
"url": "git+https://github.com/OpenFlun/nodejs-mobile-gyp.git"
|
|
63
|
-
},
|
|
64
|
-
"gitee":
|
|
65
|
-
|
|
66
|
-
"url": "https://
|
|
67
|
-
},
|
|
68
|
-
"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@flun/nodejs-mobile-gyp",
|
|
3
|
+
"description": "Node.js for Mobile Apps native addon build tool (flun fork)",
|
|
4
|
+
"keywords": [
|
|
5
|
+
"nodejs-mobile",
|
|
6
|
+
"native",
|
|
7
|
+
"addon",
|
|
8
|
+
"module",
|
|
9
|
+
"c",
|
|
10
|
+
"c++",
|
|
11
|
+
"bindings",
|
|
12
|
+
"gyp"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.2.3",
|
|
15
|
+
"installVersion": 11,
|
|
16
|
+
"author": "flun <open@flun.top>",
|
|
17
|
+
"bin": {
|
|
18
|
+
"nodejs-mobile-gyp": "./bin/node-gyp.js"
|
|
19
|
+
},
|
|
20
|
+
"main": "./lib/node-gyp.js",
|
|
21
|
+
"files": [
|
|
22
|
+
"bin/",
|
|
23
|
+
"gyp/data/",
|
|
24
|
+
"gyp/pylib/gyp/",
|
|
25
|
+
"gyp/pylib/packaging/",
|
|
26
|
+
"!gyp/pylib/gyp/__pycache__/",
|
|
27
|
+
"!gyp/pylib/gyp/generator/__pycache__/",
|
|
28
|
+
"!gyp/pylib/gyp/**/*_test.py",
|
|
29
|
+
"!gyp/pylib/packaging/__pycache__/",
|
|
30
|
+
"gyp/gyp",
|
|
31
|
+
"gyp/gyp_main.py",
|
|
32
|
+
"gyp/gyp.bat",
|
|
33
|
+
"lib/",
|
|
34
|
+
"src/",
|
|
35
|
+
"addon.gypi",
|
|
36
|
+
"CHANGELOG.md",
|
|
37
|
+
"README.md",
|
|
38
|
+
"LICENSE"
|
|
39
|
+
],
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"chalk": "^6.0.1",
|
|
42
|
+
"env-paths": "^4.0.0",
|
|
43
|
+
"exponential-backoff": "^3.1.3",
|
|
44
|
+
"glob": "^14.0.4",
|
|
45
|
+
"graceful-fs": "^4.2.11",
|
|
46
|
+
"make-fetch-happen": "^16.0.1",
|
|
47
|
+
"nopt": "^10.0.1",
|
|
48
|
+
"proc-log": "^7.0.0",
|
|
49
|
+
"semver": "^7.8.6",
|
|
50
|
+
"tar": "^7.5.22",
|
|
51
|
+
"which": "^7.0.0"
|
|
52
|
+
},
|
|
53
|
+
"allowScripts": {
|
|
54
|
+
"node": true
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=22.12.0"
|
|
58
|
+
},
|
|
59
|
+
"homepage": "https://github.com/OpenFlun/nodejs-mobile-gyp#readme",
|
|
60
|
+
"repository": {
|
|
61
|
+
"type": "git",
|
|
62
|
+
"url": "git+https://github.com/OpenFlun/nodejs-mobile-gyp.git"
|
|
63
|
+
},
|
|
64
|
+
"gitee": {
|
|
65
|
+
"type": "git",
|
|
66
|
+
"url": "https://gitee.com/OpenFlun/nodejs-mobile-gyp.git"
|
|
67
|
+
},
|
|
68
|
+
"bugs": {
|
|
69
|
+
"url": "https://github.com/OpenFlun/nodejs-mobile-gyp/issues"
|
|
70
|
+
},
|
|
71
|
+
"license": "ISC",
|
|
72
|
+
"type": "module",
|
|
73
|
+
"publishConfig": {
|
|
74
|
+
"access": "public",
|
|
75
|
+
"registry": "https://registry.npmjs.org/"
|
|
76
|
+
}
|
|
74
77
|
}
|