maactl 0.1.0 → 0.1.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/README.md +64 -62
- package/bin/maactl.js +19 -19
- package/lib/binary.js +221 -221
- package/lib/cli.js +136 -136
- package/lib/download.js +188 -188
- package/lib/env.js +17 -17
- package/lib/errors.js +17 -17
- package/lib/messages.js +80 -80
- package/package.json +52 -52
- package/scripts/install.js +48 -48
- package/scripts/vendor-binary.js +67 -67
- package/vendor/maactl.exe +0 -0
package/lib/env.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Small helpers so every module reads the environment the same way.
|
|
4
|
-
|
|
5
|
-
const TRUTHY = new Set(['1', 'true', 'yes', 'on']);
|
|
6
|
-
|
|
7
|
-
/** Trimmed value of an environment variable ('' when unset). */
|
|
8
|
-
function value(name) {
|
|
9
|
-
return (process.env[name] || '').trim();
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/** True when the variable is set to 1/true/yes/on (regardless of case). */
|
|
13
|
-
function flag(name) {
|
|
14
|
-
return TRUTHY.has(value(name).toLowerCase());
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
module.exports = { value, flag };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Small helpers so every module reads the environment the same way.
|
|
4
|
+
|
|
5
|
+
const TRUTHY = new Set(['1', 'true', 'yes', 'on']);
|
|
6
|
+
|
|
7
|
+
/** Trimmed value of an environment variable ('' when unset). */
|
|
8
|
+
function value(name) {
|
|
9
|
+
return (process.env[name] || '').trim();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** True when the variable is set to 1/true/yes/on (regardless of case). */
|
|
13
|
+
function flag(name) {
|
|
14
|
+
return TRUTHY.has(value(name).toLowerCase());
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = { value, flag };
|
package/lib/errors.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Error type used for every failure raised by the npm wrapper itself.
|
|
5
|
-
*
|
|
6
|
-
* The wrapper never relays these to maactl.exe: they describe problems with
|
|
7
|
-
* locating, downloading or starting the executable.
|
|
8
|
-
*/
|
|
9
|
-
class MaactlError extends Error {
|
|
10
|
-
constructor(message, { exitCode = 1, cause } = {}) {
|
|
11
|
-
super(message, cause ? { cause } : undefined);
|
|
12
|
-
this.name = 'MaactlError';
|
|
13
|
-
this.exitCode = exitCode;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
module.exports = { MaactlError };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error type used for every failure raised by the npm wrapper itself.
|
|
5
|
+
*
|
|
6
|
+
* The wrapper never relays these to maactl.exe: they describe problems with
|
|
7
|
+
* locating, downloading or starting the executable.
|
|
8
|
+
*/
|
|
9
|
+
class MaactlError extends Error {
|
|
10
|
+
constructor(message, { exitCode = 1, cause } = {}) {
|
|
11
|
+
super(message, cause ? { cause } : undefined);
|
|
12
|
+
this.name = 'MaactlError';
|
|
13
|
+
this.exitCode = exitCode;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = { MaactlError };
|
package/lib/messages.js
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// The wrapper only prints text for error and progress paths, so the message
|
|
4
|
-
// catalogue stays small. Language follows MAACTL_LANG, the same variable the
|
|
5
|
-
// CLI itself honours; anything not starting with "zh" falls back to English.
|
|
6
|
-
|
|
7
|
-
const MESSAGES = {
|
|
8
|
-
zh: {
|
|
9
|
-
downloading: (url) => `maactl: 首次使用,正在下载 maactl.exe\n ${url}`,
|
|
10
|
-
downloaded: (size, dest) => `maactl: 已下载 ${size} 到 ${dest}`,
|
|
11
|
-
downloadFailed: (url, reason) =>
|
|
12
|
-
`maactl: 下载 maactl.exe 失败\n ${url}\n 原因: ${reason}`,
|
|
13
|
-
verifyFailed: (file, reason) => `maactl: 下载的 maactl.exe 校验失败 (${file})\n 原因: ${reason}`,
|
|
14
|
-
explicitMissing: (file) => `maactl: MAACTL_BINARY 指向的文件不存在: ${file}`,
|
|
15
|
-
spawnFailed: (file, reason) => `maactl: 无法启动 maactl.exe (${file})\n 原因: ${reason}`,
|
|
16
|
-
resolveHint: () =>
|
|
17
|
-
[
|
|
18
|
-
'maactl: 找不到 maactl.exe。可用的解决办法:',
|
|
19
|
-
' 1. 设置 MAACTL_BINARY 指向本地已有的 maactl.exe;',
|
|
20
|
-
' 2. 检查网络后重试,或设置 MAACTL_MIRROR 使用镜像下载;',
|
|
21
|
-
' 3. 手动下载 release 里的 maactl.exe,放到 %LOCALAPPDATA%\\maactl\\npm\\<version>\\ 下。',
|
|
22
|
-
].join('\n'),
|
|
23
|
-
skippingDownload: () => 'maactl: 已跳过 maactl.exe 下载 (MAACTL_SKIP_DOWNLOAD)',
|
|
24
|
-
bundledMissing: (file) => `maactl: 未找到内置的 ${file},改为下载 maactl.exe`,
|
|
25
|
-
preDownloadFailed: (reason) => `maactl: 预下载 maactl.exe 失败 (${reason})`,
|
|
26
|
-
preDownloadHint: () =>
|
|
27
|
-
'maactl: 改为首次运行时下载;设置 MAACTL_STRICT_INSTALL=1 可让安装在此处直接失败。',
|
|
28
|
-
usingBinary: (file) => `maactl: 使用 ${file}`,
|
|
29
|
-
},
|
|
30
|
-
en: {
|
|
31
|
-
downloading: (url) => `maactl: downloading maactl.exe for first use\n ${url}`,
|
|
32
|
-
downloaded: (size, dest) => `maactl: downloaded ${size} to ${dest}`,
|
|
33
|
-
downloadFailed: (url, reason) => `maactl: could not download maactl.exe\n ${url}\n reason: ${reason}`,
|
|
34
|
-
verifyFailed: (file, reason) => `maactl: the downloaded maactl.exe failed verification (${file})\n reason: ${reason}`,
|
|
35
|
-
explicitMissing: (file) => `maactl: MAACTL_BINARY points at a missing file: ${file}`,
|
|
36
|
-
spawnFailed: (file, reason) => `maactl: could not start maactl.exe (${file})\n reason: ${reason}`,
|
|
37
|
-
resolveHint: () =>
|
|
38
|
-
[
|
|
39
|
-
'maactl: maactl.exe could not be located. Things to try:',
|
|
40
|
-
' 1. set MAACTL_BINARY to an existing maactl.exe;',
|
|
41
|
-
' 2. check your network and retry, or set MAACTL_MIRROR to use a mirror;',
|
|
42
|
-
' 3. download maactl.exe from the release page and place it in %LOCALAPPDATA%\\maactl\\npm\\<version>\\.',
|
|
43
|
-
].join('\n'),
|
|
44
|
-
skippingDownload: () => 'maactl: skipped downloading maactl.exe (MAACTL_SKIP_DOWNLOAD)',
|
|
45
|
-
bundledMissing: (file) => `maactl: no bundled ${file}; fetching maactl.exe instead`,
|
|
46
|
-
preDownloadFailed: (reason) => `maactl: could not pre-download maactl.exe (${reason})`,
|
|
47
|
-
preDownloadHint: () =>
|
|
48
|
-
'maactl: it will be fetched on first run instead; set MAACTL_STRICT_INSTALL=1 to fail the install here.',
|
|
49
|
-
usingBinary: (file) => `maactl: using ${file}`,
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
function language() {
|
|
54
|
-
const explicit = (process.env.MAACTL_LANG || '').trim().toLowerCase();
|
|
55
|
-
if (explicit) {
|
|
56
|
-
return explicit.startsWith('zh') ? 'zh' : 'en';
|
|
57
|
-
}
|
|
58
|
-
if (process.platform !== 'win32') {
|
|
59
|
-
const posix = `${process.env.LC_ALL || ''}${process.env.LC_MESSAGES || ''}${process.env.LANG || ''}`.toLowerCase();
|
|
60
|
-
if (posix) {
|
|
61
|
-
return posix.includes('zh') ? 'zh' : 'en';
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
let locale = '';
|
|
65
|
-
try {
|
|
66
|
-
locale = Intl.DateTimeFormat().resolvedOptions().locale || '';
|
|
67
|
-
} catch {
|
|
68
|
-
locale = '';
|
|
69
|
-
}
|
|
70
|
-
return locale.toLowerCase().startsWith('zh') ? 'zh' : 'en';
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/** Return the localized message for `key`, formatted with `args`. */
|
|
74
|
-
function text(key, ...args) {
|
|
75
|
-
const catalogue = MESSAGES[language()] || MESSAGES.en;
|
|
76
|
-
const entry = catalogue[key] || MESSAGES.en[key];
|
|
77
|
-
return typeof entry === 'function' ? entry(...args) : String(entry ?? '');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
module.exports = { text, language };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// The wrapper only prints text for error and progress paths, so the message
|
|
4
|
+
// catalogue stays small. Language follows MAACTL_LANG, the same variable the
|
|
5
|
+
// CLI itself honours; anything not starting with "zh" falls back to English.
|
|
6
|
+
|
|
7
|
+
const MESSAGES = {
|
|
8
|
+
zh: {
|
|
9
|
+
downloading: (url) => `maactl: 首次使用,正在下载 maactl.exe\n ${url}`,
|
|
10
|
+
downloaded: (size, dest) => `maactl: 已下载 ${size} 到 ${dest}`,
|
|
11
|
+
downloadFailed: (url, reason) =>
|
|
12
|
+
`maactl: 下载 maactl.exe 失败\n ${url}\n 原因: ${reason}`,
|
|
13
|
+
verifyFailed: (file, reason) => `maactl: 下载的 maactl.exe 校验失败 (${file})\n 原因: ${reason}`,
|
|
14
|
+
explicitMissing: (file) => `maactl: MAACTL_BINARY 指向的文件不存在: ${file}`,
|
|
15
|
+
spawnFailed: (file, reason) => `maactl: 无法启动 maactl.exe (${file})\n 原因: ${reason}`,
|
|
16
|
+
resolveHint: () =>
|
|
17
|
+
[
|
|
18
|
+
'maactl: 找不到 maactl.exe。可用的解决办法:',
|
|
19
|
+
' 1. 设置 MAACTL_BINARY 指向本地已有的 maactl.exe;',
|
|
20
|
+
' 2. 检查网络后重试,或设置 MAACTL_MIRROR 使用镜像下载;',
|
|
21
|
+
' 3. 手动下载 release 里的 maactl.exe,放到 %LOCALAPPDATA%\\maactl\\npm\\<version>\\ 下。',
|
|
22
|
+
].join('\n'),
|
|
23
|
+
skippingDownload: () => 'maactl: 已跳过 maactl.exe 下载 (MAACTL_SKIP_DOWNLOAD)',
|
|
24
|
+
bundledMissing: (file) => `maactl: 未找到内置的 ${file},改为下载 maactl.exe`,
|
|
25
|
+
preDownloadFailed: (reason) => `maactl: 预下载 maactl.exe 失败 (${reason})`,
|
|
26
|
+
preDownloadHint: () =>
|
|
27
|
+
'maactl: 改为首次运行时下载;设置 MAACTL_STRICT_INSTALL=1 可让安装在此处直接失败。',
|
|
28
|
+
usingBinary: (file) => `maactl: 使用 ${file}`,
|
|
29
|
+
},
|
|
30
|
+
en: {
|
|
31
|
+
downloading: (url) => `maactl: downloading maactl.exe for first use\n ${url}`,
|
|
32
|
+
downloaded: (size, dest) => `maactl: downloaded ${size} to ${dest}`,
|
|
33
|
+
downloadFailed: (url, reason) => `maactl: could not download maactl.exe\n ${url}\n reason: ${reason}`,
|
|
34
|
+
verifyFailed: (file, reason) => `maactl: the downloaded maactl.exe failed verification (${file})\n reason: ${reason}`,
|
|
35
|
+
explicitMissing: (file) => `maactl: MAACTL_BINARY points at a missing file: ${file}`,
|
|
36
|
+
spawnFailed: (file, reason) => `maactl: could not start maactl.exe (${file})\n reason: ${reason}`,
|
|
37
|
+
resolveHint: () =>
|
|
38
|
+
[
|
|
39
|
+
'maactl: maactl.exe could not be located. Things to try:',
|
|
40
|
+
' 1. set MAACTL_BINARY to an existing maactl.exe;',
|
|
41
|
+
' 2. check your network and retry, or set MAACTL_MIRROR to use a mirror;',
|
|
42
|
+
' 3. download maactl.exe from the release page and place it in %LOCALAPPDATA%\\maactl\\npm\\<version>\\.',
|
|
43
|
+
].join('\n'),
|
|
44
|
+
skippingDownload: () => 'maactl: skipped downloading maactl.exe (MAACTL_SKIP_DOWNLOAD)',
|
|
45
|
+
bundledMissing: (file) => `maactl: no bundled ${file}; fetching maactl.exe instead`,
|
|
46
|
+
preDownloadFailed: (reason) => `maactl: could not pre-download maactl.exe (${reason})`,
|
|
47
|
+
preDownloadHint: () =>
|
|
48
|
+
'maactl: it will be fetched on first run instead; set MAACTL_STRICT_INSTALL=1 to fail the install here.',
|
|
49
|
+
usingBinary: (file) => `maactl: using ${file}`,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
function language() {
|
|
54
|
+
const explicit = (process.env.MAACTL_LANG || '').trim().toLowerCase();
|
|
55
|
+
if (explicit) {
|
|
56
|
+
return explicit.startsWith('zh') ? 'zh' : 'en';
|
|
57
|
+
}
|
|
58
|
+
if (process.platform !== 'win32') {
|
|
59
|
+
const posix = `${process.env.LC_ALL || ''}${process.env.LC_MESSAGES || ''}${process.env.LANG || ''}`.toLowerCase();
|
|
60
|
+
if (posix) {
|
|
61
|
+
return posix.includes('zh') ? 'zh' : 'en';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
let locale = '';
|
|
65
|
+
try {
|
|
66
|
+
locale = Intl.DateTimeFormat().resolvedOptions().locale || '';
|
|
67
|
+
} catch {
|
|
68
|
+
locale = '';
|
|
69
|
+
}
|
|
70
|
+
return locale.toLowerCase().startsWith('zh') ? 'zh' : 'en';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Return the localized message for `key`, formatted with `args`. */
|
|
74
|
+
function text(key, ...args) {
|
|
75
|
+
const catalogue = MESSAGES[language()] || MESSAGES.en;
|
|
76
|
+
const entry = catalogue[key] || MESSAGES.en[key];
|
|
77
|
+
return typeof entry === 'function' ? entry(...args) : String(entry ?? '');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
module.exports = { text, language };
|
package/package.json
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "maactl",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "MaaFramework / ProjectInterface v2 command-line client, runnable with npx on Windows",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"maactl",
|
|
7
|
-
"maafw",
|
|
8
|
-
"maaframework",
|
|
9
|
-
"projectinterface",
|
|
10
|
-
"automation",
|
|
11
|
-
"adb",
|
|
12
|
-
"cli"
|
|
13
|
-
],
|
|
14
|
-
"license": "MIT",
|
|
15
|
-
"author": "TanyaShue",
|
|
16
|
-
"homepage": "https://github.com/TanyaShue/MaaCtl#readme",
|
|
17
|
-
"repository": {
|
|
18
|
-
"type": "git",
|
|
19
|
-
"url": "git+https://github.com/TanyaShue/MaaCtl.git",
|
|
20
|
-
"directory": "npm"
|
|
21
|
-
},
|
|
22
|
-
"bugs": {
|
|
23
|
-
"url": "https://github.com/TanyaShue/MaaCtl/issues"
|
|
24
|
-
},
|
|
25
|
-
"bin": {
|
|
26
|
-
"maactl": "bin/maactl.js"
|
|
27
|
-
},
|
|
28
|
-
"files": [
|
|
29
|
-
"bin/",
|
|
30
|
-
"lib/",
|
|
31
|
-
"scripts/",
|
|
32
|
-
"vendor/",
|
|
33
|
-
"README.md"
|
|
34
|
-
],
|
|
35
|
-
"scripts": {
|
|
36
|
-
"postinstall": "node scripts/install.js",
|
|
37
|
-
"vendor:binary": "node scripts/vendor-binary.js",
|
|
38
|
-
"check:vendor": "node scripts/vendor-binary.js --check",
|
|
39
|
-
"test": "node --test",
|
|
40
|
-
"prepublishOnly": "npm test && npm run check:vendor"
|
|
41
|
-
},
|
|
42
|
-
"engines": {
|
|
43
|
-
"node": ">=
|
|
44
|
-
},
|
|
45
|
-
"os": [
|
|
46
|
-
"win32"
|
|
47
|
-
],
|
|
48
|
-
"publishConfig": {
|
|
49
|
-
"access": "public",
|
|
50
|
-
"registry": "https://registry.npmjs.org/"
|
|
51
|
-
}
|
|
52
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "maactl",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "MaaFramework / ProjectInterface v2 command-line client, runnable with npx on Windows",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"maactl",
|
|
7
|
+
"maafw",
|
|
8
|
+
"maaframework",
|
|
9
|
+
"projectinterface",
|
|
10
|
+
"automation",
|
|
11
|
+
"adb",
|
|
12
|
+
"cli"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"author": "TanyaShue",
|
|
16
|
+
"homepage": "https://github.com/TanyaShue/MaaCtl#readme",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/TanyaShue/MaaCtl.git",
|
|
20
|
+
"directory": "npm"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/TanyaShue/MaaCtl/issues"
|
|
24
|
+
},
|
|
25
|
+
"bin": {
|
|
26
|
+
"maactl": "bin/maactl.js"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"bin/",
|
|
30
|
+
"lib/",
|
|
31
|
+
"scripts/",
|
|
32
|
+
"vendor/",
|
|
33
|
+
"README.md"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"postinstall": "node scripts/install.js",
|
|
37
|
+
"vendor:binary": "node scripts/vendor-binary.js",
|
|
38
|
+
"check:vendor": "node scripts/vendor-binary.js --check",
|
|
39
|
+
"test": "node --test",
|
|
40
|
+
"prepublishOnly": "npm test && npm run check:vendor"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=22"
|
|
44
|
+
},
|
|
45
|
+
"os": [
|
|
46
|
+
"win32"
|
|
47
|
+
],
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public",
|
|
50
|
+
"registry": "https://registry.npmjs.org/"
|
|
51
|
+
}
|
|
52
|
+
}
|
package/scripts/install.js
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
// postinstall: pre-fetch maactl.exe into the user cache.
|
|
5
|
-
//
|
|
6
|
-
// The published tarball already carries vendor/maactl.exe, so this only runs
|
|
7
|
-
// for installs without the bundled executable (git checkouts, `npm pack` from
|
|
8
|
-
// source, custom MAACTL_ASSET builds). A download failure must never break
|
|
9
|
-
// `npm install`: the shim retries lazily on first use. Set
|
|
10
|
-
// MAACTL_STRICT_INSTALL=1 to turn the warning into an error.
|
|
11
|
-
|
|
12
|
-
const { ensureBinary, resolveBinary, bundledExePath } = require('../lib/binary');
|
|
13
|
-
const env = require('../lib/env');
|
|
14
|
-
const messages = require('../lib/messages');
|
|
15
|
-
|
|
16
|
-
function write(line) {
|
|
17
|
-
process.stderr.write(`${line}\n`);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async function install() {
|
|
21
|
-
if (env.flag('MAACTL_SKIP_DOWNLOAD')) {
|
|
22
|
-
write(messages.text('skippingDownload'));
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// resolveBinary() may throw when MAACTL_BINARY is set to a missing path, and
|
|
27
|
-
// that is a configuration error the user should see right away.
|
|
28
|
-
if (resolveBinary()) {
|
|
29
|
-
return; // bundled or cached executable is already in place
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
write(messages.text('bundledMissing', bundledExePath()));
|
|
34
|
-
await ensureBinary({ write, quiet: false });
|
|
35
|
-
} catch (error) {
|
|
36
|
-
const strict = env.flag('MAACTL_STRICT_INSTALL');
|
|
37
|
-
if (strict) {
|
|
38
|
-
throw error;
|
|
39
|
-
}
|
|
40
|
-
write(messages.text('preDownloadFailed', error.message));
|
|
41
|
-
write(messages.text('preDownloadHint'));
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
install().catch((error) => {
|
|
46
|
-
write(`maactl: install step failed: ${error.message}`);
|
|
47
|
-
process.exitCode = 1;
|
|
48
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// postinstall: pre-fetch maactl.exe into the user cache.
|
|
5
|
+
//
|
|
6
|
+
// The published tarball already carries vendor/maactl.exe, so this only runs
|
|
7
|
+
// for installs without the bundled executable (git checkouts, `npm pack` from
|
|
8
|
+
// source, custom MAACTL_ASSET builds). A download failure must never break
|
|
9
|
+
// `npm install`: the shim retries lazily on first use. Set
|
|
10
|
+
// MAACTL_STRICT_INSTALL=1 to turn the warning into an error.
|
|
11
|
+
|
|
12
|
+
const { ensureBinary, resolveBinary, bundledExePath } = require('../lib/binary');
|
|
13
|
+
const env = require('../lib/env');
|
|
14
|
+
const messages = require('../lib/messages');
|
|
15
|
+
|
|
16
|
+
function write(line) {
|
|
17
|
+
process.stderr.write(`${line}\n`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function install() {
|
|
21
|
+
if (env.flag('MAACTL_SKIP_DOWNLOAD')) {
|
|
22
|
+
write(messages.text('skippingDownload'));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// resolveBinary() may throw when MAACTL_BINARY is set to a missing path, and
|
|
27
|
+
// that is a configuration error the user should see right away.
|
|
28
|
+
if (resolveBinary()) {
|
|
29
|
+
return; // bundled or cached executable is already in place
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
write(messages.text('bundledMissing', bundledExePath()));
|
|
34
|
+
await ensureBinary({ write, quiet: false });
|
|
35
|
+
} catch (error) {
|
|
36
|
+
const strict = env.flag('MAACTL_STRICT_INSTALL');
|
|
37
|
+
if (strict) {
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
write(messages.text('preDownloadFailed', error.message));
|
|
41
|
+
write(messages.text('preDownloadHint'));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
install().catch((error) => {
|
|
46
|
+
write(`maactl: install step failed: ${error.message}`);
|
|
47
|
+
process.exitCode = 1;
|
|
48
|
+
});
|
package/scripts/vendor-binary.js
CHANGED
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
// Copy a locally built maactl.exe into vendor/ so `npm pack` / `npm publish`
|
|
5
|
-
// produce a tarball that needs no download at install time.
|
|
6
|
-
//
|
|
7
|
-
// The release workflow calls this with the exe it just built; developers can
|
|
8
|
-
// call it with the exe from `go build` to test the packaging flow offline.
|
|
9
|
-
//
|
|
10
|
-
// node scripts/vendor-binary.js [path-to-exe] # default: ../maactl.exe
|
|
11
|
-
// node scripts/vendor-binary.js --list # show the current state
|
|
12
|
-
|
|
13
|
-
const fs = require('node:fs');
|
|
14
|
-
const path = require('node:path');
|
|
15
|
-
|
|
16
|
-
const { bundledExePath, verifyBinary, EXE_NAME } = require('../lib/binary');
|
|
17
|
-
const { formatBytes } = require('../lib/download');
|
|
18
|
-
|
|
19
|
-
const ROOT = path.resolve(__dirname, '..');
|
|
20
|
-
|
|
21
|
-
function usage() {
|
|
22
|
-
process.stderr.write(
|
|
23
|
-
[
|
|
24
|
-
`usage: node scripts/vendor-binary.js [<maactl.exe>] [--check]`,
|
|
25
|
-
'',
|
|
26
|
-
`Copies <maactl.exe> (default ${path.join(ROOT, '..', EXE_NAME)}) to ${bundledExePath()}.`,
|
|
27
|
-
'Use --check to verify the vendored executable without copying anything.',
|
|
28
|
-
'',
|
|
29
|
-
].join('\n'),
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function main(argv) {
|
|
34
|
-
const args = argv.filter((arg) => !arg.startsWith('--'));
|
|
35
|
-
const check = argv.includes('--check');
|
|
36
|
-
const source = path.resolve(args[0] || path.join(ROOT, '..', EXE_NAME));
|
|
37
|
-
const dest = bundledExePath();
|
|
38
|
-
|
|
39
|
-
if (argv.includes('--help') || argv.includes('-h')) {
|
|
40
|
-
usage();
|
|
41
|
-
return 0;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (!check) {
|
|
45
|
-
if (!fs.existsSync(source)) {
|
|
46
|
-
throw new Error(`source executable not found: ${source}\nbuild it first: go build -tags bundled -o maactl.exe ./cmd/maactl`);
|
|
47
|
-
}
|
|
48
|
-
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
49
|
-
fs.copyFileSync(source, dest);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (!fs.existsSync(dest)) {
|
|
53
|
-
throw new Error(`no vendored executable at ${dest}`);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const version = verifyBinary(dest);
|
|
57
|
-
const size = formatBytes(fs.statSync(dest).size);
|
|
58
|
-
process.stdout.write(`vendored ${dest}\n ${size}\n ${version}\n`);
|
|
59
|
-
return 0;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
process.exitCode = main(process.argv.slice(2));
|
|
64
|
-
} catch (error) {
|
|
65
|
-
process.stderr.write(`vendor-binary: ${error.message}\n`);
|
|
66
|
-
process.exitCode = 1;
|
|
67
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// Copy a locally built maactl.exe into vendor/ so `npm pack` / `npm publish`
|
|
5
|
+
// produce a tarball that needs no download at install time.
|
|
6
|
+
//
|
|
7
|
+
// The release workflow calls this with the exe it just built; developers can
|
|
8
|
+
// call it with the exe from `go build` to test the packaging flow offline.
|
|
9
|
+
//
|
|
10
|
+
// node scripts/vendor-binary.js [path-to-exe] # default: ../maactl.exe
|
|
11
|
+
// node scripts/vendor-binary.js --list # show the current state
|
|
12
|
+
|
|
13
|
+
const fs = require('node:fs');
|
|
14
|
+
const path = require('node:path');
|
|
15
|
+
|
|
16
|
+
const { bundledExePath, verifyBinary, EXE_NAME } = require('../lib/binary');
|
|
17
|
+
const { formatBytes } = require('../lib/download');
|
|
18
|
+
|
|
19
|
+
const ROOT = path.resolve(__dirname, '..');
|
|
20
|
+
|
|
21
|
+
function usage() {
|
|
22
|
+
process.stderr.write(
|
|
23
|
+
[
|
|
24
|
+
`usage: node scripts/vendor-binary.js [<maactl.exe>] [--check]`,
|
|
25
|
+
'',
|
|
26
|
+
`Copies <maactl.exe> (default ${path.join(ROOT, '..', EXE_NAME)}) to ${bundledExePath()}.`,
|
|
27
|
+
'Use --check to verify the vendored executable without copying anything.',
|
|
28
|
+
'',
|
|
29
|
+
].join('\n'),
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function main(argv) {
|
|
34
|
+
const args = argv.filter((arg) => !arg.startsWith('--'));
|
|
35
|
+
const check = argv.includes('--check');
|
|
36
|
+
const source = path.resolve(args[0] || path.join(ROOT, '..', EXE_NAME));
|
|
37
|
+
const dest = bundledExePath();
|
|
38
|
+
|
|
39
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
40
|
+
usage();
|
|
41
|
+
return 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!check) {
|
|
45
|
+
if (!fs.existsSync(source)) {
|
|
46
|
+
throw new Error(`source executable not found: ${source}\nbuild it first: go build -tags bundled -o maactl.exe ./cmd/maactl`);
|
|
47
|
+
}
|
|
48
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
49
|
+
fs.copyFileSync(source, dest);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!fs.existsSync(dest)) {
|
|
53
|
+
throw new Error(`no vendored executable at ${dest}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const version = verifyBinary(dest);
|
|
57
|
+
const size = formatBytes(fs.statSync(dest).size);
|
|
58
|
+
process.stdout.write(`vendored ${dest}\n ${size}\n ${version}\n`);
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
process.exitCode = main(process.argv.slice(2));
|
|
64
|
+
} catch (error) {
|
|
65
|
+
process.stderr.write(`vendor-binary: ${error.message}\n`);
|
|
66
|
+
process.exitCode = 1;
|
|
67
|
+
}
|
package/vendor/maactl.exe
CHANGED
|
Binary file
|