@flun/nodejs-mobile-gyp 1.0.1 → 1.0.2
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 +56 -36
- package/README.md +256 -252
- package/addon.gypi +13 -1
- package/bin/node-gyp.js +66 -109
- package/gyp/pylib/gyp/MSVSSettings.py +13 -0
- package/lib/build.js +127 -209
- package/lib/clean.js +13 -16
- package/lib/configure.js +183 -265
- package/lib/create-config-gypi.js +102 -156
- package/lib/download.js +29 -42
- package/lib/find-node-directory.js +38 -55
- package/lib/find-python.js +162 -198
- package/lib/find-visualstudio.js +196 -295
- package/lib/install.js +269 -378
- package/lib/list.js +19 -25
- package/lib/log.js +69 -133
- package/lib/node-gyp.js +62 -107
- package/lib/process-release.js +100 -139
- package/lib/rebuild.js +3 -8
- package/lib/remove.js +34 -44
- package/lib/util.js +62 -73
- package/package.json +5 -3
- package/gyp/LICENSE +0 -28
package/lib/process-release.js
CHANGED
|
@@ -1,144 +1,105 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import semver from 'semver'
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
1
|
+
/* eslint-disable n/no-deprecated-api */
|
|
2
|
+
|
|
3
|
+
import semver from 'semver';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import * as log from './log.js';
|
|
6
|
+
|
|
7
|
+
// 开始发布 -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
|
+
bitsreV3 = /\/win-(x86|ia32|x64)\//, normalizePath = (p) => path.normalize(p).replace(/\\/g, '/'), // 统一分隔符为 /
|
|
10
|
+
/**
|
|
11
|
+
* 根据名称、基础 URL、架构、主版本号解析 lib 下载地址
|
|
12
|
+
*/
|
|
13
|
+
resolveLibUrl = (name, defaultUrl, arch, versionMajor) => {
|
|
14
|
+
const base = new URL('./', defaultUrl).href, // 相当于 url.resolve(defaultUrl, './')
|
|
15
|
+
hasLibUrl = bitsre.test(defaultUrl) || (versionMajor === 3 && bitsreV3.test(defaultUrl));
|
|
16
|
+
|
|
17
|
+
if (!hasLibUrl) {
|
|
18
|
+
// 假设传入的是 baseUrl
|
|
19
|
+
if (versionMajor >= 1) return new URL('win-' + arch + '/' + name + '.lib', base).href;
|
|
20
|
+
// io.js@1.0.0 之前,32 位 node.lib 在根目录,64 位在 /x64/
|
|
21
|
+
const prefix = arch === 'x86' ? '' : arch + '/';
|
|
22
|
+
return new URL(prefix + name + '.lib', base).href;
|
|
23
|
+
}
|
|
24
|
+
// 否则传入的已经是 .lib 地址,只需保证架构正确
|
|
25
|
+
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;
|
|
36
|
+
|
|
37
|
+
if (!versionSemver) return { version }; // 如果 semver 不合法,那么原样返回 version
|
|
38
|
+
version = versionSemver.version; // 把 version 拍平为字符串
|
|
39
|
+
|
|
40
|
+
// defaultVersion 来自 process.version,应当是合法 semver
|
|
41
|
+
const isDefaultVersion = version === semver.parse(defaultVersion).version;
|
|
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';
|
|
29
53
|
}
|
|
30
|
-
// io.js@1.0.0 之前,32 位 node.lib 在根目录,64 位在 /x64/
|
|
31
|
-
return url.resolve(base, (arch === 'x86' ? '' : arch + '/') + name + '.lib')
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// 否则传入的已经是 .lib 地址,只需保证架构正确
|
|
35
|
-
return defaultUrl.replace(versionMajor === 3 ? bitsreV3 : bitsre, '/win-' + arch + '/')
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* 负责确定下载 URL、本地目录和文件名。
|
|
40
|
-
* 输入来自命令行开关(--target、--dist-url)、process.version 和 process.release。
|
|
41
|
-
*/
|
|
42
|
-
const processRelease = (argv, gyp, defaultVersion, defaultRelease) => {
|
|
43
|
-
let version = (semver.valid(argv[0]) && argv[0]) || gyp.opts.target || defaultVersion
|
|
44
|
-
const versionSemver = semver.parse(version)
|
|
45
|
-
let overrideDistUrl = gyp.opts['dist-url'] || gyp.opts.disturl
|
|
46
|
-
let isNamedForLegacyIojs
|
|
47
|
-
let name
|
|
48
|
-
let distBaseUrl
|
|
49
|
-
let baseUrl
|
|
50
|
-
let libUrl32
|
|
51
|
-
let libUrl64
|
|
52
|
-
let libUrlArm64
|
|
53
|
-
let tarballUrl
|
|
54
|
-
let canGetHeaders
|
|
55
|
-
|
|
56
|
-
if (!versionSemver) {
|
|
57
|
-
// 不是合法 semver,只能原样返回 version
|
|
58
|
-
return { version }
|
|
59
|
-
}
|
|
60
|
-
// 把 version 拍平为字符串
|
|
61
|
-
version = versionSemver.version
|
|
62
|
-
|
|
63
|
-
// defaultVersion 来自 process.version,应当是合法 semver
|
|
64
|
-
const isDefaultVersion = version === semver.parse(defaultVersion).version
|
|
65
|
-
|
|
66
|
-
// 用了 --target=x.y.z 就不能用 process.release
|
|
67
|
-
if (!isDefaultVersion) {
|
|
68
|
-
defaultRelease = null
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (defaultRelease) {
|
|
72
|
-
// v3 起有 process.release
|
|
73
|
-
name = defaultRelease.name.replace(/io\.js/, 'iojs') // 去掉 '.' 以便目录命名
|
|
74
|
-
} else {
|
|
75
|
-
// 老版本 Node 或自定义 --target
|
|
76
|
-
// semver.satisfies() 不支持预发布标签,因此直接判断主版本
|
|
77
|
-
isNamedForLegacyIojs = versionSemver.major >= 1 && versionSemver.major < 4
|
|
78
|
-
// isNamedForLegacyIojs 是为了支持 Electron < 4(特别是 Electron 3)
|
|
79
|
-
// 早期逻辑用它保证 iojs 版本下载 "iojs",Node 版本下载 "node"。
|
|
80
|
-
// 但该逻辑过宽,导致 electron@3 的发布物命名为 "iojs" 才能让 node-gyp 正常工作。
|
|
81
|
-
// Electron@3 EOL 之后(2019 年底)应移除这个 hack。
|
|
82
|
-
name = isNamedForLegacyIojs ? 'iojs' : 'node'
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// 检查 nvm.sh 标准镜像环境变量
|
|
86
|
-
if (!overrideDistUrl && process.env.NODEJS_ORG_MIRROR) {
|
|
87
|
-
overrideDistUrl = process.env.NODEJS_ORG_MIRROR
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (overrideDistUrl) {
|
|
91
|
-
log.verbose('download', 'using dist-url', overrideDistUrl)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (overrideDistUrl) {
|
|
95
|
-
distBaseUrl = overrideDistUrl.replace(/\/+$/, '')
|
|
96
|
-
} else {
|
|
97
|
-
distBaseUrl = 'https://nodejs.org/dist'
|
|
98
|
-
}
|
|
99
|
-
distBaseUrl += '/v' + version + '/'
|
|
100
|
-
|
|
101
|
-
// 新式:基于 process.release,大部分数据已有
|
|
102
|
-
if (defaultRelease && defaultRelease.headersUrl && !overrideDistUrl) {
|
|
103
|
-
baseUrl = url.resolve(defaultRelease.headersUrl, './')
|
|
104
|
-
libUrl32 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x86', versionSemver.major)
|
|
105
|
-
libUrl64 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x64', versionSemver.major)
|
|
106
|
-
libUrlArm64 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'arm64', versionSemver.major)
|
|
107
|
-
tarballUrl = defaultRelease.headersUrl
|
|
108
|
-
} else {
|
|
109
|
-
// 没有 process.release 的老版本,需要做很多假设;
|
|
110
|
-
// 另外 --target=x.y.z 时也无法使用当前 process.release
|
|
111
|
-
baseUrl = distBaseUrl
|
|
112
|
-
libUrl32 = resolveLibUrl(name, baseUrl, 'x86', versionSemver.major)
|
|
113
|
-
libUrl64 = resolveLibUrl(name, baseUrl, 'x64', versionSemver.major)
|
|
114
|
-
libUrlArm64 = resolveLibUrl(name, baseUrl, 'arm64', versionSemver.major)
|
|
115
54
|
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
55
|
+
// 检查 nvm.sh 标准镜像环境变量
|
|
56
|
+
if (!overrideDistUrl && process.env.NODEJS_ORG_MIRROR) overrideDistUrl = process.env.NODEJS_ORG_MIRROR;
|
|
57
|
+
if (overrideDistUrl) log.verbose('download', 'using dist-url', overrideDistUrl);
|
|
58
|
+
if (overrideDistUrl) distBaseUrl = overrideDistUrl.replace(/\/+$/, '');
|
|
59
|
+
else distBaseUrl = 'https://nodejs.org/dist';
|
|
60
|
+
distBaseUrl += '/v' + version + '/'
|
|
61
|
+
|
|
62
|
+
// 新式:基于 process.release,大部分数据已有
|
|
63
|
+
if (defaultRelease?.headersUrl && !overrideDistUrl) {
|
|
64
|
+
baseUrl = new URL('./', defaultRelease.headersUrl).href;
|
|
65
|
+
libUrl32 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x86', versionSemver.major);
|
|
66
|
+
libUrl64 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x64', versionSemver.major);
|
|
67
|
+
libUrlArm64 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'arm64', versionSemver.major);
|
|
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);
|
|
76
|
+
|
|
77
|
+
// 大胆假设:任何版本号 >3.0.0 的版本,其 dist 目录都有 *-headers.tar.gz
|
|
78
|
+
canGetHeaders = semver.satisfies(versionSemver, headersTarballRange);
|
|
79
|
+
tarballUrl = new URL(name + '-v' + version + (canGetHeaders ? '-headers' : '') + '.tar.gz', baseUrl).href;
|
|
80
|
+
}
|
|
120
81
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
82
|
+
return {
|
|
83
|
+
version,
|
|
84
|
+
semver: versionSemver,
|
|
85
|
+
name,
|
|
86
|
+
baseUrl,
|
|
87
|
+
tarballUrl,
|
|
88
|
+
shasumsUrl: new URL('SHASUMS256.txt', baseUrl).href,
|
|
89
|
+
versionDir: (name !== 'node' ? name + '-' : '') + version,
|
|
90
|
+
ia32: {
|
|
91
|
+
libUrl: libUrl32,
|
|
92
|
+
libPath: normalizePath(path.relative(new URL(baseUrl).pathname, new URL(libUrl32).pathname))
|
|
93
|
+
},
|
|
94
|
+
x64: {
|
|
95
|
+
libUrl: libUrl64,
|
|
96
|
+
libPath: normalizePath(path.relative(new URL(baseUrl).pathname, new URL(libUrl64).pathname))
|
|
97
|
+
},
|
|
98
|
+
arm64: {
|
|
99
|
+
libUrl: libUrlArm64,
|
|
100
|
+
libPath: normalizePath(path.relative(new URL(baseUrl).pathname, new URL(libUrlArm64).pathname))
|
|
101
|
+
}
|
|
140
102
|
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
103
|
+
};
|
|
143
104
|
|
|
144
|
-
export { processRelease }
|
|
105
|
+
export { processRelease }
|
package/lib/rebuild.js
CHANGED
|
@@ -2,13 +2,8 @@
|
|
|
2
2
|
* 依次执行 clean、configure、build
|
|
3
3
|
*/
|
|
4
4
|
const rebuild = async (gyp, argv) => {
|
|
5
|
-
gyp.todo.push(
|
|
6
|
-
{ name: 'clean', args: [] }
|
|
7
|
-
, { name: 'configure', args: argv }
|
|
8
|
-
, { name: 'build', args: [] }
|
|
9
|
-
)
|
|
5
|
+
gyp.todo.push({ name: 'clean', args: [] }, { name: 'configure', args: argv }, { name: 'build', args: [] });
|
|
10
6
|
}
|
|
11
7
|
|
|
12
|
-
rebuild.usage = 'Runs "clean", "configure" and "build" all at once'
|
|
13
|
-
|
|
14
|
-
export { rebuild }
|
|
8
|
+
rebuild.usage = 'Runs "clean", "configure" and "build" all at once';
|
|
9
|
+
export { rebuild }
|
package/lib/remove.js
CHANGED
|
@@ -1,47 +1,37 @@
|
|
|
1
|
-
import gracefulFs from 'graceful-fs'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import * as log from './log.js'
|
|
4
|
-
import semver from 'semver'
|
|
5
|
-
|
|
6
|
-
const fs = gracefulFs.promises
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// 先检查是否安装过
|
|
33
|
-
try {
|
|
34
|
-
await fs.stat(versionPath)
|
|
35
|
-
} catch (err) {
|
|
36
|
-
if (err.code === 'ENOENT') {
|
|
37
|
-
return 'version was already uninstalled: ' + version
|
|
1
|
+
import gracefulFs from 'graceful-fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import * as log from './log.js';
|
|
4
|
+
import semver from 'semver';
|
|
5
|
+
|
|
6
|
+
const fs = gracefulFs.promises,
|
|
7
|
+
/**
|
|
8
|
+
* 删除指定版本的 Node 开发文件
|
|
9
|
+
*/
|
|
10
|
+
remove = async (gyp, argv) => {
|
|
11
|
+
const devDir = gyp.devDir;
|
|
12
|
+
log.verbose('remove', 'using node-gyp dir:', devDir);
|
|
13
|
+
|
|
14
|
+
// 获取用户指定的版本号
|
|
15
|
+
let version = argv[0] || gyp.opts.target;
|
|
16
|
+
log.verbose('remove', 'removing target version:', version);
|
|
17
|
+
if (!version) throw new Error('必须指定要删除的版本号,例如: "' + process.version + '"');
|
|
18
|
+
|
|
19
|
+
const versionSemver = semver.parse(version);
|
|
20
|
+
if (versionSemver) version = versionSemver.version; // 把版本数组拍平为字符串
|
|
21
|
+
|
|
22
|
+
const versionPath = path.resolve(gyp.devDir, version);
|
|
23
|
+
log.verbose('remove', 'removing development files for version:', version);
|
|
24
|
+
|
|
25
|
+
// 先检查是否安装过
|
|
26
|
+
try {
|
|
27
|
+
await fs.stat(versionPath);
|
|
28
|
+
} catch (err) {
|
|
29
|
+
if (err.code === 'ENOENT') return 'version was already uninstalled: ' + version;
|
|
30
|
+
throw err;
|
|
38
31
|
}
|
|
39
|
-
throw err
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
await fs.rm(versionPath, { recursive: true, force: true })
|
|
43
|
-
}
|
|
44
32
|
|
|
45
|
-
|
|
33
|
+
await fs.rm(versionPath, { recursive: true, force: true });
|
|
34
|
+
}
|
|
46
35
|
|
|
47
|
-
|
|
36
|
+
remove.usage = 'Removes the node development files for the specified version';
|
|
37
|
+
export { remove }
|
package/lib/util.js
CHANGED
|
@@ -1,83 +1,72 @@
|
|
|
1
|
-
import cp from 'child_process'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import gracefulFs from 'graceful-fs'
|
|
4
|
-
import * as log from './log.js'
|
|
1
|
+
import cp from 'child_process';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import gracefulFs from 'graceful-fs';
|
|
4
|
+
import * as log from './log.js';
|
|
5
5
|
|
|
6
|
-
const { openSync, closeSync } = gracefulFs
|
|
6
|
+
const { openSync, closeSync } = gracefulFs,
|
|
7
|
+
/**
|
|
8
|
+
* 执行外部命令并返回 [err, stdout, stderr]
|
|
9
|
+
*/
|
|
10
|
+
execFile = async (...args) => new Promise(resolve => {
|
|
11
|
+
const child = cp.execFile(...args, (...a) => resolve(a));
|
|
12
|
+
child.stdin.end();
|
|
13
|
+
}),
|
|
14
|
+
/**
|
|
15
|
+
* 读取 Windows 注册表指定键的值
|
|
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'), regArgs = ['query', key, '/v', value].concat(addOpts);
|
|
7
20
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*/
|
|
11
|
-
const execFile = async (...args) => new Promise((resolve) => {
|
|
12
|
-
const child = cp.execFile(...args, (...a) => resolve(a))
|
|
13
|
-
child.stdin.end()
|
|
14
|
-
})
|
|
21
|
+
log.silly('reg', 'running', reg, regArgs);
|
|
22
|
+
const [err, stdout, stderr] = await execFile(reg, regArgs, { encoding: 'utf8' });
|
|
15
23
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const reg = path.join(process.env.SystemRoot, 'System32', 'reg.exe')
|
|
23
|
-
const regArgs = ['query', key, '/v', value].concat(addOpts)
|
|
24
|
-
|
|
25
|
-
log.silly('reg', 'running', reg, regArgs)
|
|
26
|
-
const [err, stdout, stderr] = await execFile(reg, regArgs, { encoding: 'utf8' })
|
|
27
|
-
|
|
28
|
-
log.silly('reg', 'reg.exe stdout = %j', stdout)
|
|
29
|
-
if (err || stderr.trim() !== '') {
|
|
30
|
-
log.silly('reg', 'reg.exe err = %j', err && (err.stack || err))
|
|
31
|
-
log.silly('reg', 'reg.exe stderr = %j', stderr)
|
|
32
|
-
if (err) {
|
|
33
|
-
throw err
|
|
24
|
+
log.silly('reg', 'reg.exe stdout = %j', stdout);
|
|
25
|
+
if (err || stderr.trim() !== '') {
|
|
26
|
+
log.silly('reg', 'reg.exe err = %j', err && (err.stack || err));
|
|
27
|
+
log.silly('reg', 'reg.exe stderr = %j', stderr);
|
|
28
|
+
if (err) throw err;
|
|
29
|
+
throw new Error(stderr);
|
|
34
30
|
}
|
|
35
|
-
throw new Error(stderr)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const result = outRe.exec(stdout)
|
|
39
|
-
if (!result) {
|
|
40
|
-
log.silly('reg', 'error parsing stdout')
|
|
41
|
-
throw new Error('Could not parse output of reg.exe')
|
|
42
|
-
}
|
|
43
31
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* 依次搜索多个注册表键,返回第一个可读的值
|
|
50
|
-
*/
|
|
51
|
-
const regSearchKeys = async (keys, value, addOpts) => {
|
|
52
|
-
for (const key of keys) {
|
|
53
|
-
try {
|
|
54
|
-
return await regGetValue(key, value, addOpts)
|
|
55
|
-
} catch {
|
|
56
|
-
continue
|
|
32
|
+
const result = outRe.exec(stdout)
|
|
33
|
+
if (!result) {
|
|
34
|
+
log.silly('reg', 'error parsing stdout');
|
|
35
|
+
throw new Error('无法解析 reg.exe 的输出');
|
|
57
36
|
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
37
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
38
|
+
log.silly('reg', 'found: %j', result[1]);
|
|
39
|
+
return result[1];
|
|
40
|
+
},
|
|
41
|
+
/**
|
|
42
|
+
* 依次搜索多个注册表键,返回第一个可读的值
|
|
43
|
+
*/
|
|
44
|
+
regSearchKeys = async (keys, value, addOpts) => {
|
|
45
|
+
for (const key of keys) {
|
|
46
|
+
try {
|
|
47
|
+
return await regGetValue(key, value, addOpts);
|
|
48
|
+
} catch { continue }
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
/**
|
|
52
|
+
* 返回候选列表中第一个当前用户可读的文件或目录,都不存在则返回 undefined
|
|
53
|
+
*/
|
|
54
|
+
findAccessibleSync = (logprefix, dir, candidates) => {
|
|
55
|
+
for (let next = 0; next < candidates.length; next++) {
|
|
56
|
+
const candidate = path.resolve(dir, candidates[next]);
|
|
57
|
+
let fd;
|
|
58
|
+
try {
|
|
59
|
+
fd = openSync(candidate, 'r');
|
|
60
|
+
} catch (e) {
|
|
61
|
+
// 该候选文件不存在或不可读,继续检查下一个
|
|
62
|
+
log.silly(logprefix, 'Could not open %s: %s', candidate, e.message);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
closeSync(fd), log.silly(logprefix, 'Found readable %s', candidate);
|
|
66
|
+
return candidate;
|
|
74
67
|
}
|
|
75
|
-
closeSync(fd)
|
|
76
|
-
log.silly(logprefix, 'Found readable %s', candidate)
|
|
77
|
-
return candidate
|
|
78
|
-
}
|
|
79
68
|
|
|
80
|
-
|
|
81
|
-
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
82
71
|
|
|
83
|
-
export { execFile, regGetValue, regSearchKeys, findAccessibleSync }
|
|
72
|
+
export { execFile, regGetValue, regSearchKeys, findAccessibleSync }
|
package/package.json
CHANGED
|
@@ -11,10 +11,12 @@
|
|
|
11
11
|
"bindings",
|
|
12
12
|
"gyp"
|
|
13
13
|
],
|
|
14
|
-
"version": "1.0.
|
|
14
|
+
"version": "1.0.2",
|
|
15
15
|
"installVersion": 11,
|
|
16
16
|
"author": "flun <open@flun.top>",
|
|
17
|
-
"bin":
|
|
17
|
+
"bin": {
|
|
18
|
+
"nodejs-mobile-gyp": "./bin/node-gyp.js"
|
|
19
|
+
},
|
|
18
20
|
"main": "./lib/node-gyp.js",
|
|
19
21
|
"files": [
|
|
20
22
|
"bin/",
|
|
@@ -52,7 +54,7 @@
|
|
|
52
54
|
"node": true
|
|
53
55
|
},
|
|
54
56
|
"engines": {
|
|
55
|
-
"node": ">=
|
|
57
|
+
"node": "^22.22.2 || ^24.15.0 || >=26.0.0"
|
|
56
58
|
},
|
|
57
59
|
"homepage": "https://github.com/OpenFlun/nodejs-mobile-gyp",
|
|
58
60
|
"repository": {
|
package/gyp/LICENSE
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
Copyright (c) 2020 Node.js contributors. All rights reserved.
|
|
2
|
-
Copyright (c) 2009 Google Inc. All rights reserved.
|
|
3
|
-
|
|
4
|
-
Redistribution and use in source and binary forms, with or without
|
|
5
|
-
modification, are permitted provided that the following conditions are
|
|
6
|
-
met:
|
|
7
|
-
|
|
8
|
-
* Redistributions of source code must retain the above copyright
|
|
9
|
-
notice, this list of conditions and the following disclaimer.
|
|
10
|
-
* Redistributions in binary form must reproduce the above
|
|
11
|
-
copyright notice, this list of conditions and the following disclaimer
|
|
12
|
-
in the documentation and/or other materials provided with the
|
|
13
|
-
distribution.
|
|
14
|
-
* Neither the name of Google Inc. nor the names of its
|
|
15
|
-
contributors may be used to endorse or promote products derived from
|
|
16
|
-
this software without specific prior written permission.
|
|
17
|
-
|
|
18
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
19
|
-
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
20
|
-
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
21
|
-
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
22
|
-
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
23
|
-
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
24
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
25
|
-
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
26
|
-
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
27
|
-
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|