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

[dev-client][cli] Created scheme resolver #2861

Merged
merged 4 commits into from
Nov 6, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
64 changes: 64 additions & 0 deletions packages/expo-cli/src/schemes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { AndroidConfig, IOSConfig } from '@expo/config';
import plist from '@expo/plist';
import * as fs from 'fs-extra';

import { AbortCommandError } from './CommandError';
import log from './log';

async function getSchemesForIosAsync(projectRoot: string) {
try {
const configPath = IOSConfig.Paths.getInfoPlistPath(projectRoot);
const rawPlist = fs.readFileSync(configPath, 'utf8');
const plistObject = plist.parse(rawPlist);
return IOSConfig.Scheme.getSchemesFromPlist(plistObject);
} catch {
// No ios folder or some other error
return [];
}
}

async function getSchemesForAndroidAsync(projectRoot: string) {
try {
const configPath = await AndroidConfig.Paths.getAndroidManifestAsync(projectRoot);
const manifest = await AndroidConfig.Manifest.readAndroidManifestAsync(configPath);
return await AndroidConfig.Scheme.getSchemesFromManifest(manifest);
} catch {
// No android folder or some other error
return [];
}
}

function intersecting<T>(a: T[], b: T[]): T[] {
const [c, d] = a.length > b.length ? [a, b] : [b, a];
return c.filter(value => d.includes(value));
}

export async function getDevClientSchemeAsync(projectRoot: string): Promise<string> {
const [ios, android] = await Promise.all([
getSchemesForIosAsync(projectRoot),
getSchemesForAndroidAsync(projectRoot),
]);

const [matching] = intersecting(ios, android);
if (!matching) {
log.warn(
'\nDev Client: No common URI schemes could be found for the native ios and android projects, this is required for opening the project\n'
);
log(
`Ensure your project is ejected, then either add a common scheme with ${log.chalk.cyan(
EvanBacon marked this conversation as resolved.
Show resolved Hide resolved
EvanBacon marked this conversation as resolved.
Show resolved Hide resolved
'npx uri-scheme add my-scheme'
)} or provide a scheme with the ${log.chalk.cyan('--scheme')} flag\n`
);
log(
log.chalk.dim(
`You can see all of the existing schemes for your native projects by running ${log.chalk.cyan(
'npx uri-scheme list'
)}\n`
)
);

// No log error
throw new AbortCommandError();
}
return matching;
}
8 changes: 8 additions & 0 deletions packages/expo-cli/src/urlOpts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import qrcodeTerminal from 'qrcode-terminal';

import CommandError from './CommandError';
import log from './log';
import { getDevClientSchemeAsync } from './schemes';

export type URLOptions = {
devClient?: boolean;
android?: boolean;
ios?: boolean;
web?: boolean;
Expand All @@ -18,6 +20,7 @@ export type URLOptions = {

function addOptions(program: Command) {
program
.option('--dev-client', 'Starts the bundler for use with the Expo dev client')
.option('-a, --android', 'Opens your app in Expo client on a connected Android device')
.option(
'-i, --ios',
Expand Down Expand Up @@ -61,6 +64,11 @@ async function optsAsync(projectDir: string, options: any) {
opts.hostType = 'localhost';
}

if (options.devClient) {
const scheme = await getDevClientSchemeAsync(projectDir);
// TODO: Use scheme, pending https://github.com/expo/expo-cli/pull/2860
}

await ProjectSettings.setAsync(projectDir, opts);

return opts;
Expand Down