@expo-harmony/cli 55.0.26-harmony.8 → 55.0.26-harmony.9
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 +74 -46
- package/build/bin/expo-harmony.js +1 -1
- package/build/buildHap/build.d.ts +3 -10
- package/build/buildHap/build.js +11 -69
- package/build/buildHap/index.d.ts +2 -0
- package/build/buildHap/index.js +19 -0
- package/build/cli.d.ts +3 -3
- package/build/cli.js +21 -187
- package/build/command.d.ts +9 -0
- package/build/command.js +20 -0
- package/build/doctor/doctor.d.ts +1 -1
- package/build/doctor/doctor.js +64 -56
- package/build/doctor/index.d.ts +2 -0
- package/build/doctor/index.js +16 -0
- package/build/exportEmbed/export.d.ts +2 -2
- package/build/exportEmbed/export.js +53 -49
- package/build/exportEmbed/index.d.ts +2 -0
- package/build/exportEmbed/index.js +19 -0
- package/build/file.d.ts +2 -1
- package/build/file.js +18 -8
- package/build/help.d.ts +1 -0
- package/build/help.js +36 -0
- package/build/index.d.ts +5 -3
- package/build/index.js +6 -5
- package/build/internal/prebuild.d.ts +3 -0
- package/build/internal/prebuild.js +9 -0
- package/build/log.d.ts +4 -0
- package/build/log.js +6 -0
- package/build/modules/index.d.ts +2 -0
- package/build/modules/index.js +16 -0
- package/build/native/bare.d.ts +4 -0
- package/build/native/bare.js +130 -0
- package/build/native/build.d.ts +15 -0
- package/build/native/build.js +67 -0
- package/build/{run → native}/cache.d.ts +2 -2
- package/build/{run → native}/cache.js +8 -8
- package/build/native/hvigor.d.ts +2 -0
- package/build/native/hvigor.js +77 -0
- package/build/native/install.d.ts +5 -0
- package/build/native/install.js +13 -0
- package/build/native/prepareProject.d.ts +11 -0
- package/build/native/prepareProject.js +68 -0
- package/build/native/project.d.ts +8 -0
- package/build/native/project.js +58 -0
- package/build/native/toolchain.d.ts +16 -0
- package/build/{tools.js → native/toolchain.js} +1 -57
- package/build/native/types.d.ts +47 -0
- package/build/native/types.js +2 -0
- package/build/prebuild/check.d.ts +7 -3
- package/build/prebuild/check.js +26 -20
- package/build/prebuild/clean.js +5 -5
- package/build/prebuild/index.d.ts +2 -0
- package/build/prebuild/index.js +51 -0
- package/build/prebuild/prebuild.js +11 -3
- package/build/prebuild/template.js +2 -2
- package/build/process.d.ts +11 -1
- package/build/process.js +16 -0
- package/build/profile.d.ts +1 -0
- package/build/profile.js +12 -0
- package/build/projectLock.js +7 -2
- package/build/run/devices.d.ts +1 -1
- package/build/run/devices.js +15 -10
- package/build/run/emulators.d.ts +1 -1
- package/build/run/emulators.js +2 -5
- package/build/run/index.d.ts +2 -0
- package/build/run/index.js +25 -0
- package/build/run/run.d.ts +4 -10
- package/build/run/run.js +45 -90
- package/build/start/index.d.ts +2 -0
- package/build/start/index.js +33 -0
- package/package.json +14 -4
- package/src/bin/expo-harmony.ts +2 -2
- package/src/buildHap/build.ts +13 -105
- package/src/buildHap/index.ts +19 -0
- package/src/cli.ts +24 -227
- package/src/command.ts +24 -0
- package/src/doctor/doctor.ts +63 -61
- package/src/doctor/index.ts +16 -0
- package/src/exportEmbed/export.ts +64 -55
- package/src/exportEmbed/index.ts +17 -0
- package/src/file.ts +20 -11
- package/src/help.ts +33 -0
- package/src/index.ts +5 -3
- package/src/internal/prebuild.ts +3 -0
- package/src/log.ts +5 -0
- package/src/modules/index.ts +16 -0
- package/src/native/bare.ts +145 -0
- package/src/native/build.ts +81 -0
- package/src/{run → native}/cache.ts +10 -9
- package/src/native/hvigor.ts +81 -0
- package/src/native/install.ts +17 -0
- package/src/native/prepareProject.ts +99 -0
- package/src/native/project.ts +88 -0
- package/src/{tools.ts → native/toolchain.ts} +11 -118
- package/src/native/types.ts +44 -0
- package/src/prebuild/check.ts +30 -19
- package/src/prebuild/clean.ts +3 -3
- package/src/prebuild/index.ts +56 -0
- package/src/prebuild/prebuild.ts +11 -1
- package/src/prebuild/template.ts +2 -2
- package/src/process.ts +38 -1
- package/src/profile.ts +13 -0
- package/src/projectLock.ts +9 -1
- package/src/run/devices.ts +16 -11
- package/src/run/emulators.ts +4 -6
- package/src/run/index.ts +25 -0
- package/src/run/run.ts +56 -129
- package/src/start/index.ts +31 -0
- package/build/buildHap/common.d.ts +0 -24
- package/build/buildHap/common.js +0 -92
- package/build/run/install.d.ts +0 -7
- package/build/run/install.js +0 -26
- package/build/tools.d.ts +0 -39
- package/src/buildHap/common.ts +0 -145
- package/src/run/install.ts +0 -41
package/build/index.js
CHANGED
|
@@ -7,15 +7,16 @@ var build_1 = require("./buildHap/build");
|
|
|
7
7
|
Object.defineProperty(exports, "buildHarmonyAsync", { enumerable: true, get: function () { return build_1.buildHarmonyAsync; } });
|
|
8
8
|
var export_1 = require("./exportEmbed/export");
|
|
9
9
|
Object.defineProperty(exports, "exportEmbedAsync", { enumerable: true, get: function () { return export_1.exportEmbedAsync; } });
|
|
10
|
-
var
|
|
11
|
-
Object.defineProperty(exports, "resolveHarmonyBuildPlanAsync", { enumerable: true, get: function () { return
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
var project_1 = require("./native/project");
|
|
11
|
+
Object.defineProperty(exports, "resolveHarmonyBuildPlanAsync", { enumerable: true, get: function () { return project_1.resolveHarmonyBuildPlanAsync; } });
|
|
12
|
+
var toolchain_1 = require("./native/toolchain");
|
|
13
|
+
Object.defineProperty(exports, "resolveHarmonyToolchain", { enumerable: true, get: function () { return toolchain_1.resolveHarmonyToolchain; } });
|
|
14
|
+
var install_1 = require("./native/install");
|
|
14
15
|
Object.defineProperty(exports, "installHarmonyDependenciesAsync", { enumerable: true, get: function () { return install_1.installHarmonyDependenciesAsync; } });
|
|
15
16
|
var modules_1 = require("./modules/modules");
|
|
16
17
|
Object.defineProperty(exports, "formatModulesResult", { enumerable: true, get: function () { return modules_1.formatModulesResult; } });
|
|
17
18
|
Object.defineProperty(exports, "runModulesCommandAsync", { enumerable: true, get: function () { return modules_1.runModulesCommandAsync; } });
|
|
18
|
-
var cache_1 = require("./
|
|
19
|
+
var cache_1 = require("./native/cache");
|
|
19
20
|
Object.defineProperty(exports, "commitHarmonyNativeBuildCacheAsync", { enumerable: true, get: function () { return cache_1.commitHarmonyNativeBuildCacheAsync; } });
|
|
20
21
|
Object.defineProperty(exports, "prepareHarmonyNativeBuildCacheAsync", { enumerable: true, get: function () { return cache_1.prepareHarmonyNativeBuildCacheAsync; } });
|
|
21
22
|
var run_1 = require("./run/run");
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withHarmonyProjectLockAsync = exports.assertSafeCleanTarget = exports.withGeneratedProjectAsync = void 0;
|
|
4
|
+
var check_1 = require("../prebuild/check");
|
|
5
|
+
Object.defineProperty(exports, "withGeneratedProjectAsync", { enumerable: true, get: function () { return check_1.withGeneratedProjectAsync; } });
|
|
6
|
+
var clean_1 = require("../prebuild/clean");
|
|
7
|
+
Object.defineProperty(exports, "assertSafeCleanTarget", { enumerable: true, get: function () { return clean_1.assertSafeCleanTarget; } });
|
|
8
|
+
var projectLock_1 = require("../projectLock");
|
|
9
|
+
Object.defineProperty(exports, "withHarmonyProjectLockAsync", { enumerable: true, get: function () { return projectLock_1.withHarmonyProjectLockAsync; } });
|
package/build/log.d.ts
ADDED
package/build/log.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const command_1 = require("../command");
|
|
5
|
+
const options_1 = require("./options");
|
|
6
|
+
const command = async (argv, io) => {
|
|
7
|
+
const args = (0, command_1.parseCommandArgs)(options_1.parseModulesArgs, argv, io);
|
|
8
|
+
if (!args)
|
|
9
|
+
return 0;
|
|
10
|
+
const { projectRoot: root, options } = args;
|
|
11
|
+
const { formatModulesResult, runModulesCommandAsync } = await import('./modules.js');
|
|
12
|
+
const result = await runModulesCommandAsync(root, options);
|
|
13
|
+
io.log(formatModulesResult(result));
|
|
14
|
+
return result.ok ? 0 : 1;
|
|
15
|
+
};
|
|
16
|
+
exports.command = command;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { BareHarmonyBuildPlan } from './types';
|
|
2
|
+
declare function isBareHarmonyProject(root: string): boolean;
|
|
3
|
+
declare function resolveBareHarmonyBuildPlan(root: string, mode: 'debug' | 'release'): BareHarmonyBuildPlan;
|
|
4
|
+
export { isBareHarmonyProject, resolveBareHarmonyBuildPlan };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.isBareHarmonyProject = isBareHarmonyProject;
|
|
7
|
+
exports.resolveBareHarmonyBuildPlan = resolveBareHarmonyBuildPlan;
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const json5_1 = __importDefault(require("json5"));
|
|
11
|
+
const errors_1 = require("../errors");
|
|
12
|
+
function isBareHarmonyProject(root) {
|
|
13
|
+
return node_fs_1.default.existsSync(node_path_1.default.join(root, 'harmony'))
|
|
14
|
+
&& !node_fs_1.default.existsSync(node_path_1.default.join(root, 'harmony/.expo-harmony-template'))
|
|
15
|
+
&& !node_fs_1.default.existsSync(node_path_1.default.join(root, '.expo/harmony/cng-manifest.json'));
|
|
16
|
+
}
|
|
17
|
+
function record(value, field) {
|
|
18
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
19
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_PROJECT', `Native ${field} must be an object.`, { operation: 'resolve-build' });
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function records(value, field) {
|
|
24
|
+
if (!Array.isArray(value)) {
|
|
25
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_PROJECT', `Native ${field} must be an array.`, { operation: 'resolve-build' });
|
|
26
|
+
}
|
|
27
|
+
return value.map(item => record(item, field));
|
|
28
|
+
}
|
|
29
|
+
function readJson(file) {
|
|
30
|
+
try {
|
|
31
|
+
return record(json5_1.default.parse(node_fs_1.default.readFileSync(file, 'utf8')), file);
|
|
32
|
+
}
|
|
33
|
+
catch (cause) {
|
|
34
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_PROJECT', `Cannot read native project file ${file}: ${cause.message}`, { cause, operation: 'resolve-build' });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function identifier(value, field) {
|
|
38
|
+
if (typeof value !== 'string' || !/^[A-Za-z_][A-Za-z0-9_.]*$/.test(value)) {
|
|
39
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_PROJECT', `The native project must specify a valid ${field}.`, { operation: 'resolve-build' });
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
function selectDefault(items, field) {
|
|
44
|
+
if (items.length === 0) {
|
|
45
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_PROJECT', `No ${field} is defined in harmony/build-profile.json5.`, { operation: 'resolve-build' });
|
|
46
|
+
}
|
|
47
|
+
const defaults = items.filter(item => item.name === 'default');
|
|
48
|
+
if (defaults.length === 1)
|
|
49
|
+
return defaults[0];
|
|
50
|
+
if (items.length === 1)
|
|
51
|
+
return items[0];
|
|
52
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_PROJECT', `Multiple ${field} are defined; name the intended default "default" in harmony/build-profile.json5.`, { operation: 'resolve-build' });
|
|
53
|
+
}
|
|
54
|
+
function resolveBareHarmonyBuildPlan(root, mode) {
|
|
55
|
+
const harmony = node_path_1.default.join(root, 'harmony');
|
|
56
|
+
const entry = node_path_1.default.join(harmony, 'entry');
|
|
57
|
+
for (const directory of [harmony, entry]) {
|
|
58
|
+
if (!node_fs_1.default.existsSync(directory)
|
|
59
|
+
|| !node_fs_1.default.lstatSync(directory).isDirectory() || node_fs_1.default.lstatSync(directory).isSymbolicLink()) {
|
|
60
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_PROJECT', `Bare Harmony projects require a regular directory at ${directory}.`, { operation: 'resolve-build' });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const profile = readJson(node_path_1.default.join(harmony, 'build-profile.json5'));
|
|
64
|
+
const app = record(readJson(node_path_1.default.join(harmony, 'AppScope/app.json5')).app, 'app');
|
|
65
|
+
const module = record(readJson(node_path_1.default.join(entry, 'src/main/module.json5')).module, 'module');
|
|
66
|
+
const name = identifier(module.name, 'module.name');
|
|
67
|
+
const registration = records(profile.modules, 'modules').find(item => item.name === name);
|
|
68
|
+
if (!registration || typeof registration.srcPath !== 'string'
|
|
69
|
+
|| node_path_1.default.resolve(harmony, registration.srcPath) !== entry || module.type !== 'entry') {
|
|
70
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_PROJECT', 'Bare Harmony autolinking requires an entry module at harmony/entry, registered in build-profile.json5.', { operation: 'resolve-build' });
|
|
71
|
+
}
|
|
72
|
+
const config = record(profile.app, 'build-profile.app');
|
|
73
|
+
const selected = selectDefault(records(config.products, 'products'), 'products');
|
|
74
|
+
const product = identifier(selected.name, 'product name');
|
|
75
|
+
const targets = records(registration.targets, 'module targets').filter((item) => {
|
|
76
|
+
if (item.applyToProducts === undefined)
|
|
77
|
+
return true;
|
|
78
|
+
if (!Array.isArray(item.applyToProducts) || item.applyToProducts.some(value => typeof value !== 'string')) {
|
|
79
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_PROJECT', 'Native target.applyToProducts must be an array of product names.', { operation: 'resolve-build' });
|
|
80
|
+
}
|
|
81
|
+
return item.applyToProducts.includes(product);
|
|
82
|
+
});
|
|
83
|
+
const target = identifier(selectDefault(targets, 'module targets').name, 'target name');
|
|
84
|
+
const ability = identifier(module.mainElement, 'module.mainElement');
|
|
85
|
+
if (!records(module.abilities, 'abilities').some(item => item.name === ability)) {
|
|
86
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_PROJECT', `Ability ${ability} is missing from module.json5.`, { operation: 'resolve-build' });
|
|
87
|
+
}
|
|
88
|
+
const bundle = identifier(app.bundleName, 'app.bundleName');
|
|
89
|
+
const signed = Boolean(selected.signingConfig);
|
|
90
|
+
if (signed && !records(config.signingConfigs, 'signingConfigs').some(item => item.name === selected.signingConfig)) {
|
|
91
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_PROJECT', `Signing config ${selected.signingConfig} is referenced by the product but is not defined.`, { operation: 'resolve-build' });
|
|
92
|
+
}
|
|
93
|
+
const rawfile = node_path_1.default.join(entry, 'src/main/resources/rawfile');
|
|
94
|
+
const metadata = node_path_1.default.join(root, '.expo/harmony/export');
|
|
95
|
+
return {
|
|
96
|
+
workflow: 'bare',
|
|
97
|
+
abilityName: ability,
|
|
98
|
+
buildMode: mode,
|
|
99
|
+
bundleName: bundle,
|
|
100
|
+
harmonyRoot: harmony,
|
|
101
|
+
moduleName: name,
|
|
102
|
+
moduleRoot: entry,
|
|
103
|
+
productName: product,
|
|
104
|
+
targetName: target,
|
|
105
|
+
expectedHap: node_path_1.default.join(entry, `build/${target}/outputs/${target}/${name}-${target}-${signed ? 'signed' : 'unsigned'}.hap`),
|
|
106
|
+
hvigorArgs: ['--mode', 'module', '-p', `module=${name}@${target}`, '-p', `product=${product}`, '-p', `buildMode=${mode}`, '--no-daemon', 'assembleHap'],
|
|
107
|
+
exportPaths: {
|
|
108
|
+
bundle: node_path_1.default.join(rawfile, 'hermes_bundle.hbc'),
|
|
109
|
+
manifest: node_path_1.default.join(root, '.expo/harmony/export-manifest.json'),
|
|
110
|
+
metadataRoot: metadata,
|
|
111
|
+
rawfileRoot: rawfile,
|
|
112
|
+
sourceMap: node_path_1.default.join(metadata, 'hermes_bundle.hbc.map'),
|
|
113
|
+
},
|
|
114
|
+
nativeCache: {
|
|
115
|
+
invalidationRoots: [node_path_1.default.join(entry, '.cxx'), node_path_1.default.join(entry, 'build')],
|
|
116
|
+
stateFile: node_path_1.default.join(entry, '.cxx/.expo-harmony-native-dependencies.json'),
|
|
117
|
+
},
|
|
118
|
+
nativeInputs: {
|
|
119
|
+
lockfile: node_path_1.default.join(harmony, 'oh-package-lock.json5'),
|
|
120
|
+
manifest: node_path_1.default.join(harmony, 'oh-package.json5'),
|
|
121
|
+
},
|
|
122
|
+
projectFiles: {
|
|
123
|
+
hvigorConfig: node_path_1.default.join(harmony, 'hvigor/hvigor-config.json5'),
|
|
124
|
+
moduleHvigor: node_path_1.default.join(entry, 'hvigorfile.ts'),
|
|
125
|
+
moduleJson: node_path_1.default.join(entry, 'src/main/module.json5'),
|
|
126
|
+
projectBuildProfile: node_path_1.default.join(harmony, 'build-profile.json5'),
|
|
127
|
+
rootHvigor: node_path_1.default.join(harmony, 'hvigorfile.ts'),
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { HarmonyToolchain } from './toolchain';
|
|
2
|
+
import type { HarmonyBuildPlan } from './types';
|
|
3
|
+
import { type Log } from '../log';
|
|
4
|
+
export interface NativeBuildResult {
|
|
5
|
+
export: null | {
|
|
6
|
+
assetCount: number;
|
|
7
|
+
bundleSha256: string;
|
|
8
|
+
sourceMapSha256: string;
|
|
9
|
+
};
|
|
10
|
+
hapPath: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function buildNativeAsync(root: string, plan: HarmonyBuildPlan, tools: HarmonyToolchain, options: {
|
|
13
|
+
io?: Log;
|
|
14
|
+
resetCache?: boolean;
|
|
15
|
+
}, steps: Record<string, number>): Promise<NativeBuildResult>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildNativeAsync = buildNativeAsync;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const cache_1 = require("./cache");
|
|
9
|
+
const install_1 = require("./install");
|
|
10
|
+
const errors_1 = require("../errors");
|
|
11
|
+
const export_1 = require("../exportEmbed/export");
|
|
12
|
+
const file_1 = require("../file");
|
|
13
|
+
const log_1 = require("../log");
|
|
14
|
+
const path_1 = require("../path");
|
|
15
|
+
const process_1 = require("../process");
|
|
16
|
+
const profile_1 = require("../profile");
|
|
17
|
+
async function buildNativeAsync(root, plan, tools, options, steps) {
|
|
18
|
+
let exported = null;
|
|
19
|
+
if (plan.buildMode === 'release') {
|
|
20
|
+
(0, log_1.progress)(options, 'Exporting the release Hermes bundle');
|
|
21
|
+
const manifest = await (0, profile_1.timedAsync)(steps, 'export', () => (0, export_1.exportEmbedAsync)(root, {
|
|
22
|
+
resetCache: options.resetCache,
|
|
23
|
+
skipDoctor: true,
|
|
24
|
+
}));
|
|
25
|
+
exported = {
|
|
26
|
+
assetCount: manifest.assets.length,
|
|
27
|
+
bundleSha256: manifest.bundle.sha256,
|
|
28
|
+
sourceMapSha256: manifest.sourceMap.sha256,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
steps.export = 0;
|
|
33
|
+
}
|
|
34
|
+
(0, log_1.progress)(options, 'Installing Harmony project dependencies');
|
|
35
|
+
await (0, profile_1.timedAsync)(steps, 'ohpm', () => (0, install_1.installHarmonyDependenciesAsync)(plan, tools));
|
|
36
|
+
(0, log_1.progress)(options, 'Checking Harmony native dependency cache');
|
|
37
|
+
const cache = await (0, profile_1.timedAsync)(steps, 'nativeCache', () => (0, cache_1.prepareHarmonyNativeBuildCacheAsync)(root, plan));
|
|
38
|
+
if (cache.changed)
|
|
39
|
+
(0, log_1.progress)(options, 'Invalidated stale Harmony native build objects');
|
|
40
|
+
(0, log_1.progress)(options, `Building the ${plan.buildMode} HAP`);
|
|
41
|
+
await (0, profile_1.timedAsync)(steps, 'build', () => (0, process_1.runCheckedAsync)(tools.hvigor.command, [
|
|
42
|
+
...tools.hvigor.args,
|
|
43
|
+
...plan.hvigorArgs,
|
|
44
|
+
], {
|
|
45
|
+
code: 'ERR_HARMONY_BUILD_FAILED',
|
|
46
|
+
cwd: plan.harmonyRoot,
|
|
47
|
+
env: {
|
|
48
|
+
...process.env,
|
|
49
|
+
EXPO_HARMONY_NODE: process.env.EXPO_HARMONY_NODE || process.execPath,
|
|
50
|
+
EXPO_METRO_TARGET: 'harmony',
|
|
51
|
+
HERMES_V1_ENABLED: 'true',
|
|
52
|
+
...(plan.workflow === 'bare' ? { EXPO_HARMONY_NATIVE_PREPARED: '1' } : {}),
|
|
53
|
+
...(plan.buildMode === 'release' ? { EXPO_HARMONY_BUNDLE_PREBUILT: '1' } : {}),
|
|
54
|
+
...(tools.sdkHome && !process.env.DEVECO_SDK_HOME
|
|
55
|
+
? { DEVECO_SDK_HOME: tools.sdkHome }
|
|
56
|
+
: {}),
|
|
57
|
+
},
|
|
58
|
+
message: 'Hvigor build',
|
|
59
|
+
operation: 'hvigor-build',
|
|
60
|
+
timeoutMs: 15 * 60_000,
|
|
61
|
+
}));
|
|
62
|
+
if (!(0, file_1.isNonEmptyRegularFile)(plan.expectedHap)) {
|
|
63
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_HAP_MISSING', 'Hvigor completed without producing the expected non-empty regular HAP.', { operation: 'verify-hap' });
|
|
64
|
+
}
|
|
65
|
+
await (0, profile_1.timedAsync)(steps, 'nativeCacheCommit', () => (0, cache_1.commitHarmonyNativeBuildCacheAsync)(cache));
|
|
66
|
+
return { export: exported, hapPath: (0, path_1.toPosixPath)(node_path_1.default.relative(root, plan.expectedHap)) };
|
|
67
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type HarmonyBuildPlan } from './types';
|
|
2
2
|
export interface HarmonyNativeBuildCacheState {
|
|
3
3
|
artifactCount: number;
|
|
4
4
|
cacheFile: string;
|
|
@@ -6,6 +6,6 @@ export interface HarmonyNativeBuildCacheState {
|
|
|
6
6
|
fingerprint: string;
|
|
7
7
|
fingerprintVersion: number;
|
|
8
8
|
}
|
|
9
|
-
declare function prepareHarmonyNativeBuildCacheAsync(
|
|
9
|
+
declare function prepareHarmonyNativeBuildCacheAsync(root: string, plan: HarmonyBuildPlan): Promise<HarmonyNativeBuildCacheState>;
|
|
10
10
|
declare function commitHarmonyNativeBuildCacheAsync(state: HarmonyNativeBuildCacheState): Promise<void>;
|
|
11
11
|
export { commitHarmonyNativeBuildCacheAsync, prepareHarmonyNativeBuildCacheAsync, };
|
|
@@ -7,9 +7,9 @@ exports.commitHarmonyNativeBuildCacheAsync = commitHarmonyNativeBuildCacheAsync;
|
|
|
7
7
|
exports.prepareHarmonyNativeBuildCacheAsync = prepareHarmonyNativeBuildCacheAsync;
|
|
8
8
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
9
|
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
-
const native_inputs_1 = require("@expo-harmony/config-plugins/native-inputs");
|
|
10
|
+
const native_inputs_1 = require("@expo-harmony/config-plugins/internal/native-inputs");
|
|
11
11
|
const errors_1 = require("../errors");
|
|
12
|
-
const
|
|
12
|
+
const SchemaVersion = 1;
|
|
13
13
|
async function readOptionalFile(file) {
|
|
14
14
|
try {
|
|
15
15
|
return await node_fs_1.default.promises.readFile(file);
|
|
@@ -20,20 +20,20 @@ async function readOptionalFile(file) {
|
|
|
20
20
|
throw new errors_1.HarmonyCliError(error.code || 'ERR_HARMONY_NATIVE_CACHE', error.message || `Cannot read a Harmony native cache input: ${file}`, { cause: error, exitCode: error.exitCode, operation: error.operation });
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
async function resolveNativeDependencyFingerprintAsync(
|
|
23
|
+
async function resolveNativeDependencyFingerprintAsync(root, plan) {
|
|
24
24
|
try {
|
|
25
25
|
return (0, native_inputs_1.fingerprintHarmonyNativeInputsSync)({
|
|
26
26
|
lockfile: plan.nativeInputs.lockfile,
|
|
27
27
|
manifest: plan.nativeInputs.manifest,
|
|
28
|
-
projectRoot,
|
|
28
|
+
projectRoot: root,
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
catch (cause) {
|
|
32
32
|
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_CACHE', `Cannot fingerprint generated Harmony native dependencies: ${cause.message}`, { cause, operation: 'native-cache' });
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
async function prepareHarmonyNativeBuildCacheAsync(
|
|
36
|
-
const current = await resolveNativeDependencyFingerprintAsync(
|
|
35
|
+
async function prepareHarmonyNativeBuildCacheAsync(root, plan) {
|
|
36
|
+
const current = await resolveNativeDependencyFingerprintAsync(root, plan);
|
|
37
37
|
const file = plan.nativeCache.stateFile;
|
|
38
38
|
const source = await readOptionalFile(file);
|
|
39
39
|
let saved = null;
|
|
@@ -45,7 +45,7 @@ async function prepareHarmonyNativeBuildCacheAsync(projectRoot, plan) {
|
|
|
45
45
|
saved = null;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
-
const changed = saved?.schemaVersion !==
|
|
48
|
+
const changed = saved?.schemaVersion !== SchemaVersion
|
|
49
49
|
|| saved?.fingerprintVersion !== native_inputs_1.HarmonyNativeInputsFingerprintVersion
|
|
50
50
|
|| saved?.fingerprint !== current.fingerprint;
|
|
51
51
|
if (changed) {
|
|
@@ -67,7 +67,7 @@ async function commitHarmonyNativeBuildCacheAsync(state) {
|
|
|
67
67
|
artifactCount: state.artifactCount,
|
|
68
68
|
fingerprint: state.fingerprint,
|
|
69
69
|
fingerprintVersion: state.fingerprintVersion,
|
|
70
|
-
schemaVersion:
|
|
70
|
+
schemaVersion: SchemaVersion,
|
|
71
71
|
}, null, 2)}\n`);
|
|
72
72
|
await node_fs_1.default.promises.rename(temp, state.cacheFile);
|
|
73
73
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.prepareHarmonyNativeBuild = prepareHarmonyNativeBuild;
|
|
7
|
+
exports.bundleHarmonyNativeBuild = bundleHarmonyNativeBuild;
|
|
8
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
9
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
10
|
+
const node_module_1 = require("node:module");
|
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const node_child_process_1 = require("node:child_process");
|
|
13
|
+
const native_inputs_1 = require("@expo-harmony/config-plugins/internal/native-inputs");
|
|
14
|
+
const errors_1 = require("../errors");
|
|
15
|
+
const toolchain_1 = require("./toolchain");
|
|
16
|
+
function nodeExecutable() {
|
|
17
|
+
const candidates = process.env.EXPO_HARMONY_NODE
|
|
18
|
+
? [process.env.EXPO_HARMONY_NODE]
|
|
19
|
+
: [
|
|
20
|
+
process.execPath,
|
|
21
|
+
...(process.env.PATH || '').split(node_path_1.default.delimiter).filter(Boolean)
|
|
22
|
+
.map(directory => node_path_1.default.join(directory, process.platform === 'win32' ? 'node.exe' : 'node')),
|
|
23
|
+
];
|
|
24
|
+
for (const candidate of new Set(candidates)) {
|
|
25
|
+
const result = (0, node_child_process_1.spawnSync)(candidate, ['-p', 'process.versions.node'], { encoding: 'utf8', timeout: 5_000 });
|
|
26
|
+
if (result.status === 0 && Number.parseInt(result.stdout, 10) >= 20)
|
|
27
|
+
return candidate;
|
|
28
|
+
}
|
|
29
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NODE', 'Harmony native builds require Node.js 20 or newer. Set EXPO_HARMONY_NODE to its executable.', { operation: 'native-build' });
|
|
30
|
+
}
|
|
31
|
+
function run(command, args, cwd) {
|
|
32
|
+
const result = (0, node_child_process_1.spawnSync)(command, args, {
|
|
33
|
+
cwd,
|
|
34
|
+
env: { ...(0, toolchain_1.createHarmonyToolchainEnv)(), EXPO_HARMONY: '1', EXPO_METRO_TARGET: 'harmony', HERMES_V1_ENABLED: 'true' },
|
|
35
|
+
stdio: 'inherit',
|
|
36
|
+
timeout: 10 * 60_000,
|
|
37
|
+
});
|
|
38
|
+
if (result.error || result.status !== 0) {
|
|
39
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_NATIVE_BUILD', `Harmony build command failed: ${command} (${result.error?.message || result.status}).`, { cause: result.error, exitCode: result.status || 1, operation: 'native-build' });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Hvigor configuration is synchronous; linking must finish before task execution.
|
|
43
|
+
function prepareHarmonyNativeBuild(root, mode) {
|
|
44
|
+
const harmony = node_path_1.default.join(root, 'harmony');
|
|
45
|
+
if (process.env.EXPO_HARMONY_NATIVE_PREPARED !== '1') {
|
|
46
|
+
const require = (0, node_module_1.createRequire)(node_path_1.default.join(root, 'package.json'));
|
|
47
|
+
const manifest = node_path_1.default.resolve(node_path_1.default.dirname(require.resolve('@expo-harmony/expo-modules-autolinking')), '../package.json');
|
|
48
|
+
const bin = node_path_1.default.resolve(node_path_1.default.dirname(manifest), require(manifest).bin['expo-harmony-autolinking']);
|
|
49
|
+
run(nodeExecutable(), [bin, 'link', '--project-root', root, '--harmony-project-path', harmony, '--build-type', mode], root);
|
|
50
|
+
const { ohpm } = (0, toolchain_1.resolveHarmonyToolchain)();
|
|
51
|
+
run(ohpm.command, [...ohpm.args, 'install', '--all'], harmony);
|
|
52
|
+
}
|
|
53
|
+
const { fingerprint } = (0, native_inputs_1.fingerprintHarmonyNativeInputsSync)({
|
|
54
|
+
projectRoot: root,
|
|
55
|
+
manifest: node_path_1.default.join(harmony, 'oh-package.json5'),
|
|
56
|
+
lockfile: node_path_1.default.join(harmony, 'oh-package-lock.json5'),
|
|
57
|
+
});
|
|
58
|
+
const file = node_path_1.default.join(harmony, '.hvigor/expo-harmony/native-inputs.cmake');
|
|
59
|
+
const content = `# Generated native dependency fingerprint.\nadd_compile_definitions(EXPO_HARMONY_NATIVE_INPUTS_SHA256_${fingerprint}=1)\n`;
|
|
60
|
+
if (node_fs_1.default.existsSync(file) && node_fs_1.default.readFileSync(file, 'utf8') === content)
|
|
61
|
+
return;
|
|
62
|
+
node_fs_1.default.mkdirSync(node_path_1.default.dirname(file), { recursive: true });
|
|
63
|
+
const temp = `${file}.${node_crypto_1.default.randomUUID()}.tmp`;
|
|
64
|
+
try {
|
|
65
|
+
node_fs_1.default.writeFileSync(temp, content);
|
|
66
|
+
node_fs_1.default.renameSync(temp, file);
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
node_fs_1.default.rmSync(temp, { force: true });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function bundleHarmonyNativeBuild(root) {
|
|
73
|
+
if (process.env.EXPO_HARMONY_BUNDLE_PREBUILT === '1')
|
|
74
|
+
return;
|
|
75
|
+
const require = (0, node_module_1.createRequire)(node_path_1.default.join(root, 'package.json'));
|
|
76
|
+
run(nodeExecutable(), [require.resolve('@expo-harmony/cli/bin/expo-harmony'), 'export:embed', root], root);
|
|
77
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { HarmonyBuildPlan } from './types';
|
|
2
|
+
import type { HarmonyToolchain } from './toolchain';
|
|
3
|
+
export declare function installHarmonyDependenciesAsync(plan: Pick<HarmonyBuildPlan, 'harmonyRoot'>, tools: HarmonyToolchain, options?: {
|
|
4
|
+
timeoutMs?: number;
|
|
5
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.installHarmonyDependenciesAsync = installHarmonyDependenciesAsync;
|
|
4
|
+
const process_1 = require("../process");
|
|
5
|
+
async function installHarmonyDependenciesAsync(plan, tools, options = {}) {
|
|
6
|
+
await (0, process_1.runCheckedAsync)(tools.ohpm.command, [...tools.ohpm.args, 'install', '--all'], {
|
|
7
|
+
code: 'ERR_HARMONY_OHPM_FAILED',
|
|
8
|
+
cwd: plan.harmonyRoot,
|
|
9
|
+
message: 'OHPM install',
|
|
10
|
+
operation: 'ohpm-install',
|
|
11
|
+
timeoutMs: options.timeoutMs || 5 * 60_000,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Log } from '../log';
|
|
2
|
+
import type { HarmonyBuildPlan } from './types';
|
|
3
|
+
interface PrepareProjectOptions {
|
|
4
|
+
io?: Log;
|
|
5
|
+
requireDeviceTools?: boolean;
|
|
6
|
+
check?: boolean;
|
|
7
|
+
sync: boolean;
|
|
8
|
+
variant: 'debug' | 'release';
|
|
9
|
+
}
|
|
10
|
+
declare function prepareNativeProjectAsync(root: string, options: PrepareProjectOptions, steps: Record<string, number>): Promise<HarmonyBuildPlan>;
|
|
11
|
+
export { prepareNativeProjectAsync };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.prepareNativeProjectAsync = prepareNativeProjectAsync;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const expo_modules_autolinking_1 = require("@expo-harmony/expo-modules-autolinking");
|
|
9
|
+
const doctor_1 = require("../doctor/doctor");
|
|
10
|
+
const errors_1 = require("../errors");
|
|
11
|
+
const log_1 = require("../log");
|
|
12
|
+
const profile_1 = require("../profile");
|
|
13
|
+
const check_1 = require("../prebuild/check");
|
|
14
|
+
const prebuild_1 = require("../prebuild/prebuild");
|
|
15
|
+
const toolchain_1 = require("./toolchain");
|
|
16
|
+
const project_1 = require("./project");
|
|
17
|
+
async function prepareNativeProjectAsync(root, options, steps) {
|
|
18
|
+
const plan = await (0, profile_1.timedAsync)(steps, 'buildPlan', () => (0, project_1.resolveHarmonyBuildPlanIfPresentAsync)(root, {
|
|
19
|
+
buildMode: options.variant,
|
|
20
|
+
}));
|
|
21
|
+
const exists = Boolean(plan && node_fs_1.default.existsSync(plan.harmonyRoot));
|
|
22
|
+
if (plan?.workflow === 'bare' && options.sync) {
|
|
23
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_BARE_SYNC', '--sync regenerates CNG projects and cannot be used with a manually maintained bare project.', { operation: 'build' });
|
|
24
|
+
}
|
|
25
|
+
(0, log_1.progress)(options, 'Checking the Harmony project');
|
|
26
|
+
const doctor = await (0, profile_1.timedAsync)(steps, 'doctor', () => (0, doctor_1.doctorAsync)(root, {
|
|
27
|
+
requireBuildTools: true,
|
|
28
|
+
requireDeviceTools: options.requireDeviceTools,
|
|
29
|
+
validateGeneratedProject: exists,
|
|
30
|
+
validateModules: false,
|
|
31
|
+
}));
|
|
32
|
+
if (!doctor.ok) {
|
|
33
|
+
const checks = doctor.checks.filter(check => check.status === 'error').map(check => check.id);
|
|
34
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_DOCTOR_FAILED', `Harmony doctor found blocking checks: ${checks.join(', ') || 'unknown'}.`, { operation: 'doctor' });
|
|
35
|
+
}
|
|
36
|
+
if (plan?.workflow === 'bare') {
|
|
37
|
+
(0, log_1.progress)(options, 'Autolinking the bare Harmony project');
|
|
38
|
+
await (0, profile_1.timedAsync)(steps, 'autolinking', () => (0, expo_modules_autolinking_1.linkModulesAsync)({
|
|
39
|
+
projectRoot: root,
|
|
40
|
+
harmonyProjectPath: plan.harmonyRoot,
|
|
41
|
+
buildType: options.variant,
|
|
42
|
+
env: (0, toolchain_1.createHarmonyToolchainEnv)(),
|
|
43
|
+
}));
|
|
44
|
+
steps.prebuild = 0;
|
|
45
|
+
steps.cngCheck = 0;
|
|
46
|
+
return plan;
|
|
47
|
+
}
|
|
48
|
+
if (!exists || options.sync) {
|
|
49
|
+
(0, log_1.progress)(options, exists
|
|
50
|
+
? 'Synchronizing the generated Harmony project'
|
|
51
|
+
: 'Generating the missing Harmony project');
|
|
52
|
+
await (0, profile_1.timedAsync)(steps, 'prebuild', () => (0, prebuild_1.prebuildParsedAsync)(root, [], { buildType: options.variant }));
|
|
53
|
+
steps.cngCheck = 0;
|
|
54
|
+
return (0, profile_1.timedAsync)(steps, 'buildPlan', () => (0, project_1.resolveHarmonyBuildPlanAsync)(root, { buildMode: options.variant }));
|
|
55
|
+
}
|
|
56
|
+
steps.prebuild = 0;
|
|
57
|
+
if (options.check === false) {
|
|
58
|
+
steps.cngCheck = 0;
|
|
59
|
+
return plan;
|
|
60
|
+
}
|
|
61
|
+
(0, log_1.progress)(options, 'Checking CNG ownership and drift');
|
|
62
|
+
const check = await (0, profile_1.timedAsync)(steps, 'cngCheck', () => (0, check_1.checkAsync)(root, { buildType: options.variant }));
|
|
63
|
+
if (!check.clean) {
|
|
64
|
+
const summary = check.changes.slice(0, 8).map(change => `${change.type}:${change.path}`).join(', ');
|
|
65
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_MANIFEST_DRIFT', `Generated Harmony files differ from CNG desired state${summary ? ` (${summary})` : ''}. Run expo-harmony prebuild or retry with --sync.`, { operation: 'check' });
|
|
66
|
+
}
|
|
67
|
+
return plan;
|
|
68
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { HarmonyBuildPlan } from './types';
|
|
2
|
+
declare function resolveHarmonyBuildPlanIfPresentAsync(root: string, options?: {
|
|
3
|
+
buildMode?: 'debug' | 'release';
|
|
4
|
+
}): Promise<HarmonyBuildPlan | null>;
|
|
5
|
+
declare function resolveHarmonyBuildPlanAsync(root: string, options?: {
|
|
6
|
+
buildMode?: 'debug' | 'release';
|
|
7
|
+
}): Promise<HarmonyBuildPlan>;
|
|
8
|
+
export { resolveHarmonyBuildPlanAsync, resolveHarmonyBuildPlanIfPresentAsync };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveHarmonyBuildPlanAsync = resolveHarmonyBuildPlanAsync;
|
|
4
|
+
exports.resolveHarmonyBuildPlanIfPresentAsync = resolveHarmonyBuildPlanIfPresentAsync;
|
|
5
|
+
const internal_1 = require("@expo-harmony/prebuild-config/internal");
|
|
6
|
+
const errors_1 = require("../errors");
|
|
7
|
+
const bare_1 = require("./bare");
|
|
8
|
+
function createHarmonyBuildPlan(root, build, mode) {
|
|
9
|
+
const resolve = relative => (0, internal_1.resolveHarmonyBuildPath)(root, relative);
|
|
10
|
+
const variant = build.variants[mode];
|
|
11
|
+
return {
|
|
12
|
+
workflow: 'cng',
|
|
13
|
+
abilityName: build.identity.abilityName,
|
|
14
|
+
buildMode: mode,
|
|
15
|
+
bundleName: build.identity.bundleName,
|
|
16
|
+
expectedHap: resolve(variant.expectedHap),
|
|
17
|
+
exportPaths: Object.fromEntries(Object.entries(build.export).map(([name, relative]) => [name, resolve(relative)])),
|
|
18
|
+
harmonyRoot: resolve(build.harmonyRoot),
|
|
19
|
+
hvigorArgs: [...variant.hvigorArgs],
|
|
20
|
+
moduleName: build.identity.moduleName,
|
|
21
|
+
moduleRoot: resolve(build.moduleRoot),
|
|
22
|
+
nativeCache: {
|
|
23
|
+
invalidationRoots: build.nativeCache.invalidationRoots.map(resolve),
|
|
24
|
+
stateFile: resolve(build.nativeCache.stateFile),
|
|
25
|
+
},
|
|
26
|
+
nativeInputs: {
|
|
27
|
+
lockfile: resolve(build.nativeInputs.lockfile),
|
|
28
|
+
manifest: resolve(build.nativeInputs.manifest),
|
|
29
|
+
},
|
|
30
|
+
productName: build.identity.productName,
|
|
31
|
+
projectFiles: Object.fromEntries(Object.entries(build.projectFiles).map(([name, relative]) => [name, resolve(relative)])),
|
|
32
|
+
targetName: build.identity.targetName,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
async function resolveHarmonyBuildPlanIfPresentAsync(root, options = {}) {
|
|
36
|
+
const mode = options.buildMode || 'debug';
|
|
37
|
+
if (!['debug', 'release'].includes(mode)) {
|
|
38
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_CONFIG_INVALID', `Harmony buildMode must be debug or release, received: ${mode}`, { operation: 'resolve-build' });
|
|
39
|
+
}
|
|
40
|
+
let manifest;
|
|
41
|
+
try {
|
|
42
|
+
manifest = await (0, internal_1.readManifestIfPresentAsync)(root);
|
|
43
|
+
}
|
|
44
|
+
catch (cause) {
|
|
45
|
+
throw new errors_1.HarmonyCliError(cause.code || 'ERR_HARMONY_TEMPLATE_INVALID', `Cannot read the generated Harmony build descriptor: ${cause.message}`, { cause, operation: 'resolve-build' });
|
|
46
|
+
}
|
|
47
|
+
if (!manifest) {
|
|
48
|
+
return (0, bare_1.isBareHarmonyProject)(root) ? (0, bare_1.resolveBareHarmonyBuildPlan)(root, mode) : null;
|
|
49
|
+
}
|
|
50
|
+
return createHarmonyBuildPlan(root, manifest.build, mode);
|
|
51
|
+
}
|
|
52
|
+
async function resolveHarmonyBuildPlanAsync(root, options = {}) {
|
|
53
|
+
const plan = await resolveHarmonyBuildPlanIfPresentAsync(root, options);
|
|
54
|
+
if (!plan) {
|
|
55
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_MANIFEST_DRIFT', 'Cannot read the generated Harmony build descriptor because the CNG manifest is missing.', { operation: 'resolve-build' });
|
|
56
|
+
}
|
|
57
|
+
return plan;
|
|
58
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface HarmonyTool {
|
|
2
|
+
args: string[];
|
|
3
|
+
command: string;
|
|
4
|
+
source: 'deveco' | 'override' | 'path';
|
|
5
|
+
}
|
|
6
|
+
export interface HarmonyToolchain {
|
|
7
|
+
hdc: HarmonyTool;
|
|
8
|
+
hvigor: HarmonyTool;
|
|
9
|
+
ohpm: HarmonyTool;
|
|
10
|
+
sdkHome: string | null;
|
|
11
|
+
toolsRoot: string | null;
|
|
12
|
+
}
|
|
13
|
+
declare function resolveHarmonyToolchain(): HarmonyToolchain;
|
|
14
|
+
declare function createHarmonyToolchainEnv(toolchain?: HarmonyToolchain): NodeJS.ProcessEnv;
|
|
15
|
+
declare function resolveHarmonyEmulator(toolchain: HarmonyToolchain): HarmonyTool;
|
|
16
|
+
export { createHarmonyToolchainEnv, resolveHarmonyEmulator, resolveHarmonyToolchain };
|