Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions packages/react-native/scripts/__tests__/replace-hermes-version-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @noflow
*/

'use strict';

const {execFileSync} = require('node:child_process');
const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');

const SCRIPT =
require.resolve('../../sdks/hermes-engine/utils/replace_hermes_version.js');
const VERSION = '0.0.0-test';
const BINARY =
'destroot/Library/Frameworks/universal/hermesvm.xcframework/ios-arm64/hermesvm.framework/hermesvm';

function writeFile(filePath, contents) {
fs.mkdirSync(path.dirname(filePath), {recursive: true});
fs.writeFileSync(filePath, contents);
}

describe('Hermes configuration replacement', () => {
let podsRoot;
let binary;
let marker;

beforeEach(() => {
podsRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'hermes-config-test-'));
binary = path.join(podsRoot, 'hermes-engine', BINARY);
marker = path.join(podsRoot, 'hermes-engine/.last_build_configuration');
});

afterEach(() => {
fs.rmSync(podsRoot, {recursive: true, force: true});
});

function buildTarball(configuration) {
const stage = path.join(podsRoot, 'stage');
writeFile(path.join(stage, BINARY), configuration);
const artifacts = path.join(podsRoot, 'hermes-engine-artifacts');
fs.mkdirSync(artifacts, {recursive: true});
execFileSync('tar', [
'-czf',
path.join(
artifacts,
`hermes-ios-${VERSION}-${configuration.toLowerCase()}.tar.gz`,
),
'-C',
stage,
'.',
]);
}

function runScript(configuration) {
// Match the podspec's build phase: run the CLI from the Pods directory.
execFileSync(
process.execPath,
[SCRIPT, '-c', configuration, '-r', VERSION, '-p', podsRoot],
{cwd: podsRoot, encoding: 'utf8'},
);
}

it.each([
['Debug', 'Release'],
['Release', 'Debug'],
])('restores %s when the marker is missing and %s remains', (target, old) => {
writeFile(binary, old);
buildTarball(target);

runScript(target);

expect(fs.readFileSync(binary, 'utf8')).toBe(target);
expect(fs.readFileSync(marker, 'utf8')).toBe(target);
});

it.each(['Debug', 'Release'])(
'keeps a recorded %s configuration without requiring a tarball',
configuration => {
writeFile(binary, configuration);
writeFile(marker, configuration);

runScript(configuration);

expect(fs.readFileSync(binary, 'utf8')).toBe(configuration);
expect(fs.readFileSync(marker, 'utf8')).toBe(configuration);
},
);

it.each([
['Debug', 'Release'],
['Release', 'Debug'],
])('switches to %s when %s is recorded', (target, old) => {
writeFile(binary, old);
writeFile(marker, old);
buildTarball(target);

runScript(target);

expect(fs.readFileSync(binary, 'utf8')).toBe(target);
expect(fs.readFileSync(marker, 'utf8')).toBe(target);
});

it('records Debug after restoring a fresh install with no marker', () => {
writeFile(binary, 'Debug');
buildTarball('Debug');

runScript('Debug');

expect(fs.readFileSync(binary, 'utf8')).toBe('Debug');
expect(fs.readFileSync(marker, 'utf8')).toBe('Debug');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ Pod::Spec.new do |spec|
if HermesEngineSourceType::isPrebuilt(source_type) then

spec.subspec 'Pre-built' do |ss|
ss.preserve_paths = ["destroot/bin/*"].concat(["**/*.{h,c,cpp}"])
# Keep the configuration marker when CocoaPods cleans an unchanged pod.
ss.preserve_paths = ["destroot/bin/*", ".last_build_configuration"].concat(["**/*.{h,c,cpp}"])
ss.source_files = ["destroot/include/hermes/**/*.h", "destroot/include/jsi/hermes.h"]
ss.header_mappings_dir = "destroot/include"
ss.ios.vendored_frameworks = "destroot/Library/Frameworks/universal/hermesvm.xcframework"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,8 @@ function shouldReplaceHermesConfiguration(configuration) {
}
}

// Assumption: if there is no stored last build, we assume that it was build for debug.
if (!fileExists && configuration === 'Debug') {
console.log(
'No previous build detected, but Debug Configuration. No need to replace Hermes engine',
);
return false;
}

// The binary may outlive its marker, so a missing marker does not imply Debug.
// Restore the requested configuration instead of assuming what is installed.
return true;
}

Expand Down
Loading