From 500304f49340d9c7b4c1a5a0ee51a87a8440cafc Mon Sep 17 00:00:00 2001 From: Wojciech Kozyra Date: Mon, 17 Aug 2020 16:43:49 +0200 Subject: [PATCH] review feedback --- .../builders/__tests__/AndroidBuilder-test.ts | 10 +++ .../builders/__tests__/iOSBuilder-test.ts | 10 +++ .../eas-build/build/builders/iOSBuilder.ts | 69 +----------------- .../commands/eas-build/build/utils/xcode.ts | 70 +++++++++++++++++++ .../eas-build/credentialsSync/action.ts | 51 ++++++++++---- .../__tests__/read-test.ts} | 24 +++---- .../read.ts} | 10 ++- .../{local => credentialsJson}/update.ts | 51 +++++--------- .../expo-cli/src/credentials/local/index.ts | 2 - .../provider/AndroidCredentialsProvider.ts | 6 +- .../provider/iOSCredentialsProvider.ts | 4 +- .../credentials/views/SetupAndroidKeystore.ts | 6 +- .../views/SetupIosBuildCredentials.ts | 6 +- 13 files changed, 174 insertions(+), 145 deletions(-) create mode 100644 packages/expo-cli/src/commands/eas-build/build/utils/xcode.ts rename packages/expo-cli/src/credentials/{local/__tests__/credentials-json-test.ts => credentialsJson/__tests__/read-test.ts} (86%) rename packages/expo-cli/src/credentials/{local/credentialsJson.ts => credentialsJson/read.ts} (89%) rename packages/expo-cli/src/credentials/{local => credentialsJson}/update.ts (70%) delete mode 100644 packages/expo-cli/src/credentials/local/index.ts diff --git a/packages/expo-cli/src/commands/eas-build/build/builders/__tests__/AndroidBuilder-test.ts b/packages/expo-cli/src/commands/eas-build/build/builders/__tests__/AndroidBuilder-test.ts index b030ac6acf..7734e89b63 100644 --- a/packages/expo-cli/src/commands/eas-build/build/builders/__tests__/AndroidBuilder-test.ts +++ b/packages/expo-cli/src/commands/eas-build/build/builders/__tests__/AndroidBuilder-test.ts @@ -35,6 +35,16 @@ function setupCredentialsConfig() { }); } +const originalWarn = console.warn; +const originalLog = console.log; +beforeAll(() => { + console.warn = jest.fn(); + console.log = jest.fn(); +}); +afterAll(() => { + console.warn = originalWarn; + console.log = originalLog; +}); beforeEach(() => { vol.reset(); }); diff --git a/packages/expo-cli/src/commands/eas-build/build/builders/__tests__/iOSBuilder-test.ts b/packages/expo-cli/src/commands/eas-build/build/builders/__tests__/iOSBuilder-test.ts index faa20fc403..f012f028ec 100644 --- a/packages/expo-cli/src/commands/eas-build/build/builders/__tests__/iOSBuilder-test.ts +++ b/packages/expo-cli/src/commands/eas-build/build/builders/__tests__/iOSBuilder-test.ts @@ -40,6 +40,16 @@ function setupCredentialsConfig() { }); } +const originalWarn = console.warn; +const originalLog = console.log; +beforeAll(() => { + console.warn = jest.fn(); + console.log = jest.fn(); +}); +afterAll(() => { + console.warn = originalWarn; + console.log = originalLog; +}); beforeEach(() => { vol.reset(); }); diff --git a/packages/expo-cli/src/commands/eas-build/build/builders/iOSBuilder.ts b/packages/expo-cli/src/commands/eas-build/build/builders/iOSBuilder.ts index e15599c3b0..7ebcc8d090 100644 --- a/packages/expo-cli/src/commands/eas-build/build/builders/iOSBuilder.ts +++ b/packages/expo-cli/src/commands/eas-build/build/builders/iOSBuilder.ts @@ -2,7 +2,6 @@ import { BuildType, Job, Platform, iOS, sanitizeJob } from '@expo/build-tools'; import { IOSConfig } from '@expo/config'; import chalk from 'chalk'; import figures from 'figures'; -import once from 'lodash/once'; import ora from 'ora'; import iOSCredentialsProvider, { @@ -16,10 +15,10 @@ import { iOSManagedBuildProfile, } from '../../../../easJson'; import log from '../../../../log'; -import prompts from '../../../../prompts'; import { ensureCredentialsAsync } from '../credentials'; import { Builder, BuilderContext } from '../types'; import * as gitUtils from '../utils/git'; +import { getBundleIdentifier } from '../utils/xcode'; interface CommonJobProperties { platform: Platform.iOS; @@ -83,7 +82,7 @@ class iOSBuilder implements Builder { if (!this.credentials) { throw new Error('Call ensureCredentialsAsync first!'); } - const bundleIdentifier = await getBundleIdentifier(this.ctx); + const bundleIdentifier = await getBundleIdentifier(this.ctx.projectDir, this.ctx.exp); const spinner = ora('Making sure your iOS project is set up properly'); @@ -176,69 +175,5 @@ class iOSBuilder implements Builder { ); } } -const getBundleIdentifier = once(_getBundleIdentifier); - -async function _getBundleIdentifier(ctx: BuilderContext): Promise { - const bundleIdentifierFromPbxproj = IOSConfig.BundleIdenitifer.getBundleIdentifierFromPbxproj( - ctx.projectDir - ); - const bundleIdentifierFromConfig = IOSConfig.BundleIdenitifer.getBundleIdentifier(ctx.exp); - if (bundleIdentifierFromPbxproj !== null && bundleIdentifierFromConfig !== null) { - if (bundleIdentifierFromPbxproj === bundleIdentifierFromConfig) { - return bundleIdentifierFromPbxproj; - } else { - log.newLine(); - log( - log.chalk.yellow( - `We detected that your Xcode project is configured with a different bundle identifier than the one defined in app.json/app.config.js. -If you choose the one defined in app.json/app.config.js we'll automatically configure your Xcode project with it. -However, if you choose the one defined in the Xcode project you'll have to update app.json/app.config.js on your own. -Otherwise, you'll see this prompt again in the future.` - ) - ); - log.newLine(); - const { bundleIdentifier } = await prompts({ - type: 'select', - name: 'bundleIdentifier', - message: 'Which bundle identifier should we use?', - choices: [ - { - title: `Defined in the Xcode project: ${log.chalk.bold(bundleIdentifierFromPbxproj)}`, - value: bundleIdentifierFromPbxproj, - }, - { - title: `Defined in app.json/app.config.js: ${log.chalk.bold( - bundleIdentifierFromConfig - )}`, - value: bundleIdentifierFromConfig, - }, - ], - }); - return bundleIdentifier; - } - } else if (bundleIdentifierFromPbxproj === null && bundleIdentifierFromConfig === null) { - throw new Error('Please define "expo.ios.bundleIdentifier" in app.json/app.config.js'); - } else { - if (bundleIdentifierFromPbxproj !== null) { - log( - `Using ${log.chalk.bold( - bundleIdentifierFromPbxproj - )} as the bundle identifier (read from the Xcode project).` - ); - return bundleIdentifierFromPbxproj; - } else { - // bundleIdentifierFromConfig is never null in this case - // the following line is to satisfy TS - const bundleIdentifier = bundleIdentifierFromConfig ?? ''; - log( - `Using ${log.chalk.bold( - bundleIdentifier - )} as the bundle identifier (read from app.json/app.config.js). -We'll automatically configure your Xcode project using this value.` - ); - return bundleIdentifier; - } - } -} export default iOSBuilder; diff --git a/packages/expo-cli/src/commands/eas-build/build/utils/xcode.ts b/packages/expo-cli/src/commands/eas-build/build/utils/xcode.ts new file mode 100644 index 0000000000..dfa29dd279 --- /dev/null +++ b/packages/expo-cli/src/commands/eas-build/build/utils/xcode.ts @@ -0,0 +1,70 @@ +import { ExpoConfig, IOSConfig } from '@expo/config'; +import once from 'lodash/once'; + +import log from '../../../../log'; +import prompts from '../../../../prompts'; + +export const getBundleIdentifier = once(_getBundleIdentifier); + +async function _getBundleIdentifier(projectDir: string, manifest: ExpoConfig): Promise { + const bundleIdentifierFromPbxproj = IOSConfig.BundleIdenitifer.getBundleIdentifierFromPbxproj( + projectDir + ); + const bundleIdentifierFromConfig = IOSConfig.BundleIdenitifer.getBundleIdentifier(manifest); + if (bundleIdentifierFromPbxproj !== null && bundleIdentifierFromConfig !== null) { + if (bundleIdentifierFromPbxproj === bundleIdentifierFromConfig) { + return bundleIdentifierFromPbxproj; + } else { + log.newLine(); + log( + log.chalk.yellow( + `We detected that your Xcode project is configured with a different bundle identifier than the one defined in app.json/app.config.js. +If you choose the one defined in app.json/app.config.js we'll automatically configure your Xcode project with it. +However, if you choose the one defined in the Xcode project you'll have to update app.json/app.config.js on your own. +Otherwise, you'll see this prompt again in the future.` + ) + ); + log.newLine(); + const { bundleIdentifier } = await prompts({ + type: 'select', + name: 'bundleIdentifier', + message: 'Which bundle identifier should we use?', + choices: [ + { + title: `Defined in the Xcode project: ${log.chalk.bold(bundleIdentifierFromPbxproj)}`, + value: bundleIdentifierFromPbxproj, + }, + { + title: `Defined in app.json/app.config.js: ${log.chalk.bold( + bundleIdentifierFromConfig + )}`, + value: bundleIdentifierFromConfig, + }, + ], + }); + return bundleIdentifier; + } + } else if (bundleIdentifierFromPbxproj === null && bundleIdentifierFromConfig === null) { + throw new Error('Please define "expo.ios.bundleIdentifier" in app.json/app.config.js'); + } else { + if (bundleIdentifierFromPbxproj !== null) { + log( + `Using ${log.chalk.bold( + bundleIdentifierFromPbxproj + )} as the bundle identifier (read from the Xcode project).` + ); + return bundleIdentifierFromPbxproj; + } else { + // bundleIdentifierFromConfig is never null in this case + // the following line is to satisfy TS + const bundleIdentifier = bundleIdentifierFromConfig ?? ''; + log( + `Using ${log.chalk.bold( + bundleIdentifier + )} as the bundle identifier (read from app.json/app.config.js). +We'll automatically configure your Xcode project using this value.` + ); + return bundleIdentifier; + } + } +} diff --git a/packages/expo-cli/src/commands/eas-build/credentialsSync/action.ts b/packages/expo-cli/src/commands/eas-build/credentialsSync/action.ts index c3c5ec0dca..18b7a7d769 100644 --- a/packages/expo-cli/src/commands/eas-build/credentialsSync/action.ts +++ b/packages/expo-cli/src/commands/eas-build/credentialsSync/action.ts @@ -1,10 +1,12 @@ import CommandError from '../../../CommandError'; import { Context } from '../../../credentials/context'; -import { updateLocalCredentialsJsonAsync } from '../../../credentials/local'; +import * as credentialsJson from '../../../credentials/credentialsJson/update'; import { runCredentialsManager } from '../../../credentials/route'; import { SetupAndroidBuildCredentialsFromLocal } from '../../../credentials/views/SetupAndroidKeystore'; import { SetupIosBuildCredentialsFromLocal } from '../../../credentials/views/SetupIosBuildCredentials'; +import log from '../../../log'; import prompts from '../../../prompts'; +import { getBundleIdentifier } from '../build/utils/xcode'; import { BuildCommandPlatform } from '../types'; interface Options { @@ -24,31 +26,37 @@ export default async function credentialsSyncAction(projectDir: string, options: message: 'What do you want to do?', choices: [ { - title: 'Update credentials on Expo servers with local credentials.json content', + title: 'Update credentials on the Expo servers with local credentials.json contents', value: 'remote', }, - { title: 'Update local credentials.json with values from Expo servers', value: 'local' }, + { + title: 'Update or create local credentials.json with credentials from Expo servers', + value: 'local', + }, ], }, { type: 'select', name: 'platform', - message: 'Do you want to update credentials for both platforms?', + message: 'Which platform would you like to update?', choices: [ - { title: 'Android & iOS', value: BuildCommandPlatform.ALL }, - { title: 'only Android', value: BuildCommandPlatform.ANDROID }, - { title: 'only iOS', value: BuildCommandPlatform.IOS }, + { title: 'Android', value: BuildCommandPlatform.ANDROID }, + { title: 'iOS', value: BuildCommandPlatform.IOS }, + { title: 'both', value: BuildCommandPlatform.ALL }, ], }, ]); if (update === 'local') { - await updateLocalCredentialsJsonAsync(projectDir, platform); + await updateLocalCredentialsAsync(projectDir, platform); } else { await updateRemoteCredentialsAsync(projectDir, platform); } } -async function updateRemoteCredentialsAsync(projectDir: string, platform: BuildCommandPlatform) { +async function updateRemoteCredentialsAsync( + projectDir: string, + platform: BuildCommandPlatform +): Promise { const ctx = new Context(); await ctx.init(projectDir); if (!ctx.hasProjectContext) { @@ -59,10 +67,7 @@ async function updateRemoteCredentialsAsync(projectDir: string, platform: BuildC await runCredentialsManager(ctx, new SetupAndroidBuildCredentialsFromLocal(experienceName)); } if (['all', 'ios'].includes(platform)) { - const bundleIdentifier = ctx.manifest.ios?.bundleIdentifier; - if (!bundleIdentifier) { - throw new Error('"expo.ios.bundleIdentifier" field is required in your app.json'); - } + const bundleIdentifier = await getBundleIdentifier(projectDir, ctx.manifest); const appLookupParams = { accountName: ctx.manifest.owner ?? ctx.user.username, projectName: ctx.manifest.slug, @@ -71,3 +76,23 @@ async function updateRemoteCredentialsAsync(projectDir: string, platform: BuildC await runCredentialsManager(ctx, new SetupIosBuildCredentialsFromLocal(appLookupParams)); } } + +export async function updateLocalCredentialsAsync( + projectDir: string, + platform: BuildCommandPlatform +): Promise { + const ctx = new Context(); + await ctx.init(projectDir); + if (!ctx.hasProjectContext) { + throw new Error('project context is required'); // should be checked earlier + } + if ([BuildCommandPlatform.ALL, BuildCommandPlatform.ANDROID].includes(platform)) { + log('Updating Android credentials in credentials.json'); + await credentialsJson.updateAndroidCredentialsAsync(ctx); + } + if ([BuildCommandPlatform.ALL, BuildCommandPlatform.IOS].includes(platform)) { + const bundleIdentifier = await getBundleIdentifier(projectDir, ctx.manifest); + log('Updating iOS credentials in credentials.json'); + await credentialsJson.updateIosCredentialsAsync(ctx, bundleIdentifier); + } +} diff --git a/packages/expo-cli/src/credentials/local/__tests__/credentials-json-test.ts b/packages/expo-cli/src/credentials/credentialsJson/__tests__/read-test.ts similarity index 86% rename from packages/expo-cli/src/credentials/local/__tests__/credentials-json-test.ts rename to packages/expo-cli/src/credentials/credentialsJson/__tests__/read-test.ts index 734d34694c..0c35252af7 100644 --- a/packages/expo-cli/src/credentials/local/__tests__/credentials-json-test.ts +++ b/packages/expo-cli/src/credentials/credentialsJson/__tests__/read-test.ts @@ -1,6 +1,6 @@ import { vol } from 'memfs'; -import credentialsJson from '../credentialsJson'; +import * as credentialsJson from '../read'; jest.mock('fs'); @@ -24,7 +24,7 @@ describe('credentialsJson', () => { }), 'keystore.jks': 'somebinarydata', }); - const result = await credentialsJson.readAndroidAsync('.'); + const result = await credentialsJson.readAndroidCredentialsAsync('.'); expect(result).toEqual({ keystore: { keystore: 'c29tZWJpbmFyeWRhdGE=', @@ -35,7 +35,7 @@ describe('credentialsJson', () => { }); }); it('should throw error when credentials.json is missing', async () => { - const promise = credentialsJson.readAndroidAsync('.'); + const promise = credentialsJson.readAndroidCredentialsAsync('.'); await expect(promise).rejects.toThrow( 'credentials.json must exist in the project root directory and contain a valid JSON' ); @@ -46,7 +46,7 @@ describe('credentialsJson', () => { './credentials.json': JSON.stringify({}), 'keystore.jks': 'somebinarydata', }); - const promise = credentialsJson.readAndroidAsync('.'); + const promise = credentialsJson.readAndroidCredentialsAsync('.'); await expect(promise).rejects.toThrow( 'Android credentials are missing from credentials.json' ); @@ -64,7 +64,7 @@ describe('credentialsJson', () => { }), 'keystore.jks': 'somebinarydata', }); - const promise = credentialsJson.readAndroidAsync('.'); + const promise = credentialsJson.readAndroidCredentialsAsync('.'); await expect(promise).rejects.toThrow( 'credentials.json is not valid [ValidationError: "android.keystore.keystorePath" is required]' ); @@ -82,7 +82,7 @@ describe('credentialsJson', () => { }, }), }); - const promise = credentialsJson.readAndroidAsync('.'); + const promise = credentialsJson.readAndroidCredentialsAsync('.'); await expect(promise).rejects.toThrow( "ENOENT: no such file or directory, open 'keystore.jks'" ); @@ -104,7 +104,7 @@ describe('credentialsJson', () => { './pprofile': 'somebinarycontent', './cert.p12': 'somebinarycontent2', }); - const result = await credentialsJson.readIosAsync('.'); + const result = await credentialsJson.readIosCredentialsAsync('.'); expect(result).toEqual({ provisioningProfile: 'c29tZWJpbmFyeWNvbnRlbnQ=', distributionCertificate: { @@ -114,7 +114,7 @@ describe('credentialsJson', () => { }); }); it('should throw error when credentials.json is missing', async () => { - const promise = credentialsJson.readIosAsync('.'); + const promise = credentialsJson.readIosCredentialsAsync('.'); await expect(promise).rejects.toThrow( 'credentials.json must exist in the project root directory and contain a valid JSON' ); @@ -125,7 +125,7 @@ describe('credentialsJson', () => { './pprofile': 'somebinarycontent', './cert.p12': 'somebinarycontent2', }); - const promise = credentialsJson.readIosAsync('.'); + const promise = credentialsJson.readIosCredentialsAsync('.'); await expect(promise).rejects.toThrow('iOS credentials are missing from credentials.json'); }); it('should throw error if some field is missing', async () => { @@ -141,7 +141,7 @@ describe('credentialsJson', () => { './pprofile': 'somebinarycontent', './cert.p12': 'somebinarycontent2', }); - const promise = credentialsJson.readIosAsync('.'); + const promise = credentialsJson.readIosCredentialsAsync('.'); await expect(promise).rejects.toThrow( 'credentials.json is not valid [ValidationError: "ios.provisioningProfilePath" is required]' ); @@ -159,7 +159,7 @@ describe('credentialsJson', () => { }), './pprofile': 'somebinarycontent', }); - const promise = credentialsJson.readIosAsync('.'); + const promise = credentialsJson.readIosCredentialsAsync('.'); await expect(promise).rejects.toThrow("ENOENT: no such file or directory, open 'cert.p12'"); }); it('should throw error if provisioningProfile file is missing', async () => { @@ -175,7 +175,7 @@ describe('credentialsJson', () => { }), './cert.p12': 'somebinarycontent2', }); - const promise = credentialsJson.readIosAsync('.'); + const promise = credentialsJson.readIosCredentialsAsync('.'); await expect(promise).rejects.toThrow("ENOENT: no such file or directory, open 'pprofile'"); }); }); diff --git a/packages/expo-cli/src/credentials/local/credentialsJson.ts b/packages/expo-cli/src/credentials/credentialsJson/read.ts similarity index 89% rename from packages/expo-cli/src/credentials/local/credentialsJson.ts rename to packages/expo-cli/src/credentials/credentialsJson/read.ts index db7f8bd668..0f8b155903 100644 --- a/packages/expo-cli/src/credentials/local/credentialsJson.ts +++ b/packages/expo-cli/src/credentials/credentialsJson/read.ts @@ -52,11 +52,11 @@ interface iOSCredentials { }; } -async function fileExistsAsync(projectDir: string): Promise { +export async function fileExistsAsync(projectDir: string): Promise { return await fs.pathExists(path.join(projectDir, 'credentials.json')); } -async function readAndroidAsync(projectDir: string): Promise { +export async function readAndroidCredentialsAsync(projectDir: string): Promise { const credentialsJson = await readAsync(projectDir); if (!credentialsJson.android) { throw new Error('Android credentials are missing from credentials.json'); // TODO: add fyi @@ -72,7 +72,7 @@ async function readAndroidAsync(projectDir: string): Promise }; } -async function readIosAsync(projectDir: string): Promise { +export async function readIosCredentialsAsync(projectDir: string): Promise { const credentialsJson = await readAsync(projectDir); if (!credentialsJson.ios) { throw new Error('iOS credentials are missing from credentials.json'); // TODO: add fyi @@ -107,7 +107,7 @@ async function readAsync(projectDir: string): Promise { return credentialsJson; } -async function readRawAsync(projectDir: string): Promise { +export async function readRawAsync(projectDir: string): Promise { const credentialsJsonFilePath = path.join(projectDir, 'credentials.json'); try { const credentialsJSONContents = await fs.readFile(credentialsJsonFilePath, 'utf8'); @@ -121,5 +121,3 @@ async function readRawAsync(projectDir: string): Promise { const getAbsolutePath = (projectDir: string, filePath: string): string => path.isAbsolute(filePath) ? filePath : path.join(projectDir, filePath); - -export default { readAndroidAsync, readIosAsync, readRawAsync, fileExistsAsync }; diff --git a/packages/expo-cli/src/credentials/local/update.ts b/packages/expo-cli/src/credentials/credentialsJson/update.ts similarity index 70% rename from packages/expo-cli/src/credentials/local/update.ts rename to packages/expo-cli/src/credentials/credentialsJson/update.ts index 94b86906fd..59fb683118 100644 --- a/packages/expo-cli/src/credentials/local/update.ts +++ b/packages/expo-cli/src/credentials/credentialsJson/update.ts @@ -5,31 +5,13 @@ import prompts from 'prompts'; import log from '../../log'; import { Context } from '../context'; -type Platform = 'android' | 'ios' | 'all'; - -export async function updateLocalCredentialsJsonAsync(projectDir: string, platform: Platform) { - const ctx = new Context(); - await ctx.init(projectDir); - if (!ctx.hasProjectContext) { - throw new Error('project context is required'); // should be checked earlier - } - if (['all', 'android'].includes(platform)) { - log('Updating Android credentials in credentials.json'); - await updateAndroidAsync(ctx); - } - if (['all', 'ios'].includes(platform)) { - log('Updating iOS credentials in credentials.json'); - await updateIosAsync(ctx); - } -} - -async function updateAndroidAsync(ctx: Context) { +export async function updateAndroidCredentialsAsync(ctx: Context) { const credentialsJsonFilePath = path.join(ctx.projectDir, 'credentials.json'); let rawCredentialsJsonObject: any = {}; if (await fs.pathExists(credentialsJsonFilePath)) { try { - const rawFile = await fs.readFile(credentialsJsonFilePath); - rawCredentialsJsonObject = JSON.parse(rawFile.toString()); + const rawFile = await fs.readFile(credentialsJsonFilePath, 'utf-8'); + rawCredentialsJsonObject = JSON.parse(rawFile); } catch (error) { log.error(`There was an error while reading credentials.json [${error}]`); log.error('Make sure that file is correct (or remove it) and rerun this command.'); @@ -39,7 +21,8 @@ async function updateAndroidAsync(ctx: Context) { const experienceName = `@${ctx.manifest.owner || ctx.user.username}/${ctx.manifest.slug}`; const keystore = await ctx.android.fetchKeystore(experienceName); if (!keystore) { - throw new Error('There are no credentials configured for this project on Expo servers'); + log.error('There are no credentials configured for this project on Expo servers'); + return; } const isKeystoreComplete = @@ -60,7 +43,8 @@ async function updateAndroidAsync(ctx: Context) { const keystorePath = rawCredentialsJsonObject?.android?.keystorePath ?? './android/keystores/keystore.jks'; - await _updateFileAsync(ctx.projectDir, keystorePath, keystore.keystore); + log(`Writing Keystore to ${keystorePath}`); + await updateFileAsync(ctx.projectDir, keystorePath, keystore.keystore); rawCredentialsJsonObject.android = { keystore: { @@ -75,13 +59,13 @@ async function updateAndroidAsync(ctx: Context) { }); } -async function updateIosAsync(ctx: Context) { +export async function updateIosCredentialsAsync(ctx: Context, bundleIdentifier: string) { const credentialsJsonFilePath = path.join(ctx.projectDir, 'credentials.json'); let rawCredentialsJsonObject: any = {}; if (await fs.pathExists(credentialsJsonFilePath)) { try { - const rawFile = await fs.readFile(credentialsJsonFilePath); - rawCredentialsJsonObject = JSON.parse(rawFile.toString()); + const rawFile = await fs.readFile(credentialsJsonFilePath, 'utf-8'); + rawCredentialsJsonObject = JSON.parse(rawFile); } catch (error) { log.error(`There was an error while reading credentials.json [${error}]`); log.error('Make sure that file is correct (or remove it) and rerun this command.'); @@ -89,10 +73,6 @@ async function updateIosAsync(ctx: Context) { } } - const bundleIdentifier = ctx.manifest.ios?.bundleIdentifier; - if (!bundleIdentifier) { - throw new Error('"expo.ios.bundleIdentifier" field is required in your app.json'); - } const appLookupParams = { accountName: ctx.manifest.owner ?? ctx.user.username, projectName: ctx.manifest.slug, @@ -105,7 +85,8 @@ async function updateIosAsync(ctx: Context) { const appCredentials = await ctx.ios.getAppCredentials(appLookupParams); const distCredentials = await ctx.ios.getDistCert(appLookupParams); if (!appCredentials && !distCredentials) { - throw new Error('There are no credentials configured for this project on Expo servers'); + log.error('There are no credentials configured for this project on Expo servers'); + return; } const areCredentialsComplete = @@ -126,12 +107,14 @@ async function updateIosAsync(ctx: Context) { } } - await _updateFileAsync( + log(`Writing Provisioning Profile to ${pprofilePath}`); + await updateFileAsync( ctx.projectDir, pprofilePath, appCredentials?.credentials?.provisioningProfile ); - await _updateFileAsync(ctx.projectDir, distCertPath, distCredentials?.certP12); + log(`Writing Distribution Certificate to ${distCertPath}`); + await updateFileAsync(ctx.projectDir, distCertPath, distCredentials?.certP12); rawCredentialsJsonObject.ios = { provisioningProfilePath: pprofilePath, @@ -145,7 +128,7 @@ async function updateIosAsync(ctx: Context) { }); } -async function _updateFileAsync(projectDir: string, filePath: string, base64Data?: string) { +async function updateFileAsync(projectDir: string, filePath: string, base64Data?: string) { const absolutePath = path.isAbsolute(filePath) ? filePath : path.join(projectDir, filePath); if (await fs.pathExists(absolutePath)) { await fs.remove(absolutePath); diff --git a/packages/expo-cli/src/credentials/local/index.ts b/packages/expo-cli/src/credentials/local/index.ts deleted file mode 100644 index 8ff4a893f6..0000000000 --- a/packages/expo-cli/src/credentials/local/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as credentialsJson } from './credentialsJson'; -export { updateLocalCredentialsJsonAsync } from './update'; diff --git a/packages/expo-cli/src/credentials/provider/AndroidCredentialsProvider.ts b/packages/expo-cli/src/credentials/provider/AndroidCredentialsProvider.ts index 41c2189fb9..1a6f1d052d 100644 --- a/packages/expo-cli/src/credentials/provider/AndroidCredentialsProvider.ts +++ b/packages/expo-cli/src/credentials/provider/AndroidCredentialsProvider.ts @@ -2,7 +2,7 @@ import { CredentialsSource } from '../../easJson'; import log from '../../log'; import { Context } from '../context'; import { Keystore } from '../credentials'; -import { credentialsJson } from '../local'; +import * as credentialsJson from '../credentialsJson/read'; import { runCredentialsManager } from '../route'; import { SetupAndroidKeystore } from '../views/SetupAndroidKeystore'; import { CredentialsProvider } from './provider'; @@ -55,7 +55,7 @@ export default class AndroidCredentialsProvider implements CredentialsProvider { try { const [remote, local] = await Promise.all([ this.ctx.android.fetchKeystore(this.projectFullName), - await credentialsJson.readAndroidAsync(this.projectDir), + await credentialsJson.readAndroidCredentialsAsync(this.projectDir), ]); const r = remote!; const l = local?.keystore!; @@ -97,7 +97,7 @@ export default class AndroidCredentialsProvider implements CredentialsProvider { } private async getLocalAsync(): Promise { - const credentials = await credentialsJson.readAndroidAsync(this.projectDir); + const credentials = await credentialsJson.readAndroidCredentialsAsync(this.projectDir); if (!this.isValidKeystore(credentials.keystore)) { throw new Error('Invalid keystore in credentials.json'); } diff --git a/packages/expo-cli/src/credentials/provider/iOSCredentialsProvider.ts b/packages/expo-cli/src/credentials/provider/iOSCredentialsProvider.ts index dd4423d284..01807b667e 100644 --- a/packages/expo-cli/src/credentials/provider/iOSCredentialsProvider.ts +++ b/packages/expo-cli/src/credentials/provider/iOSCredentialsProvider.ts @@ -2,7 +2,7 @@ import { CredentialsSource } from '../../easJson'; import log from '../../log'; import { AppLookupParams } from '../api/IosApi'; import { Context } from '../context'; -import { credentialsJson } from '../local'; +import * as credentialsJson from '../credentialsJson/read'; import { runCredentialsManager } from '../route'; import { SetupIosBuildCredentials } from '../views/SetupIosBuildCredentials'; import { CredentialsProvider } from './provider'; @@ -74,7 +74,7 @@ export default class iOSCredentialsProvider implements CredentialsProvider { } private async getLocalAsync(): Promise { - return await credentialsJson.readIosAsync(this.projectDir); + return await credentialsJson.readIosCredentialsAsync(this.projectDir); } private async getRemoteAsync(): Promise { await runCredentialsManager(this.ctx, new SetupIosBuildCredentials(this.app)); diff --git a/packages/expo-cli/src/credentials/views/SetupAndroidKeystore.ts b/packages/expo-cli/src/credentials/views/SetupAndroidKeystore.ts index b2c344d417..35ab53a2ce 100644 --- a/packages/expo-cli/src/credentials/views/SetupAndroidKeystore.ts +++ b/packages/expo-cli/src/credentials/views/SetupAndroidKeystore.ts @@ -2,7 +2,7 @@ import commandExists from 'command-exists'; import log from '../../log'; import { Context, IView } from '../context'; -import { credentialsJson } from '../local'; +import * as credentialsJson from '../credentialsJson/read'; import { UpdateKeystore } from './AndroidKeystore'; interface Options { @@ -47,10 +47,10 @@ export class SetupAndroidBuildCredentialsFromLocal implements IView { async open(ctx: Context): Promise { let localCredentials; try { - localCredentials = await credentialsJson.readAndroidAsync(ctx.projectDir); + localCredentials = await credentialsJson.readAndroidCredentialsAsync(ctx.projectDir); } catch (error) { log.error( - 'Reading credentials from credentials.json failed. Make sure that file is correct and all credentials are present.' + 'Reading credentials from credentials.json failed. Make sure this file is correct and all credentials are present there.' ); throw error; } diff --git a/packages/expo-cli/src/credentials/views/SetupIosBuildCredentials.ts b/packages/expo-cli/src/credentials/views/SetupIosBuildCredentials.ts index 1c312f66a1..d222f46d3d 100644 --- a/packages/expo-cli/src/credentials/views/SetupIosBuildCredentials.ts +++ b/packages/expo-cli/src/credentials/views/SetupIosBuildCredentials.ts @@ -6,7 +6,7 @@ import log from '../../log'; import prompts from '../../prompts'; import { AppLookupParams } from '../api/IosApi'; import { Context, IView } from '../context'; -import { credentialsJson } from '../local'; +import * as credentialsJson from '../credentialsJson/read'; import { runCredentialsManager } from '../route'; import { readAppleTeam } from '../utils/provisioningProfile'; import { SetupIosDist } from './SetupIosDist'; @@ -83,10 +83,10 @@ export class SetupIosBuildCredentialsFromLocal implements IView { async open(ctx: Context): Promise { let localCredentials; try { - localCredentials = await credentialsJson.readIosAsync(ctx.projectDir); + localCredentials = await credentialsJson.readIosCredentialsAsync(ctx.projectDir); } catch (error) { log.error( - 'Reading credentials from credentials.json failed. Make sure that file is correct and all credentials are present.' + 'Reading credentials from credentials.json failed. Make sure this file is correct and all credentials are present there.' ); throw error; }