Skip to content
This repository has been archived by the owner on Jan 18, 2024. It is now read-only.

Commit

Permalink
[config] Created paths module for ios (#2784)
Browse files Browse the repository at this point in the history
* Created paths module for ios

* Fix device family bug

* sort paths alphabetically

* Update DeviceFamily.ts
  • Loading branch information
EvanBacon committed Oct 13, 2020
1 parent 2e69621 commit 9e0be1d
Show file tree
Hide file tree
Showing 16 changed files with 455 additions and 113 deletions.
6 changes: 6 additions & 0 deletions packages/config/src/Errors.ts
Expand Up @@ -10,6 +10,12 @@ export class ConfigError extends Error {
}
}

export class UnexpectedError extends Error {
constructor(message: string) {
super(`${message}\nPlease report this as an issue on https://github.com/expo/expo-cli/issues`);
}
}

export function errorFromJSON({ name, ...json }: any): Error {
let error: any;
if (name === 'TypeError') {
Expand Down
23 changes: 18 additions & 5 deletions packages/config/src/Modules.ts
@@ -1,4 +1,4 @@
import { stat, statSync } from 'fs-extra';
import { stat, Stats, statSync } from 'fs-extra';
import { join, resolve } from 'path';
import resolveFrom from 'resolve-from';

Expand Down Expand Up @@ -35,14 +35,27 @@ export function moduleNameFromPath(modulePath: string): string {
return packageName ? packageName : modulePath;
}

export async function fileExistsAsync(file: string): Promise<boolean> {
/**
* A non-failing version of async FS stat.
*
* @param file
*/
async function statAsync(file: string): Promise<Stats | null> {
try {
return (await stat(file)).isFile();
} catch (e) {
return false;
return await stat(file);
} catch {
return null;
}
}

export async function fileExistsAsync(file: string): Promise<boolean> {
return (await statAsync(file))?.isFile() ?? false;
}

export async function directoryExistsAsync(file: string): Promise<boolean> {
return (await statAsync(file))?.isDirectory() ?? false;
}

export function fileExists(file: string): boolean {
try {
return statSync(file).isFile();
Expand Down
22 changes: 1 addition & 21 deletions packages/config/src/android/Paths.ts
Expand Up @@ -2,6 +2,7 @@ import fs from 'fs-extra';
import { sync as globSync } from 'glob';
import * as path from 'path';

import { directoryExistsAsync } from '../Modules';
import { ResourceKind } from './Resources';

export async function getMainActivityAsync(
Expand Down Expand Up @@ -60,24 +61,3 @@ export async function getResourceXMLPathAsync(
const filePath = path.join(projectPath, `app/src/main/res/${kind}/${name}.xml`);
return filePath;
}

/**
* A non-failing version of async FS stat.
*
* @param file
*/
async function statAsync(file: string): Promise<fs.Stats | null> {
try {
return await fs.stat(file);
} catch {
return null;
}
}

export async function fileExistsAsync(file: string): Promise<boolean> {
return (await statAsync(file))?.isFile() ?? false;
}

async function directoryExistsAsync(file: string): Promise<boolean> {
return (await statAsync(file))?.isDirectory() ?? false;
}
3 changes: 2 additions & 1 deletion packages/config/src/android/__tests__/Resources-test.ts
@@ -1,6 +1,7 @@
import { vol } from 'memfs';

import { fileExistsAsync, getResourceXMLPathAsync } from '../Paths';
import { fileExistsAsync } from '../../Modules';
import { getResourceXMLPathAsync } from '../Paths';
import { readResourcesXMLAsync } from '../Resources';

jest.mock('fs');
Expand Down
19 changes: 10 additions & 9 deletions packages/config/src/ios/BundleIdentifier.ts
@@ -1,10 +1,10 @@
import plist, { PlistObject } from '@expo/plist';
import fs from 'fs-extra';
import { sync as globSync } from 'glob';
import xcode from 'xcode';

import { ExpoConfig } from '../Config.types';
import { InfoPlist } from './IosConfig.types';
import { getAllInfoPlistPaths, getAllPBXProjectPaths, getPBXProjectPath } from './Paths';
import {
ConfigurationSectionEntry,
findFirstNativeTarget,
Expand Down Expand Up @@ -41,12 +41,10 @@ function setBundleIdentifier(config: ExpoConfig, infoPlist: InfoPlist): InfoPlis
* @returns {string | null} bundle identifier of the Xcode project or null if the project is not configured
*/
function getBundleIdentifierFromPbxproj(projectRoot: string): string | null {
// TODO(dsokal):
// I'm not sure if it's either possible or common that an iOS project has multiple project.pbxproj files.
// For now, I'm assuming that the glob returns at last one file.
const pbxprojPaths = globSync('ios/*/project.pbxproj', { absolute: true, cwd: projectRoot });
const pbxprojPath = pbxprojPaths.length > 0 ? pbxprojPaths[0] : undefined;
if (!pbxprojPath) {
let pbxprojPath: string;
try {
pbxprojPath = getPBXProjectPath(projectRoot);
} catch {
return null;
}
const project = xcode.project(pbxprojPath);
Expand Down Expand Up @@ -128,7 +126,10 @@ function setBundleIdentifierForPbxproj(
updateProductName: boolean = true
): void {
// Get all pbx projects in the ${projectRoot}/ios directory
const pbxprojPaths = globSync('ios/*/project.pbxproj', { absolute: true, cwd: projectRoot });
let pbxprojPaths: string[] = [];
try {
pbxprojPaths = getAllPBXProjectPaths(projectRoot);
} catch {}

for (const pbxprojPath of pbxprojPaths) {
updateBundleIdentifierForPbxproj(pbxprojPath, bundleIdentifier, updateProductName);
Expand All @@ -142,7 +143,7 @@ function setBundleIdentifierForPbxproj(
const defaultBundleId = '$(PRODUCT_BUNDLE_IDENTIFIER)';

function resetAllPlistBundleIdentifiers(projectRoot: string): void {
const infoPlistPaths = globSync('ios/*/Info.plist', { absolute: true, cwd: projectRoot });
const infoPlistPaths = getAllInfoPlistPaths(projectRoot);

for (const plistPath of infoPlistPaths) {
resetPlistBundleIdentifier(plistPath);
Expand Down
18 changes: 5 additions & 13 deletions packages/config/src/ios/DeviceFamily.ts
Expand Up @@ -4,19 +4,11 @@ import { ExpoConfig } from '../Config.types';
import { getPbxproj } from './utils/Xcodeproj';

export function getSupportsTablet(config: ExpoConfig): boolean {
if (config.ios?.supportsTablet) {
return !!config.ios?.supportsTablet;
}

return false;
return !!config.ios?.supportsTablet;
}

export function getIsTabletOnly(config: ExpoConfig): boolean {
if (config.ios?.isTabletOnly) {
return !!config.ios.isTabletOnly;
}

return false;
return !!config?.ios?.isTabletOnly;
}

export function getDeviceFamilies(config: ExpoConfig): number[] {
Expand All @@ -29,18 +21,18 @@ export function getDeviceFamilies(config: ExpoConfig): number[] {
} else if (supportsTablet) {
return [1, 2];
} else {
// is iPhone only
return [1];
}
}

/**
* Wrapping the families in double quotes is the only way to set a value with a comma in it.
* Use a number when only value is returned, this better emulates Xcode.
*
* @param deviceFamilies
*/
export function formatDeviceFamilies(deviceFamilies: number[]): string | number {
return deviceFamilies.length === 1 ? deviceFamilies[0] : `"${deviceFamilies.join(',')}"`;
export function formatDeviceFamilies(deviceFamilies: number[]): string {
return `"${deviceFamilies.join(',')}"`;
}

/**
Expand Down
25 changes: 2 additions & 23 deletions packages/config/src/ios/Entitlements.ts
@@ -1,10 +1,10 @@
import fs from 'fs-extra';
import { sync as globSync } from 'glob';
import path from 'path';

import { ExpoConfig } from '../Config.types';
import { addWarningIOS } from '../WarningAggregator';
import { InfoPlist } from './IosConfig.types';
import * as Paths from './Paths';
import {
getPbxproj,
getProjectName,
Expand Down Expand Up @@ -90,7 +90,7 @@ export function setAssociatedDomains(
}

export function getEntitlementsPath(projectRoot: string): string {
return getExistingEntitlementsPath(projectRoot) ?? createEntitlementsFile(projectRoot);
return Paths.getEntitlementsPath(projectRoot) ?? createEntitlementsFile(projectRoot);
}

function createEntitlementsFile(projectRoot: string) {
Expand Down Expand Up @@ -135,24 +135,3 @@ const ENTITLEMENTS_TEMPLATE = `
</dict>
</plist>
`;

/**
* Get the path to an existing entitlements file or use the default
*/
function getExistingEntitlementsPath(projectRoot: string): string | null {
const entitlementsPaths = globSync('ios/*/.entitlements', { absolute: true, cwd: projectRoot });
if (entitlementsPaths.length === 0) {
return null;
}
const [entitlementsPath, ...otherEntitlementsPaths] = entitlementsPaths[0];

if (entitlementsPaths.length > 1) {
console.warn(
`Found multiple entitlements paths, using ${entitlementsPath}. Other paths ${JSON.stringify(
otherEntitlementsPaths
)} ignored.`
);
}

return entitlementsPath;
}
3 changes: 2 additions & 1 deletion packages/config/src/ios/Google.ts
Expand Up @@ -3,8 +3,9 @@ import path from 'path';

import { ExpoConfig } from '../Config.types';
import { InfoPlist } from './IosConfig.types';
import { getSourceRoot } from './Paths';
import { appendScheme } from './Scheme';
import { addFileToGroup, getPbxproj, getProjectName, getSourceRoot } from './utils/Xcodeproj';
import { addFileToGroup, getPbxproj, getProjectName } from './utils/Xcodeproj';

export function getGoogleMapsApiKey(config: ExpoConfig) {
return config.ios?.config?.googleMapsApiKey ?? null;
Expand Down

0 comments on commit 9e0be1d

Please sign in to comment.