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

Commit

Permalink
[cli] refactor IQuit, contextual errors (#1891)
Browse files Browse the repository at this point in the history
* [cli] refactor IQuit to propagate error if non interactive

* [cli] contextual setup debug logs

* Make code review changes

Co-authored-by: Brent Vatne <brentvatne@gmail.com>
  • Loading branch information
quinlanj and brentvatne authored Apr 16, 2020
1 parent c94638e commit 57abd9f
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 33 deletions.
43 changes: 33 additions & 10 deletions packages/expo-cli/src/commands/build/ios/IOSBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import get from 'lodash/get';
import { XDLError } from '@expo/xdl';

import { Dictionary } from 'lodash';
import terminalLink from 'terminal-link';
import BaseBuilder from '../BaseBuilder';
import { PLATFORMS } from '../constants';
import * as utils from '../utils';
Expand All @@ -16,7 +17,7 @@ import { displayProjectCredentials } from '../../../credentials/actions/list';
import { SetupIosDist } from '../../../credentials/views/SetupIosDist';
import { SetupIosPush } from '../../../credentials/views/SetupIosPush';
import { SetupIosProvisioningProfile } from '../../../credentials/views/SetupIosProvisioningProfile';
import CommandError from '../../../CommandError';
import CommandError, { ErrorCodes } from '../../../CommandError';
import log from '../../../log';

import {
Expand Down Expand Up @@ -122,16 +123,38 @@ See https://docs.expo.io/versions/latest/distribution/building-standalone-apps/#
}
await this.produceCredentials(context, experienceName, bundleIdentifier);
} catch (e) {
log(
chalk.bold.red(
'Failed to prepare all credentials. \nThe next time you build, we will automatically use the following configuration:'
)
);
throw e;
} finally {
const credentials = await context.ios.getAllCredentials();
displayProjectCredentials(experienceName, bundleIdentifier, credentials);
if (e.code === ErrorCodes.NON_INTERACTIVE) {
log.newLine();
const link = terminalLink(
'expo.fyi/credentials-non-interactive',
'https://expo.fyi/credentials-non-interactive'
);
log(
chalk.bold.red(
`Additional information needed to setup credentials in non-interactive mode.`
)
);
log(chalk.bold.red(`Learn more about how to resolve this: ${link}.`));
log.newLine();

// We don't want to display project credentials when we bail out due to
// non-interactive mode error, because we are unable to recover without
// user input.
throw new CommandError(
ErrorCodes.NON_INTERACTIVE,
'Unable to proceed, see the above error message.'
);
} else {
log(
chalk.bold.red(
'Failed to prepare all credentials. \nThe next time you build, we will automatically use the following configuration:'
)
);
}
}

const credentials = await context.ios.getAllCredentials();
displayProjectCredentials(experienceName, bundleIdentifier, credentials);
}

async produceCredentials(ctx: Context, experienceName: string, bundleIdentifier: string) {
Expand Down
18 changes: 13 additions & 5 deletions packages/expo-cli/src/credentials/route.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import log from '../log';

import { Context, IView } from './context';
import { IQuit, QuitError, askQuit, doQuit } from './views/Select';
import { AskQuit, DoQuit, IQuit, QuitError } from './views/Select';

export async function runCredentialsManagerStandalone(ctx: Context, startView: IView) {
const manager = new CredentialsManager(ctx, startView, askQuit);
const manager = new CredentialsManager(ctx, startView, new AskQuit());
await manager.run();
}

export async function runCredentialsManager(ctx: Context, startView: IView): Promise<null> {
const manager = new CredentialsManager(ctx, startView, doQuit);
const manager = new CredentialsManager(ctx, startView, new DoQuit());
return await manager.run();
}

Expand Down Expand Up @@ -39,14 +39,22 @@ export class CredentialsManager {
while (true) {
try {
this._currentView =
(await this._currentView.open(this._ctx)) || (await this._quit(this._mainView));
(await this._currentView.open(this._ctx)) || (await this._quit.runAsync(this._mainView));
} catch (error) {
// View quit normally, exit normally
if (error instanceof QuitError) {
return null;
}

// View encountered error
if (this._quit instanceof DoQuit) {
// propagate error up
throw error;
} else {
// fallback to interactive Quit View
log(error);
await new Promise(res => setTimeout(res, 1000));
this._currentView = await this._quit(this._mainView);
this._currentView = await this._quit.runAsync(this._mainView);
}
}
}
Expand Down
42 changes: 24 additions & 18 deletions packages/expo-cli/src/credentials/views/Select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,26 +170,32 @@ export class QuitError extends Error {
}
}

export type IQuit = (view: IView) => Promise<IView>;
export interface IQuit {
runAsync(mainpage: IView): Promise<IView>;
}

export async function doQuit(mainpage: IView): Promise<IView> {
throw new QuitError();
export class DoQuit implements IQuit {
async runAsync(mainpage: IView): Promise<IView> {
throw new QuitError();
}
}

export async function askQuit(mainpage: IView): Promise<IView> {
const { selected } = await prompt([
{
type: 'list',
name: 'selected',
message: 'Do you want to quit Credential Manager',
choices: [
{ value: 'exit', name: 'Quit Credential Manager' },
{ value: 'mainpage', name: 'Go back to experience overview.' },
],
},
]);
if (selected === 'exit') {
process.exit(0);
export class AskQuit implements IQuit {
async runAsync(mainpage: IView): Promise<IView> {
const { selected } = await prompt([
{
type: 'list',
name: 'selected',
message: 'Do you want to quit Credential Manager',
choices: [
{ value: 'exit', name: 'Quit Credential Manager' },
{ value: 'mainpage', name: 'Go back to experience overview.' },
],
},
]);
if (selected === 'exit') {
process.exit(0);
}
return mainpage;
}
return mainpage;
}

0 comments on commit 57abd9f

Please sign in to comment.