Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
27 changes: 17 additions & 10 deletions ios/app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ import {

const SUPPORTED_PLATFORMS = ["ios", "macos", "visionos"];

/**
* @param {string} platform
* @returns {asserts platform is ApplePlatform}
*/
function assertSupportedPlatform(platform) {
if (!SUPPORTED_PLATFORMS.includes(platform)) {
throw new Error(`Unsupported platform: ${platform}`);
}
}

/**
* @param {string} projectRoot
* @param {string} destination
Expand Down Expand Up @@ -99,7 +109,7 @@ function readPackageVersion(p, fs = nodefs) {

/**
* @param {string} projectRoot
* @param {ApplePlatform} targetPlatform
* @param {string} targetPlatform
* @param {JSONObject} options
* @returns {ProjectConfiguration}
*/
Expand All @@ -109,9 +119,7 @@ export function generateProject(
options,
fs = nodefs
) {
if (!SUPPORTED_PLATFORMS.includes(targetPlatform)) {
throw new Error(`Unsupported platform: ${targetPlatform}`);
}
assertSupportedPlatform(targetPlatform);

const appConfig = loadAppConfig(projectRoot, fs);

Expand All @@ -134,7 +142,8 @@ export function generateProject(
// Link source files
const srcDirs = ["ReactTestApp", "ReactTestAppTests", "ReactTestAppUITests"];
for (const file of srcDirs) {
fs.linkSync(projectPath(file, targetPlatform), destination);
const symlink = path.join(destination, file);
fs.linkSync(projectPath(file, targetPlatform), symlink);
}

// Shared code lives in `ios/ReactTestApp/`
Expand Down Expand Up @@ -168,8 +177,8 @@ export function generateProject(

/** @type {ProjectConfiguration} */
const project = {
xcodeprojPath: xcodeprojDst,
reactNativePath,
xcodeprojPath: path.resolve(xcodeprojDst),
reactNativePath: path.resolve(reactNativePath),
reactNativeVersion,
useNewArch,
useBridgeless,
Expand All @@ -178,9 +187,7 @@ export function generateProject(
uitestsBuildSettings: {},
};

if (isObject(platformConfig)) {
applyBuildSettings(platformConfig, project, projectRoot, destination, fs);
}
applyBuildSettings(platformConfig, project, projectRoot, destination, fs);

const overrides = options["buildSettingOverrides"];
if (isObject(overrides)) {
Expand Down
2 changes: 1 addition & 1 deletion ios/assetsCatalog.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export function generateAssetsCatalogs(
const xcassets_dst = path.join(destination, path.basename(xcassets_src));

rm_r(xcassets_dst, fs);
cp_r(xcassets_src, xcassets_dst, fs);
cp_r(xcassets_src, destination, fs);

const platformConfig = appConfig[targetPlatform];
if (!isObject(platformConfig)) {
Expand Down
2 changes: 1 addition & 1 deletion ios/utils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export function plistFromJSON(source, filename) {
*/
export function projectPath(p, targetPlatform) {
const packageDir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
return path.join(packageDir, targetPlatform, p);
return path.resolve(packageDir, targetPlatform, p);
}

/**
Expand Down
17 changes: 10 additions & 7 deletions ios/xcode.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { isObject, isString } from "./utils.mjs";
* @import {
* ApplePlatform,
* JSONObject,
* JSONValue,
* ProjectConfiguration,
* XmlOptions,
* } from "../scripts/types.js";
Expand All @@ -32,7 +33,7 @@ export const USER_HEADER_SEARCH_PATHS = "USER_HEADER_SEARCH_PATHS";
export const WARNING_CFLAGS = "WARNING_CFLAGS";

/**
* @param {JSONObject} platformConfig
* @param {JSONValue} platformConfig
* @param {ProjectConfiguration} project
* @param {string} projectRoot
* @param {string} destination
Expand All @@ -45,7 +46,9 @@ export function applyBuildSettings(
destination,
fs = nodefs
) {
const codeSignEntitlements = platformConfig["codeSignEntitlements"];
const config = isObject(platformConfig) ? platformConfig : {};

const codeSignEntitlements = config["codeSignEntitlements"];
if (isString(codeSignEntitlements)) {
const appManifest = findFile("app.json", projectRoot, fs);
if (!appManifest) {
Expand All @@ -58,19 +61,19 @@ export function applyBuildSettings(
project.buildSettings[CODE_SIGN_ENTITLEMENTS] = relPath;
}

const codeSignIdentity = platformConfig["codeSignIdentity"];
const codeSignIdentity = config["codeSignIdentity"];
if (isString(codeSignIdentity)) {
project.buildSettings[CODE_SIGN_IDENTITY] = codeSignIdentity;
}

const developmentTeam = platformConfig["developmentTeam"];
const developmentTeam = config["developmentTeam"];
if (isString(developmentTeam)) {
project.buildSettings[DEVELOPMENT_TEAM] = developmentTeam;
project.testsBuildSettings[DEVELOPMENT_TEAM] = developmentTeam;
project.uitestsBuildSettings[DEVELOPMENT_TEAM] = developmentTeam;
}

const bundleIdentifier = platformConfig["bundleIdentifier"];
const bundleIdentifier = config["bundleIdentifier"];
if (isString(bundleIdentifier)) {
project.buildSettings[PRODUCT_BUNDLE_IDENTIFIER] = bundleIdentifier;
project.testsBuildSettings[PRODUCT_BUNDLE_IDENTIFIER] =
Expand All @@ -79,7 +82,7 @@ export function applyBuildSettings(
`${bundleIdentifier}UITests`;
}

const buildNumber = platformConfig["buildNumber"];
const buildNumber = config["buildNumber"];
project.buildSettings[PRODUCT_BUILD_NUMBER] =
buildNumber && isString(buildNumber) ? buildNumber : "1";

Expand Down Expand Up @@ -161,7 +164,7 @@ export function applyUserHeaderSearchPaths({ buildSettings }, destination) {
const existingPaths = buildSettings[USER_HEADER_SEARCH_PATHS];
const searchPaths = Array.isArray(existingPaths) ? existingPaths : [];

searchPaths.push(path.dirname(destination));
searchPaths.push(path.resolve(path.dirname(destination)));

buildSettings[USER_HEADER_SEARCH_PATHS] = searchPaths;
}
Expand Down
14 changes: 6 additions & 8 deletions scripts/appConfig.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,17 @@ import { findFile, readJSONFile } from "./helpers.js";

const SOURCE_KEY = Symbol.for("source");

/** @type {JSONObject} */
let appConfig;

/**
* @param {string} projectRoot
* @returns {JSONObject}
*/
export function loadAppConfig(projectRoot, fs = nodefs) {
if (!appConfig) {
const configFile = findFile("app.json", projectRoot, fs);
appConfig = configFile ? readJSONFile(configFile) : {};
appConfig[SOURCE_KEY] = configFile || projectRoot;
}
const configFile = findFile("app.json", projectRoot, fs);

/** @type {JSONObject} */
const appConfig = configFile ? readJSONFile(configFile, fs) : {};
appConfig[SOURCE_KEY] = configFile || projectRoot;

return appConfig;
}

Expand Down
40 changes: 38 additions & 2 deletions test/fs.mock.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,47 @@
/* node:coverage disable */
import type { DirectoryJSON } from "memfs";
import { fs as memfs, vol } from "memfs";
import * as path from "node:path";
import { mkdir_p } from "../scripts/utils/filesystem.mjs";

export const fs = memfs as unknown as typeof import("node:fs");

// Stub `cpSync` until memfs implements it
fs.cpSync = fs.cpSync ?? (() => undefined);
// Add simple `cpSync` implementation until memfs implements it
fs.cpSync =
fs.cpSync ??
((src: string, dst: string, options) => {
const srcStat = fs.statSync(src);
const dstStat = fs.statSync(dst);
if (!srcStat.isDirectory()) {
const finalDst = dstStat.isDirectory()
? path.join(dst, path.basename(src))
: dst;
return fs.copyFileSync(src, finalDst);
}

let finalDst: string;
if (!dstStat.isDirectory()) {
fs.rmSync(dst);
finalDst = dst;
} else {
finalDst = path.join(dst, path.basename(src));
}

mkdir_p(finalDst, fs);
for (const filename of fs.readdirSync(src)) {
const p = path.join(src, filename);
const pStat = fs.statSync(p);
if (pStat.isDirectory()) {
if (options?.recursive) {
fs.cpSync(p, finalDst, options);
} else {
mkdir_p(path.join(finalDst, filename));
}
} else {
fs.copyFileSync(p, path.join(finalDst, filename));
}
}
});

export function setMockFiles(files: DirectoryJSON = {}) {
vol.reset();
Expand Down
Loading
Loading