0bfc5768cc
让Linux no-bundle smoke不再误用Windows随包资源目标。 统一dev与release的Cargo目标和feature解析,补充跨平台回归测试。 同步随包资源staging技术方案中的实际构建目标约定。
135 lines
5.3 KiB
JavaScript
135 lines
5.3 KiB
JavaScript
/** 默认桌面能力;显式 feature 参数优先,不把应用参数当 Cargo 参数。 */
|
||
export function withDefaultCargoFeatures(argv, features) {
|
||
// 只看第一个 `--` 之前的 Tauri 选项:runner 参数区里的 `--features` 会与这里注入的
|
||
// 默认值在 Cargo 侧合并,不能当作「用户已经指定过了」而跳过注入。
|
||
if (!features.length || tauriOptions(argv).some(hasExplicitFeatures)) {
|
||
return argv;
|
||
}
|
||
return [`--features=${features.join(',')}`, ...argv];
|
||
}
|
||
|
||
/// 第一个 `--` 之前是 Tauri 自己的选项,之后是 runner(Cargo)参数。
|
||
function tauriOptions(argv) {
|
||
const separator = argv.indexOf('--');
|
||
return separator < 0 ? argv : argv.slice(0, separator);
|
||
}
|
||
|
||
/**
|
||
* 交给 Tauri 与 Cargo 的参数区间:第一个 `--` 之前是 Tauri 选项,之后到第二个 `--` 是
|
||
* runner(Cargo)参数;第二个 `--` 之后由 Tauri 转交应用,不属于构建参数。
|
||
* dev 入口(`buildTauriArguments` 会把启动器的单个 `--` 补成 runner + 应用两段)与发布
|
||
* 入口都用这一份区间解析,两边的目标与 feature 必须来自同一个口径。
|
||
*/
|
||
function cargoArguments(argv) {
|
||
const separator = argv.indexOf('--');
|
||
if (separator < 0) return argv;
|
||
const applicationStart = argv.indexOf('--', separator + 1);
|
||
return applicationStart < 0 ? argv : argv.slice(0, applicationStart);
|
||
}
|
||
|
||
/// 四种拼写(`--features x` / `--features=x` / `-f x` / `-fx`)都算显式指定。
|
||
function hasExplicitFeatures(value) {
|
||
return (
|
||
value === '--features' ||
|
||
value === '-f' ||
|
||
value.startsWith('--features=') ||
|
||
/^-f.+/u.test(value)
|
||
);
|
||
}
|
||
|
||
function parseFeatureNames(raw) {
|
||
return String(raw)
|
||
.split(',')
|
||
.map((name) => name.trim())
|
||
.filter(Boolean);
|
||
}
|
||
|
||
export function defaultEditorFeatures(target) {
|
||
return target === 'win32' || target.includes('windows')
|
||
? ['cocos-editor-execute', 'unity-editor-execute', 'godot-editor-execute']
|
||
: [];
|
||
}
|
||
|
||
/**
|
||
* 显式 Cargo 目标解析:`--target <triple>` / `--target=<triple>` / `-t <triple>`。
|
||
* 应用参数区(第二个 `--` 之后)不参与解析。未显式指定返回 undefined;取值缺失、
|
||
* 取到另一个选项或重复指定都失败关闭。
|
||
* dev 入口与发布入口共用这一份解析:cargo 的构建目标与随包资源 staging 目标
|
||
* 必须来自同一个显式来源,不能一方读参数、另一方回退宿主默认值。
|
||
*/
|
||
export function readCargoTarget(argv = []) {
|
||
const options = cargoArguments(argv);
|
||
let target;
|
||
for (let index = 0; index < options.length; index += 1) {
|
||
const argument = String(options[index]);
|
||
let value;
|
||
if (argument === '--target' || argument === '-t') {
|
||
value = options[index + 1];
|
||
index += 1;
|
||
} else if (argument.startsWith('--target=')) {
|
||
value = argument.slice('--target='.length);
|
||
} else if (argument.startsWith('-t') && argument.length > 2) {
|
||
value = argument.slice(2).replace(/^=/u, '');
|
||
} else {
|
||
continue;
|
||
}
|
||
if (!value?.trim() || String(value).startsWith('-')) {
|
||
throw new Error('--target 缺少有效目标');
|
||
}
|
||
if (target !== undefined) throw new Error('不能重复指定 --target');
|
||
target = String(value).trim();
|
||
}
|
||
return target;
|
||
}
|
||
|
||
/**
|
||
* 单一声明式解析:本次构建实际生效的编辑器 feature 集。
|
||
* 解析顺序:命令行 `--features`(Cargo 真正收到的参数,不能被环境覆盖)
|
||
* > 环境变量 `AGC_DEV_CARGO_FEATURES`(存在即以它为准,空串即关闭默认 feature)
|
||
* > 目标平台默认值。
|
||
* 传入的必须是「最终交给 Tauri 的参数」:dev 入口与发布入口的 cargo 参数与随包资源
|
||
* 准备步骤都消费这里的返回值,否则会出现「cargo 开了 feature、staging 没开(或反之)」。
|
||
*/
|
||
export function resolveEditorFeatures({
|
||
argv = [],
|
||
target,
|
||
env = process.env,
|
||
} = {}) {
|
||
const fromArgv = featuresFromArgv(argv);
|
||
if (fromArgv) {
|
||
return fromArgv;
|
||
}
|
||
// 变量存在本身即声明「本次 feature 集由环境决定」:空串是有意的关闭,不是未设置。
|
||
if (env.AGC_DEV_CARGO_FEATURES !== undefined) {
|
||
return parseFeatureNames(env.AGC_DEV_CARGO_FEATURES);
|
||
}
|
||
return defaultEditorFeatures(target);
|
||
}
|
||
|
||
/// 汇总 cargo 参数区里出现在任何位置的 `--features` / `-f`(Cargo 会把多个 flag 合并);
|
||
/// 没有任何 feature flag 时返回 null。显式但为空(如 `--features=`)返回空数组。
|
||
export function featuresFromArgv(argv = []) {
|
||
const options = cargoArguments(argv);
|
||
const features = [];
|
||
let found = false;
|
||
for (let index = 0; index < options.length; index += 1) {
|
||
const value = String(options[index]);
|
||
if (value.startsWith('--features=')) {
|
||
found = true;
|
||
features.push(...parseFeatureNames(value.slice('--features='.length)));
|
||
} else if (value === '--features' || value === '-f') {
|
||
found = true;
|
||
index += 1;
|
||
const next = options[index];
|
||
// 变参 flag:后面不是选项时才是它的取值。
|
||
if (next !== undefined && !String(next).startsWith('-')) {
|
||
features.push(...parseFeatureNames(next));
|
||
}
|
||
} else if (value.startsWith('-f') && value.length > 2) {
|
||
found = true;
|
||
features.push(...parseFeatureNames(value.slice(2).replace(/^=/u, '')));
|
||
}
|
||
}
|
||
return found ? features : null;
|
||
}
|