From f344504bdbf5502c731ef7da7ee3f2462e29bfd0 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 09:23:39 +0200 Subject: [PATCH 01/46] wip save work --- packages/cli/src/commands/link/link.js | 8 ++--- packages/cli/src/tools/config/index.js | 32 ++++++++++++------- .../src/tools/config/readConfigFromDisk.js | 4 +-- packages/cli/src/tools/config/types.flow.js | 32 +++++++++++++------ packages/cli/src/tools/types.flow.js | 2 +- 5 files changed, 50 insertions(+), 28 deletions(-) diff --git a/packages/cli/src/commands/link/link.js b/packages/cli/src/commands/link/link.js index c57f950ac..6b6652983 100644 --- a/packages/cli/src/commands/link/link.js +++ b/packages/cli/src/commands/link/link.js @@ -8,7 +8,7 @@ */ import {pick} from 'lodash'; -import type {ContextT} from '../../tools/types.flow'; +import {type ContextT} from '../../tools/types.flow'; import promiseWaterfall from './promiseWaterfall'; import logger from '../../tools/logger'; @@ -32,10 +32,9 @@ type FlagsType = { * only that package is processed. */ function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { - let platforms; - let project; + let platforms = ctx.platforms; + let project = ctx.project; try { - platforms = getPlatforms(ctx.root); logger.debug( 'Available platforms: ' + `${Object.getOwnPropertyNames(platforms) @@ -51,7 +50,6 @@ function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { .map(platform => getPlatformName(platform)) .join(', ')}`, ); - project = getProjectConfig(ctx, platforms); } catch (err) { logger.error( 'No package found. Are you sure this is a React Native project?', diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.js index f6920a8c5..ba78eee56 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.js @@ -4,15 +4,16 @@ import dedent from 'dedent'; import path from 'path'; import merge from 'deepmerge'; +import {omit} from 'lodash'; import findDependencies from './findDependencies'; import { - readProjectConfigFromDisk, + readConfigFromDisk, readDependencyConfigFromDisk, readLegacyDependencyConfigFromDisk, } from './readConfigFromDisk'; -import {type ProjectConfigT, type RawProjectConfigT} from './types.flow'; +import {type ConfigT, type RawConfigT} from './types.flow'; /** * Built-in platforms @@ -24,9 +25,11 @@ import resolveReactNativePath from './resolveReactNativePath'; /** * Loads CLI configuration */ -function loadConfig(projectRoot: string = process.cwd()): ProjectConfigT { - const inferredProjectConfig = findDependencies(projectRoot).reduce( - (acc: RawProjectConfigT, dependencyName) => { +function loadConfig(projectRoot: string = process.cwd()): ConfigT { + const userConfig = readConfigFromDisk(projectRoot); + + const inferredConfig = findDependencies(projectRoot).reduce( + (acc: RawConfigT, dependencyName) => { const root = path.join(projectRoot, 'node_modules', dependencyName); const config = @@ -88,13 +91,21 @@ function loadConfig(projectRoot: string = process.cwd()): ProjectConfigT { providesModuleNodeModules: [], platforms: [], }, - }: RawProjectConfigT), + // $FlowExpectedError: This getter is safe + get project() { + return Object.keys(this.platforms).reduce((project, platform) => { + project[platform] = this.platforms[platform].projectConfig( + projectRoot, + userConfig.project, + ); + return project; + }, {}); + }, + }: RawConfigT), ); - const config: RawProjectConfigT = merge( - inferredProjectConfig, - readProjectConfigFromDisk(projectRoot), - ); + // @todo(grabbou): make this explicit + const config: ConfigT = merge(inferredConfig, omit(userConfig, 'project')); if (config.reactNativePath === null) { throw new Error(dedent` @@ -111,7 +122,6 @@ function loadConfig(projectRoot: string = process.cwd()): ProjectConfigT { `); } - // $FlowIssue: `reactNativePath: null` is never null at this point return config; } diff --git a/packages/cli/src/tools/config/readConfigFromDisk.js b/packages/cli/src/tools/config/readConfigFromDisk.js index 11ebc7915..3ed00a4d4 100644 --- a/packages/cli/src/tools/config/readConfigFromDisk.js +++ b/packages/cli/src/tools/config/readConfigFromDisk.js @@ -7,7 +7,7 @@ import Joi from 'joi'; import cosmiconfig from 'cosmiconfig'; import path from 'path'; -import {type DependencyConfigT, type ProjectConfigT} from './types.flow'; +import {type DependencyConfigT, type UserConfigT} from './types.flow'; import {JoiError} from '../errors'; @@ -23,7 +23,7 @@ const searchPlaces = ['react-native.config.js', 'package.json']; * Reads a project configuration as defined by the user in the current * workspace. */ -export function readProjectConfigFromDisk(rootFolder: string): ProjectConfigT { +export function readConfigFromDisk(rootFolder: string): UserConfigT { const explorer = cosmiconfig('react-native', {searchPlaces}); const {config} = explorer.searchSync(rootFolder) || {config: undefined}; diff --git a/packages/cli/src/tools/config/types.flow.js b/packages/cli/src/tools/config/types.flow.js index 01901b934..44237485c 100644 --- a/packages/cli/src/tools/config/types.flow.js +++ b/packages/cli/src/tools/config/types.flow.js @@ -8,6 +8,8 @@ import type { InquirerPromptT, DependencyConfigAndroidT, DependencyConfigIOST, + ProjectConfigAndroidT, + ProjectConfigIOST, } from '../types.flow'; /** @@ -45,13 +47,19 @@ export type DependencyConfigT = { platforms: PlatformsT, }; -type _ProjectConfigT = { +export type ConfigT = {| root: string, + reactNativePath: string, + project: { + android?: ProjectConfigAndroidT, + ios?: ProjectConfigIOST, + [key: string]: any, + }, dependencies: { [key: string]: { platforms: { - android: DependencyConfigAndroidT | null, - ios: DependencyConfigIOST | null, + android?: DependencyConfigAndroidT | null, + ios?: DependencyConfigIOST | null, [key: string]: any, }, assets: string[], @@ -65,12 +73,18 @@ type _ProjectConfigT = { platforms: Array, providesModuleNodeModules: Array, }, -}; +|}; -export type RawProjectConfigT = _ProjectConfigT & { - reactNativePath: string | null, -}; +export type RawConfigT = {| + ...ConfigT, + reactNativePath: ?string, +|}; -export type ProjectConfigT = _ProjectConfigT & { - reactNativePath: string, +export type UserConfigT = { + ...RawConfigT, + project: { + android?: AndroidConfigParamsT, + ios?: IOSConfigParamsT, + [key: string]: any, + }, }; diff --git a/packages/cli/src/tools/types.flow.js b/packages/cli/src/tools/types.flow.js index 32682a3e2..bd7ee7973 100644 --- a/packages/cli/src/tools/types.flow.js +++ b/packages/cli/src/tools/types.flow.js @@ -2,7 +2,7 @@ * @flow */ -import {type ProjectConfigT as ConfigT} from './config/types.flow'; +import {type ConfigT} from './config/types.flow'; export type ContextT = ConfigT; From 38e2cbad7f06b8c6319547018bc88543e4d8f5ef Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 09:54:58 +0200 Subject: [PATCH 02/46] wip 3 --- packages/cli/src/commands/link/link.js | 22 ---------------- packages/cli/src/tools/config/schema.js | 29 ++++++++++++++++++++- packages/cli/src/tools/config/types.flow.js | 3 ++- packages/cli/src/tools/types.flow.js | 12 +++++++++ 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/packages/cli/src/commands/link/link.js b/packages/cli/src/commands/link/link.js index 6b6652983..aab8c724d 100644 --- a/packages/cli/src/commands/link/link.js +++ b/packages/cli/src/commands/link/link.js @@ -34,28 +34,6 @@ type FlagsType = { function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { let platforms = ctx.platforms; let project = ctx.project; - try { - logger.debug( - 'Available platforms: ' + - `${Object.getOwnPropertyNames(platforms) - .map(platform => getPlatformName(platform)) - .join(', ')}`, - ); - if (opts.platforms) { - platforms = pick(platforms, opts.platforms); - } - logger.debug( - 'Targeted platforms: ' + - `${Object.getOwnPropertyNames(platforms) - .map(platform => getPlatformName(platform)) - .join(', ')}`, - ); - } catch (err) { - logger.error( - 'No package found. Are you sure this is a React Native project?', - ); - return Promise.reject(err); - } if (rawPackageName === undefined) { logger.debug( diff --git a/packages/cli/src/tools/config/schema.js b/packages/cli/src/tools/config/schema.js index 93f058cb9..98f622863 100644 --- a/packages/cli/src/tools/config/schema.js +++ b/packages/cli/src/tools/config/schema.js @@ -118,5 +118,32 @@ export const projectConfig = t }), reactNativePath: t.string(), root: t.string(), + project: map( + t.string(), + t + .object({ + ios: t + .object({ + project: t.string(), + sharedLibraries: t.array().items(t.string()), + libraryFolder: t.string(), + }) + .default({}), + android: t + .object({ + sourceDir: t.string(), + manifestPath: t.string(), + packageName: t.string(), + packageFolder: t.string(), + mainFilePath: t.string(), + stringsPath: t.string(), + settingsGradlePath: t.string(), + assetsPath: t.string(), + buildGradlePath: t.string(), + }) + .default({}), + }) + .default(), + ).default(), }) - .default({}); + .default(); diff --git a/packages/cli/src/tools/config/types.flow.js b/packages/cli/src/tools/config/types.flow.js index 44237485c..80361564f 100644 --- a/packages/cli/src/tools/config/types.flow.js +++ b/packages/cli/src/tools/config/types.flow.js @@ -4,6 +4,7 @@ import type { AndroidConfigParamsT, + AndroidProjectConfigParamsT, IOSConfigParamsT, InquirerPromptT, DependencyConfigAndroidT, @@ -83,7 +84,7 @@ export type RawConfigT = {| export type UserConfigT = { ...RawConfigT, project: { - android?: AndroidConfigParamsT, + android?: AndroidProjectConfigParamsT, ios?: IOSConfigParamsT, [key: string]: any, }, diff --git a/packages/cli/src/tools/types.flow.js b/packages/cli/src/tools/types.flow.js index bd7ee7973..e9844a0eb 100644 --- a/packages/cli/src/tools/types.flow.js +++ b/packages/cli/src/tools/types.flow.js @@ -81,6 +81,18 @@ export type IOSConfigParamsT = { libraryFolder?: string, }; +export type AndroidProjectConfigParamsT = { + sourceDir?: string, + manifestPath?: string, + packageName?: string, + packageFolder?: string, + mainFilePath?: string, + stringsPath?: string, + settingsGradlePath?: string, + assetsPath?: string, + buildGradlePath?: string, +}; + export type ProjectConfigIOST = {}; export type DependencyConfigIOST = ProjectConfigIOST; From 1d0ea0db82899e7c4dc0035f2bc1b05cefe43e71 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 09:58:35 +0200 Subject: [PATCH 03/46] Clean up diff --- packages/cli/src/commands/link/link.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/cli/src/commands/link/link.js b/packages/cli/src/commands/link/link.js index aab8c724d..4f0753f4b 100644 --- a/packages/cli/src/commands/link/link.js +++ b/packages/cli/src/commands/link/link.js @@ -35,6 +35,24 @@ function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { let platforms = ctx.platforms; let project = ctx.project; + logger.debug( + 'Available platforms: ' + + `${Object.getOwnPropertyNames(platforms) + .map(platform => getPlatformName(platform)) + .join(', ')}`, + ); + + if (opts.platforms) { + platforms = pick(platforms, opts.platforms); + } + + logger.debug( + 'Targeted platforms: ' + + `${Object.getOwnPropertyNames(platforms) + .map(platform => getPlatformName(platform)) + .join(', ')}`, + ); + if (rawPackageName === undefined) { logger.debug( 'No package name provided, will attemp to link all possible packages.', From 365c6eb44dddc154d5efa6bc378ac31925317449 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 09:59:21 +0200 Subject: [PATCH 04/46] Loggers are unneccessary here --- packages/cli/src/commands/link/link.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/packages/cli/src/commands/link/link.js b/packages/cli/src/commands/link/link.js index 4f0753f4b..d26edf55c 100644 --- a/packages/cli/src/commands/link/link.js +++ b/packages/cli/src/commands/link/link.js @@ -35,24 +35,10 @@ function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { let platforms = ctx.platforms; let project = ctx.project; - logger.debug( - 'Available platforms: ' + - `${Object.getOwnPropertyNames(platforms) - .map(platform => getPlatformName(platform)) - .join(', ')}`, - ); - if (opts.platforms) { platforms = pick(platforms, opts.platforms); } - logger.debug( - 'Targeted platforms: ' + - `${Object.getOwnPropertyNames(platforms) - .map(platform => getPlatformName(platform)) - .join(', ')}`, - ); - if (rawPackageName === undefined) { logger.debug( 'No package name provided, will attemp to link all possible packages.', From 6c033448193fa50a92b6790ccef19c774167e9fb Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 10:10:37 +0200 Subject: [PATCH 05/46] Fix some Flowtype compatibilities between link and config --- packages/cli/src/tools/config/index.js | 17 +++++++----- packages/cli/src/tools/config/types.flow.js | 30 +++++++-------------- packages/cli/src/tools/types.flow.js | 29 ++++++++++++-------- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.js index ba78eee56..a5e1bba64 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.js @@ -93,13 +93,16 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { }, // $FlowExpectedError: This getter is safe get project() { - return Object.keys(this.platforms).reduce((project, platform) => { - project[platform] = this.platforms[platform].projectConfig( - projectRoot, - userConfig.project, - ); - return project; - }, {}); + return Object.keys(this.platforms).reduce( + (project, platform) => { + project[platform] = this.platforms[platform].projectConfig( + projectRoot, + userConfig.project, + ); + return project; + }, + {ios: null, android: null}, + ); }, }: RawConfigT), ); diff --git a/packages/cli/src/tools/config/types.flow.js b/packages/cli/src/tools/config/types.flow.js index 80361564f..1a4a4a83a 100644 --- a/packages/cli/src/tools/config/types.flow.js +++ b/packages/cli/src/tools/config/types.flow.js @@ -3,14 +3,15 @@ */ import type { - AndroidConfigParamsT, - AndroidProjectConfigParamsT, - IOSConfigParamsT, + DependencyParamsAndroidT, + ProjectParamsAndroidT, + ProjectParamsIOST, InquirerPromptT, DependencyConfigAndroidT, DependencyConfigIOST, ProjectConfigAndroidT, ProjectConfigIOST, + PlatformsT, } from '../types.flow'; /** @@ -22,22 +23,11 @@ type HooksT = { postlink?: string, }; -/** - * A map with additional platforms that ship with a dependency. - */ -export type PlatformsT = { - [key: string]: { - dependencyConfig?: Function, - projectConfig?: Function, - linkConfig?: Function, - }, -}; - export type DependencyConfigT = { dependency: { platforms: { - android?: AndroidConfigParamsT, - ios?: IOSConfigParamsT, + android?: DependencyParamsAndroidT, + ios?: ProjectParamsIOST, [key: string]: any, }, assets: string[], @@ -52,8 +42,8 @@ export type ConfigT = {| root: string, reactNativePath: string, project: { - android?: ProjectConfigAndroidT, - ios?: ProjectConfigIOST, + android: ?ProjectConfigAndroidT, + ios: ?ProjectConfigIOST, [key: string]: any, }, dependencies: { @@ -84,8 +74,8 @@ export type RawConfigT = {| export type UserConfigT = { ...RawConfigT, project: { - android?: AndroidProjectConfigParamsT, - ios?: IOSConfigParamsT, + android?: ProjectParamsAndroidT, + ios?: ProjectParamsIOST, [key: string]: any, }, }; diff --git a/packages/cli/src/tools/types.flow.js b/packages/cli/src/tools/types.flow.js index e9844a0eb..63669d4a7 100644 --- a/packages/cli/src/tools/types.flow.js +++ b/packages/cli/src/tools/types.flow.js @@ -44,9 +44,14 @@ export type CommandT = LocalCommandT | ProjectCommandT; /** * Config of a single platform */ -export type PlatformConfigT = { - projectConfig: (string, ParamsT) => ?ProjectConfigT, - dependencyConfig: (string, ParamsT) => ?DependencyConfigT, +export type PlatformConfigT< + ProjectConfigT, + ProjectParamsT, + DependencyConfigT, + DependencyParamsT, +> = { + projectConfig: (string, ProjectParamsT) => ?ProjectConfigT, + dependencyConfig: (string, DependencyParamsT) => ?DependencyConfigT, /** * @todo(grabbou): This should not be part of the "core". It should be * specific to `link` and `unlink`. Remove it from here soon. @@ -68,20 +73,20 @@ export type PlatformConfigT = { }, }; -export type AndroidConfigParamsT = { +export type DependencyParamsAndroidT = { sourceDir?: string, manifestPath?: string, packageImportPath?: string, packageInstance?: string, }; -export type IOSConfigParamsT = { +export type ProjectParamsIOST = { project?: string, sharedLibraries?: string[], libraryFolder?: string, }; -export type AndroidProjectConfigParamsT = { +export type ProjectParamsAndroidT = { sourceDir?: string, manifestPath?: string, packageName?: string, @@ -136,15 +141,17 @@ export type DependenciesConfig = { export type PlatformsT = { ios: PlatformConfigT< ProjectConfigIOST, + ProjectParamsIOST, DependencyConfigIOST, - IOSConfigParamsT, + ProjectParamsIOST, >, android: PlatformConfigT< ProjectConfigAndroidT, + ProjectParamsAndroidT, DependencyConfigAndroidT, - AndroidConfigParamsT, + DependencyParamsAndroidT, >, - [name: string]: PlatformConfigT, + [name: string]: PlatformConfigT, }; export type InquirerPromptT = any; @@ -156,8 +163,8 @@ export type PackageConfigurationT = { assets?: string[], commands?: {[name: string]: string}, params?: InquirerPromptT[], - android: AndroidConfigParamsT, - ios: IOSConfigParamsT, + android: DependencyParamsAndroidT, + ios: ProjectParamsIOST, plugin?: string | Array, platform?: string, From dc0958825868dde91dd069eacb43d008135b6517 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 10:24:23 +0200 Subject: [PATCH 06/46] Update snapshots --- .../tools/config/__tests__/__snapshots__/index.js.snap | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index.js.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index.js.snap index aaa2e0cb7..1efb53808 100644 --- a/packages/cli/src/tools/config/__tests__/__snapshots__/index.js.snap +++ b/packages/cli/src/tools/config/__tests__/__snapshots__/index.js.snap @@ -33,6 +33,10 @@ Object { "android": Object {}, "ios": Object {}, }, + "project": Object { + "android": null, + "ios": null, + }, "reactNativePath": ".", "root": "<>", } @@ -50,6 +54,10 @@ Object { "android": Object {}, "ios": Object {}, }, + "project": Object { + "android": null, + "ios": null, + }, "reactNativePath": ".", "root": "<>", } From e86bd577ff917d6aba91c599edf8b6f48d4cf71b Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 10:31:25 +0200 Subject: [PATCH 07/46] Misc inside config --- .flowconfig | 1 + packages/cli/src/tools/config/index.js | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.flowconfig b/.flowconfig index be12bc31a..87fb9288f 100644 --- a/.flowconfig +++ b/.flowconfig @@ -43,6 +43,7 @@ module.ignore_non_literal_requires=true all=warn unnecessary-optional-chain=off dynamic-export=off +unsafe-getters-setters=off # There is an ESLint rule for this unclear-type=off diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.js index a5e1bba64..b9b8a6baa 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.js @@ -91,7 +91,6 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { providesModuleNodeModules: [], platforms: [], }, - // $FlowExpectedError: This getter is safe get project() { return Object.keys(this.platforms).reduce( (project, platform) => { @@ -107,7 +106,10 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { }: RawConfigT), ); - // @todo(grabbou): make this explicit + /** + * All config properties are deep-merged with user provided settings except for + * the project, which is calculated + */ const config: ConfigT = merge(inferredConfig, omit(userConfig, 'project')); if (config.reactNativePath === null) { From 3d67a0eb5fd93c0afbaf1223c428c47b0143bc81 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 11:09:58 +0200 Subject: [PATCH 08/46] WIP integration --- packages/cli/src/commands/link/link.js | 56 ++++++++------ packages/cli/src/commands/link/linkAll.js | 10 +-- .../cli/src/commands/link/linkDependency.js | 17 +++-- packages/cli/src/tools/config/index.js | 1 + .../src/tools/config/readConfigFromDisk.js | 6 +- packages/cli/src/tools/config/schema.js | 62 ++++++++------- packages/cli/src/tools/config/types.flow.js | 75 ++++++++++++------- 7 files changed, 133 insertions(+), 94 deletions(-) diff --git a/packages/cli/src/commands/link/link.js b/packages/cli/src/commands/link/link.js index d26edf55c..768e3d7ad 100644 --- a/packages/cli/src/commands/link/link.js +++ b/packages/cli/src/commands/link/link.js @@ -8,18 +8,18 @@ */ import {pick} from 'lodash'; +import dedent from 'dedent'; + import {type ContextT} from '../../tools/types.flow'; import promiseWaterfall from './promiseWaterfall'; import logger from '../../tools/logger'; -import getDependencyConfig from './getDependencyConfig'; import commandStub from './commandStub'; import promisify from './promisify'; -import getProjectConfig from './getProjectConfig'; + import linkDependency from './linkDependency'; import linkAssets from './linkAssets'; import linkAll from './linkAll'; -import getPlatforms, {getPlatformName} from '../../tools/getPlatforms'; type FlagsType = { platforms?: Array, @@ -31,7 +31,11 @@ type FlagsType = { * @param args If optional argument [packageName] is provided, * only that package is processed. */ -function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { +async function link( + [rawPackageName]: Array, + ctx: ContextT, + opts: FlagsType, +) { let platforms = ctx.platforms; let project = ctx.project; @@ -43,30 +47,42 @@ function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { logger.debug( 'No package name provided, will attemp to link all possible packages.', ); - return linkAll(ctx, platforms, project); + await linkAll(ctx, platforms); + return; } - logger.debug(`Package to link: ${rawPackageName}`); - // Trim the version / tag out of the package name (eg. package@latest) const packageName = rawPackageName.replace(/^(.+?)(@.+?)$/gi, '$1'); - const dependencyConfig = getDependencyConfig(ctx, platforms, packageName); + if (!Object.keys(ctx.dependencies).includes(packageName)) { + throw new Error(dedent` + Unknown dependency. + + Make sure that the package you are trying to link is already installed + in your "node_modules" and present in your "package.json" dependencies. + `); + } + + const {[packageName]: dependency} = ctx.dependencies; + + logger.debug(`Package to link: ${rawPackageName}`); const tasks = [ - () => promisify(dependencyConfig.commands.prelink || commandStub), - () => linkDependency(platforms, project, dependencyConfig), - () => promisify(dependencyConfig.commands.postlink || commandStub), - () => linkAssets(platforms, project, dependencyConfig.assets), + () => promisify(dependency.hooks.prelink || commandStub), + () => linkDependency(platforms, project, dependency), + () => promisify(dependency.hooks.postlink || commandStub), + () => linkAssets(platforms, project, dependency.assets), ]; - return promiseWaterfall(tasks).catch(err => { - logger.error( - `Something went wrong while linking. Error: ${err.message} \n` + - 'Please file an issue here: https://github.com/react-native-community/react-native-cli/issues', - ); - throw err; - }); + try { + await promiseWaterfall(tasks); + } catch (err) { + throw new Error(dedent` + Something went wrong while linking. Reason: ${err.message} + + Please file an issue here: https://github.com/react-native-community/react-native-cli/issues + `); + } } export const func = link; @@ -84,5 +100,3 @@ export default { }, ], }; - -// link; diff --git a/packages/cli/src/commands/link/linkAll.js b/packages/cli/src/commands/link/linkAll.js index 9ba413763..20d2064f3 100644 --- a/packages/cli/src/commands/link/linkAll.js +++ b/packages/cli/src/commands/link/linkAll.js @@ -20,11 +20,7 @@ import linkDependency from './linkDependency'; const dedupeAssets = (assets: Array): Array => uniqBy(assets, asset => path.basename(asset)); -function linkAll( - context: ContextT, - platforms: PlatformsT, - project: ProjectConfigT, -) { +function linkAll(context: ContextT, platforms: PlatformsT) { logger.warn( 'Running `react-native link` without package name is deprecated and will be removed ' + 'in next release. If you use this command to link your project assets, ' + @@ -47,9 +43,9 @@ function linkAll( const tasks = flatten( dependenciesConfig.map(config => [ () => promisify(config.commands.prelink || commandStub), - () => linkDependency(platforms, project, config), + () => linkDependency(platforms, context.project, config), () => promisify(config.commands.postlink || commandStub), - () => linkAssets(platforms, project, assets), + () => linkAssets(platforms, context.project, assets), ]), ); diff --git a/packages/cli/src/commands/link/linkDependency.js b/packages/cli/src/commands/link/linkDependency.js index e669aae29..3ba0221d7 100644 --- a/packages/cli/src/commands/link/linkDependency.js +++ b/packages/cli/src/commands/link/linkDependency.js @@ -1,10 +1,10 @@ // @flow import type { - PlatformsT, + DependencyConfigT, ProjectConfigT, - DependenciesConfig, -} from '../../tools/types.flow'; + PlatformsT, +} from '../../tools/config/types.flow'; import logger from '../../tools/logger'; import pollParams from './pollParams'; import {getPlatformName} from '../../tools/getPlatforms'; @@ -12,12 +12,12 @@ import {getPlatformName} from '../../tools/getPlatforms'; const linkDependency = async ( platforms: PlatformsT, project: ProjectConfigT, - dependency: DependenciesConfig, + dependency: DependencyConfigT, ) => { const params = await pollParams(dependency.params); Object.keys(platforms || {}).forEach(platform => { - if (!project[platform] || !dependency.config[platform]) { + if (!project[platform] || !dependency.platforms[platform]) { return; } @@ -33,7 +33,7 @@ const linkDependency = async ( const isInstalled = linkConfig.isInstalled( project[platform], dependency.name, - dependency.config[platform], + dependency.platforms[platform], ); if (isInstalled) { @@ -51,9 +51,10 @@ const linkDependency = async ( linkConfig.register( dependency.name, - dependency.config[platform] || {}, + // $FlowExpectedError: We already checked if dependency.platforms[platform] exists + dependency.platforms[platform], params, - // $FlowFixMe: We check if project[platform] exists on line 42 + // $FlowFixMe: We already checked if project[platform] exists project[platform], ); diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.js index b9b8a6baa..4eddcc115 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.js @@ -43,6 +43,7 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { // $FlowIssue: Computed getters are not yet supported. get [dependencyName]() { return { + name: dependencyName, platforms: Object.keys(acc.platforms).reduce( (dependency, platform) => { dependency[platform] = acc.platforms[ diff --git a/packages/cli/src/tools/config/readConfigFromDisk.js b/packages/cli/src/tools/config/readConfigFromDisk.js index 3ed00a4d4..90aad6cf5 100644 --- a/packages/cli/src/tools/config/readConfigFromDisk.js +++ b/packages/cli/src/tools/config/readConfigFromDisk.js @@ -7,7 +7,7 @@ import Joi from 'joi'; import cosmiconfig from 'cosmiconfig'; import path from 'path'; -import {type DependencyConfigT, type UserConfigT} from './types.flow'; +import {type UserDependencyConfigT, type UserConfigT} from './types.flow'; import {JoiError} from '../errors'; @@ -43,7 +43,7 @@ export function readConfigFromDisk(rootFolder: string): UserConfigT { */ export function readDependencyConfigFromDisk( rootFolder: string, -): DependencyConfigT { +): UserDependencyConfigT { const explorer = cosmiconfig('react-native', { stopDir: rootFolder, searchPlaces, @@ -65,7 +65,7 @@ export function readDependencyConfigFromDisk( */ export function readLegacyDependencyConfigFromDisk( rootFolder: string, -): ?DependencyConfigT { +): ?UserDependencyConfigT { const {rnpm: config, name} = require(path.join(rootFolder, 'package.json')); if (!config) { diff --git a/packages/cli/src/tools/config/schema.js b/packages/cli/src/tools/config/schema.js index 98f622863..91b5215ed 100644 --- a/packages/cli/src/tools/config/schema.js +++ b/packages/cli/src/tools/config/schema.js @@ -10,7 +10,7 @@ const map = (key, value) => .pattern(key, value); /** - * Schema for DependencyConfigT + * Schema for UserDependencyConfigT */ export const dependencyConfig = t .object({ @@ -118,32 +118,38 @@ export const projectConfig = t }), reactNativePath: t.string(), root: t.string(), - project: map( - t.string(), - t - .object({ - ios: t - .object({ - project: t.string(), - sharedLibraries: t.array().items(t.string()), - libraryFolder: t.string(), - }) - .default({}), - android: t - .object({ - sourceDir: t.string(), - manifestPath: t.string(), - packageName: t.string(), - packageFolder: t.string(), - mainFilePath: t.string(), - stringsPath: t.string(), - settingsGradlePath: t.string(), - assetsPath: t.string(), - buildGradlePath: t.string(), - }) - .default({}), - }) - .default(), - ).default(), + project: t.object({ + platforms: map( + t.string(), + t + .object({ + ios: t + .object({ + project: t.string(), + sharedLibraries: t.array().items(t.string()), + libraryFolder: t.string(), + }) + .default({}), + android: t + .object({ + sourceDir: t.string(), + manifestPath: t.string(), + packageName: t.string(), + packageFolder: t.string(), + mainFilePath: t.string(), + stringsPath: t.string(), + settingsGradlePath: t.string(), + assetsPath: t.string(), + buildGradlePath: t.string(), + }) + .default({}), + }) + .default(), + ).default(), + assets: t + .array() + .items(t.string()) + .default([]), + }), }) .default(); diff --git a/packages/cli/src/tools/config/types.flow.js b/packages/cli/src/tools/config/types.flow.js index 1a4a4a83a..f3aa9fbbb 100644 --- a/packages/cli/src/tools/config/types.flow.js +++ b/packages/cli/src/tools/config/types.flow.js @@ -11,33 +11,9 @@ import type { DependencyConfigIOST, ProjectConfigAndroidT, ProjectConfigIOST, - PlatformsT, + PlatformConfigT, } from '../types.flow'; -/** - * A map of hooks to run pre/post some of the CLI actions - */ -type HooksT = { - [key: string]: string, - prelink?: string, - postlink?: string, -}; - -export type DependencyConfigT = { - dependency: { - platforms: { - android?: DependencyParamsAndroidT, - ios?: ProjectParamsIOST, - [key: string]: any, - }, - assets: string[], - hooks: HooksT, - params: InquirerPromptT[], - }, - commands: string[], - platforms: PlatformsT, -}; - export type ConfigT = {| root: string, reactNativePath: string, @@ -48,17 +24,36 @@ export type ConfigT = {| }, dependencies: { [key: string]: { + name: string, platforms: { android?: DependencyConfigAndroidT | null, ios?: DependencyConfigIOST | null, [key: string]: any, }, assets: string[], - hooks: HooksT, + hooks: { + [key: string]: string, + prelink?: string, + postlink?: string, + }, params: InquirerPromptT[], }, }, - platforms: PlatformsT, + platforms: { + ios: PlatformConfigT< + ProjectConfigIOST, + ProjectParamsIOST, + DependencyConfigIOST, + ProjectParamsIOST, + >, + android: PlatformConfigT< + ProjectConfigAndroidT, + ProjectParamsAndroidT, + DependencyConfigAndroidT, + DependencyParamsAndroidT, + >, + [name: string]: PlatformConfigT, + }, commands: string[], haste: { platforms: Array, @@ -66,6 +61,32 @@ export type ConfigT = {| }, |}; +export type DependencyConfigT = $PropertyType< + $PropertyType, + '[key: string]', +>; + +export type HooksT = $PropertyType; + +export type ProjectConfigT = $PropertyType; + +export type PlatformsT = $PropertyType; + +export type UserDependencyConfigT = { + dependency: { + platforms: { + android?: DependencyParamsAndroidT, + ios?: ProjectParamsIOST, + [key: string]: any, + }, + assets: string[], + hooks: HooksT, + params: InquirerPromptT[], + }, + commands: string[], + platforms: PlatformsT, +}; + export type RawConfigT = {| ...ConfigT, reactNativePath: ?string, From a3d5e5a4ebb55b6229af50b3cb37abb81757c93c Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 11:13:12 +0200 Subject: [PATCH 09/46] Remove async/await for now --- packages/cli/src/commands/link/link.js | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/cli/src/commands/link/link.js b/packages/cli/src/commands/link/link.js index 768e3d7ad..0e118a058 100644 --- a/packages/cli/src/commands/link/link.js +++ b/packages/cli/src/commands/link/link.js @@ -31,11 +31,7 @@ type FlagsType = { * @param args If optional argument [packageName] is provided, * only that package is processed. */ -async function link( - [rawPackageName]: Array, - ctx: ContextT, - opts: FlagsType, -) { +function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { let platforms = ctx.platforms; let project = ctx.project; @@ -47,8 +43,7 @@ async function link( logger.debug( 'No package name provided, will attemp to link all possible packages.', ); - await linkAll(ctx, platforms); - return; + return linkAll(ctx, platforms); } // Trim the version / tag out of the package name (eg. package@latest) @@ -74,15 +69,13 @@ async function link( () => linkAssets(platforms, project, dependency.assets), ]; - try { - await promiseWaterfall(tasks); - } catch (err) { + return promiseWaterfall(tasks).catch(err => { throw new Error(dedent` Something went wrong while linking. Reason: ${err.message} Please file an issue here: https://github.com/react-native-community/react-native-cli/issues `); - } + }); } export const func = link; From 740caef3de07d1fb0a04b15abfe6fe79b3a2d4e1 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 16:05:47 +0200 Subject: [PATCH 10/46] Finish migration, start working on tests --- .../src/commands/link/getDependencyConfig.js | 47 ----------- .../cli/src/commands/link/getPlatformName.js | 12 +++ .../cli/src/commands/link/getProjectConfig.js | 33 -------- .../commands/link/getProjectDependencies.js | 31 ------- packages/cli/src/commands/link/linkAll.js | 69 +++++++-------- packages/cli/src/commands/link/unlink.js | 83 +++++++------------ packages/cli/src/tools/config/findAssets.js | 25 ++++++ packages/cli/src/tools/config/index.js | 51 ++++-------- packages/cli/src/tools/config/makeHook.js | 31 +++++++ .../tools/config/resolveReactNativePath.js | 14 +++- packages/cli/src/tools/config/schema.js | 71 +++++++--------- packages/cli/src/tools/config/types.flow.js | 13 ++- 12 files changed, 197 insertions(+), 283 deletions(-) delete mode 100644 packages/cli/src/commands/link/getDependencyConfig.js create mode 100644 packages/cli/src/commands/link/getPlatformName.js delete mode 100644 packages/cli/src/commands/link/getProjectConfig.js delete mode 100644 packages/cli/src/commands/link/getProjectDependencies.js create mode 100644 packages/cli/src/tools/config/findAssets.js create mode 100644 packages/cli/src/tools/config/makeHook.js diff --git a/packages/cli/src/commands/link/getDependencyConfig.js b/packages/cli/src/commands/link/getDependencyConfig.js deleted file mode 100644 index 7983691c2..000000000 --- a/packages/cli/src/commands/link/getDependencyConfig.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * @flow - */ - -import path from 'path'; -import type { - PlatformsT, - ContextT, - DependenciesConfig, -} from '../../tools/types.flow'; - -import getPackageConfiguration from '../../tools/getPackageConfiguration'; -import getParams from '../../tools/getParams'; -import getHooks from '../../tools/getHooks'; -import getAssets from '../../tools/getAssets'; - -export default function getDependencyConfig( - ctx: ContextT, - availablePlatforms: PlatformsT, - dependency: string, -): DependenciesConfig { - try { - const folder = path.join(ctx.root, 'node_modules', dependency); - const config = getPackageConfiguration(folder); - - const platformConfigs = {ios: undefined, android: undefined}; - - Object.keys(availablePlatforms).forEach(platform => { - platformConfigs[platform] = availablePlatforms[platform].dependencyConfig( - folder, - // $FlowIssue: Flow can't match platform config with its appropriate config function - config[platform] || {}, - ); - }); - - return { - config: platformConfigs, - name: dependency, - path: folder, - commands: getHooks(folder), - assets: getAssets(folder), - params: getParams(folder), - }; - } catch (e) { - throw new Error('Failed to get dependency config'); - } -} diff --git a/packages/cli/src/commands/link/getPlatformName.js b/packages/cli/src/commands/link/getPlatformName.js new file mode 100644 index 000000000..455d9c06c --- /dev/null +++ b/packages/cli/src/commands/link/getPlatformName.js @@ -0,0 +1,12 @@ +/** + * @flow + */ + +const names = { + ios: 'iOS', + android: 'Android', +}; + +export default function getPlatformName(name: string) { + return names[name] || name; +} diff --git a/packages/cli/src/commands/link/getProjectConfig.js b/packages/cli/src/commands/link/getProjectConfig.js deleted file mode 100644 index d3b40c169..000000000 --- a/packages/cli/src/commands/link/getProjectConfig.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @flow - */ - -import type { - PlatformsT, - ContextT, - ProjectConfigT, -} from '../../tools/types.flow'; - -import getPackageConfiguration from '../../tools/getPackageConfiguration'; -import {getPlatformName} from '../../tools/getPlatforms'; -import logger from '../../tools/logger'; - -export default function getProjectConfig( - ctx: ContextT, - availablePlatforms: PlatformsT, -): ProjectConfigT { - const config = getPackageConfiguration(ctx.root); - - const platformConfigs = {ios: undefined, android: undefined}; - - Object.keys(availablePlatforms).forEach(platform => { - logger.debug(`Getting project config for ${getPlatformName(platform)}...`); - platformConfigs[platform] = availablePlatforms[platform].projectConfig( - ctx.root, - // $FlowIssue: Flow can't match platform config with its appropriate config function - config[platform] || {}, - ); - }); - - return platformConfigs; -} diff --git a/packages/cli/src/commands/link/getProjectDependencies.js b/packages/cli/src/commands/link/getProjectDependencies.js deleted file mode 100644 index 9d6c3d4f3..000000000 --- a/packages/cli/src/commands/link/getProjectDependencies.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import path from 'path'; - -/** - * List of projects that should not be treated as projects to be linked. - * - * That includes `react-native` itself and the CLI project (under its real and staging npm package). - */ -const EXCLUDED_PROJECTS = [ - 'react-native', - '@react-native-community/cli', - 'react-native-local-cli-preview', -]; - -/** - * Returns an array of dependencies that should be linked/checked. - */ -export default function getProjectDependencies(cwd: string) { - const pkgJson = require(path.join(cwd, './package.json')); - return (Object.keys(pkgJson.dependencies || {}).filter( - name => EXCLUDED_PROJECTS.includes(name) === false, - ): Array); -} diff --git a/packages/cli/src/commands/link/linkAll.js b/packages/cli/src/commands/link/linkAll.js index 20d2064f3..faa98ae84 100644 --- a/packages/cli/src/commands/link/linkAll.js +++ b/packages/cli/src/commands/link/linkAll.js @@ -1,60 +1,53 @@ -// @flow +/** + * @flow + */ -import {uniqBy, flatten} from 'lodash'; +import {uniqBy, flatMap} from 'lodash'; import path from 'path'; -import type { - ContextT, - PlatformsT, - ProjectConfigT, -} from '../../tools/types.flow'; -import logger from '../../tools/logger'; -import getAssets from '../../tools/getAssets'; -import getProjectDependencies from './getProjectDependencies'; -import getDependencyConfig from './getDependencyConfig'; +import dedent from 'dedent'; + +import type {ContextT, PlatformsT} from '../../tools/types.flow'; + import promiseWaterfall from './promiseWaterfall'; import commandStub from './commandStub'; import promisify from './promisify'; + import linkAssets from './linkAssets'; import linkDependency from './linkDependency'; const dedupeAssets = (assets: Array): Array => uniqBy(assets, asset => path.basename(asset)); -function linkAll(context: ContextT, platforms: PlatformsT) { - logger.warn( - 'Running `react-native link` without package name is deprecated and will be removed ' + - 'in next release. If you use this command to link your project assets, ' + - 'please let us know about your use case here: https://goo.gl/RKTeoc', - ); - - const projectAssets = getAssets(context.root); - const dependencies = getProjectDependencies(context.root); - const dependenciesConfig = dependencies.map(dependency => - getDependencyConfig(context, platforms, dependency), - ); +function linkAll(config: ContextT, platforms: PlatformsT) { + const projectAssets = config.assets; const assets = dedupeAssets( - dependenciesConfig.reduce( - (acc, dependency) => acc.concat(dependency.assets), + Object.keys(config.dependencies).reduce( + (acc, dependency) => acc.concat(config.dependencies[dependency].assets), projectAssets, ), ); - const tasks = flatten( - dependenciesConfig.map(config => [ - () => promisify(config.commands.prelink || commandStub), - () => linkDependency(platforms, context.project, config), - () => promisify(config.commands.postlink || commandStub), - () => linkAssets(platforms, context.project, assets), - ]), - ); + const tasks = flatMap(config.dependencies, dependency => [ + () => + promisify(config.dependencies[dependency].hooks.prelink || commandStub), + () => + linkDependency( + config.platforms, + config.project, + config.dependencies[dependency], + ), + () => + promisify(config.dependencies[dependency].hooks.postlink || commandStub), + () => linkAssets(platforms, config.project, assets), + ]); return promiseWaterfall(tasks).catch(err => { - logger.error( - `Something went wrong while linking. Error: ${err.message} \n` + - 'Please file an issue here: https://github.com/react-native-community/react-native-cli/issues', - ); - throw err; + throw new Error(dedent` + Something went wrong while linking. Reason: ${err.message} + + Please file an issue here: https://github.com/react-native-community/react-native-cli/issues + `); }); } diff --git a/packages/cli/src/commands/link/unlink.js b/packages/cli/src/commands/link/unlink.js index 72f44e8c5..a33f893ad 100644 --- a/packages/cli/src/commands/link/unlink.js +++ b/packages/cli/src/commands/link/unlink.js @@ -7,16 +7,14 @@ * @flow */ -import {flatten, isEmpty, difference} from 'lodash'; +import {flatMap, values, difference} from 'lodash'; import type {ContextT} from '../../tools/types.flow'; +import dedent from 'dedent'; import logger from '../../tools/logger'; -import getProjectConfig from './getProjectConfig'; -import getDependencyConfig from './getDependencyConfig'; -import getProjectDependencies from './getProjectDependencies'; import promiseWaterfall from './promiseWaterfall'; import commandStub from './commandStub'; import promisify from './promisify'; -import getPlatforms, {getPlatformName} from '../../tools/getPlatforms'; +import getPlatformName from './getPlatformName'; const unlinkDependency = ( platforms, @@ -26,7 +24,7 @@ const unlinkDependency = ( otherDependencies, ) => { Object.keys(platforms || {}).forEach(platform => { - if (!project[platform] || !dependency.config[platform]) { + if (!project[platform] || !dependency.platforms[platform]) { return; } @@ -42,7 +40,7 @@ const unlinkDependency = ( const isInstalled = linkConfig.isInstalled( project[platform], packageName, - dependency.config[platform], + dependency.platforms[platform], ); if (!isInstalled) { @@ -58,9 +56,9 @@ const unlinkDependency = ( linkConfig.unregister( packageName, - // $FlowFixMe: We check for existence on line 38 + // $FlowExpectedError: We check for existence on line 38 dependency.config[platform], - // $FlowFixMe: We check for existence on line 38 + // $FlowExpectedError: We check for existence on line 38 project[platform], otherDependencies, ); @@ -82,76 +80,55 @@ const unlinkDependency = ( function unlink(args: Array, ctx: ContextT) { const packageName = args[0]; - let platforms; + const {[packageName]: dependency, ...otherDependencies} = ctx.dependencies; - try { - platforms = getPlatforms(ctx.root); - } catch (err) { - logger.error( - "No package.json found. Are you sure it's a React Native project?", - ); - return Promise.reject(err); + if (!dependency) { + throw new Error(dedent` + Failed to unlink ${packageName}. It appears that the project is not linked yet. + `); } - const allDependencies = getProjectDependencies(ctx.root).map(dependency => - getDependencyConfig(ctx, platforms, dependency), - ); - let otherDependencies; - let dependency; - - try { - const idx = allDependencies.findIndex(p => p.name === packageName); - - if (idx === -1) { - throw new Error(`Project "${packageName}" is not a react-native library`); - } - - otherDependencies = [...allDependencies]; - dependency = otherDependencies.splice(idx, 1)[0]; - } catch (err) { - return Promise.reject(err); - } - - const project = getProjectConfig(ctx, platforms); + const dependencies = values(otherDependencies); const tasks = [ - () => promisify(dependency.commands.preunlink || commandStub), + () => promisify(dependency.hooks.preulink || commandStub), () => unlinkDependency( - platforms, - project, + ctx.platforms, + ctx.project, dependency, packageName, - otherDependencies, + dependencies, ), - () => promisify(dependency.commands.postunlink || commandStub), + () => promisify(dependency.hooks.postunlink || commandStub), ]; return promiseWaterfall(tasks) .then(() => { - // @todo move all these to `tasks` array, just like in - // link + // @todo move all these to `tasks` array + // @todo it is possible we could be unlinking some project assets in case of duplicate const assets = difference( dependency.assets, - flatten(allDependencies, d => d.assets), + flatMap(dependencies, d => d.assets), ); - if (isEmpty(assets)) { + if (assets.length === 0) { return; } - Object.keys(platforms || {}).forEach(platform => { + Object.keys(ctx.platforms || {}).forEach(platform => { const linkConfig = - platforms[platform] && - platforms[platform].linkConfig && - platforms[platform].linkConfig(); - if (!linkConfig || !linkConfig.unlinkAssets || !project[platform]) { + ctx.platforms[platform] && + ctx.platforms[platform].linkConfig && + ctx.platforms[platform].linkConfig(); + if (!linkConfig || !linkConfig.unlinkAssets || !ctx.project[platform]) { return; } logger.info(`Unlinking assets from ${platform} project`); - // $FlowFixMe: We check for platorm existence on line 150 - linkConfig.unlinkAssets(assets, project[platform]); + + // $FlowFixMe: We check for platorm existence above + linkConfig.unlinkAssets(assets, ctx.project[platform]); }); logger.info( diff --git a/packages/cli/src/tools/config/findAssets.js b/packages/cli/src/tools/config/findAssets.js new file mode 100644 index 000000000..9f35e5c0c --- /dev/null +++ b/packages/cli/src/tools/config/findAssets.js @@ -0,0 +1,25 @@ +/** + * @flow + */ + +import glob from 'glob'; +import path from 'path'; + +const findAssetsInFolder = folder => + glob.sync(path.join(folder, '**'), {nodir: true}); + +/** + * Given an array of assets folders, e.g. ['Fonts', 'Images'], + * it globs in them to find all files that can be copied. + * + * It returns an array of absolute paths to files found. + */ +export default function findAssets(folder: string, assets: string[]) { + return (assets || []) + .map(asset => path.join(folder, asset)) + .reduce( + (acc, assetPath) => + (acc.concat(findAssetsInFolder(assetPath)): Array), + [], + ); +} diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.js index 4eddcc115..15b1c4719 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.js @@ -1,26 +1,27 @@ /** * @flow */ -import dedent from 'dedent'; import path from 'path'; import merge from 'deepmerge'; -import {omit} from 'lodash'; +import {mapValues} from 'lodash'; import findDependencies from './findDependencies'; +import resolveReactNativePath from './resolveReactNativePath'; +import findAssets from './findAssets'; +import makeHook from './makeHook'; import { readConfigFromDisk, readDependencyConfigFromDisk, readLegacyDependencyConfigFromDisk, } from './readConfigFromDisk'; -import {type ConfigT, type RawConfigT} from './types.flow'; +import {type ConfigT} from './types.flow'; /** * Built-in platforms */ import * as ios from '../ios'; import * as android from '../android'; -import resolveReactNativePath from './resolveReactNativePath'; /** * Loads CLI configuration @@ -29,7 +30,7 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { const userConfig = readConfigFromDisk(projectRoot); const inferredConfig = findDependencies(projectRoot).reduce( - (acc: RawConfigT, dependencyName) => { + (acc: ConfigT, dependencyName) => { const root = path.join(projectRoot, 'node_modules', dependencyName); const config = @@ -56,8 +57,8 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { }, {}, ), - assets: config.dependency.assets, - hooks: config.dependency.hooks, + assets: findAssets(root, config.dependency.assets), + hooks: mapValues(config.dependency.hooks, makeHook), params: config.dependency.params, }; }, @@ -81,9 +82,11 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { }, ({ root: projectRoot, - reactNativePath: resolveReactNativePath(projectRoot), + reactNativePath: + userConfig.reactNativePath || resolveReactNativePath(projectRoot), dependencies: {}, - commands: [], + commands: userConfig.commands, + assets: findAssets(projectRoot, userConfig.assets), platforms: { ios, android, @@ -97,38 +100,20 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { (project, platform) => { project[platform] = this.platforms[platform].projectConfig( projectRoot, - userConfig.project, + userConfig.project[platform], ); return project; }, {ios: null, android: null}, ); }, - }: RawConfigT), + }: ConfigT), ); - /** - * All config properties are deep-merged with user provided settings except for - * the project, which is calculated - */ - const config: ConfigT = merge(inferredConfig, omit(userConfig, 'project')); - - if (config.reactNativePath === null) { - throw new Error(dedent` - Unable to find React Native files. Make sure "react-native" module is installed - in your project dependencies. - - If you are using React Native from a non-standard location, consider setting: - { - "react-native": { - "reactNativePath": "./path/to/react-native" - } - } - in your \`package.json\`. - `); - } - - return config; + return { + ...inferredConfig, + dependencies: merge(inferredConfig.dependencies, userConfig.dependencies), + }; } export default loadConfig; diff --git a/packages/cli/src/tools/config/makeHook.js b/packages/cli/src/tools/config/makeHook.js new file mode 100644 index 000000000..2eaad64db --- /dev/null +++ b/packages/cli/src/tools/config/makeHook.js @@ -0,0 +1,31 @@ +/** + * @flow + */ + +import {spawn} from 'child_process'; + +export default function makeCommand(command: string) { + return (cb: Function) => { + if (!cb) { + throw new Error( + `You missed a callback function for the ${command} command`, + ); + } + + const args = command.split(' '); + const cmd = args.shift(); + + const commandProcess = spawn(cmd, args, { + stdio: 'inherit', + stdin: 'inherit', + }); + + commandProcess.on('close', code => { + if (code) { + throw new Error(`Error occurred during executing "${command}" command`); + } + + cb(); + }); + }; +} diff --git a/packages/cli/src/tools/config/resolveReactNativePath.js b/packages/cli/src/tools/config/resolveReactNativePath.js index 422a10249..bf1facd66 100644 --- a/packages/cli/src/tools/config/resolveReactNativePath.js +++ b/packages/cli/src/tools/config/resolveReactNativePath.js @@ -2,6 +2,7 @@ * @flow */ import path from 'path'; +import dedent from 'dedent'; /** * Finds path to React Native inside `node_modules` or throws @@ -16,6 +17,17 @@ export default function resolveReactNativePath(root: string) { }), ); } catch (_ignored) { - return null; + throw new Error(dedent` + Unable to find React Native files. Make sure "react-native" module is installed + in your project dependencies. + + If you are using React Native from a non-standard location, consider setting: + { + "react-native": { + "reactNativePath": "./path/to/react-native" + } + } + in your \`package.json\`. + `); } } diff --git a/packages/cli/src/tools/config/schema.js b/packages/cli/src/tools/config/schema.js index 91b5215ed..067395c52 100644 --- a/packages/cli/src/tools/config/schema.js +++ b/packages/cli/src/tools/config/schema.js @@ -39,7 +39,7 @@ export const dependencyConfig = t .array() .items(t.string()) .default([]), - hooks: map(t.string(), t.string()).default(), + hooks: map(t.string(), t.string()).default({}), params: t .array() .items( @@ -110,46 +110,39 @@ export const projectConfig = t ), }) .allow(null), - ), - commands: t.array().items(t.string()), - haste: t.object({ - providesModuleNodeModules: t.array().items(t.string()), - platforms: t.array().items(t.string()), - }), + ).default({}), reactNativePath: t.string(), - root: t.string(), - project: t.object({ - platforms: map( - t.string(), - t + project: map(t.string(), t.any()) + .keys({ + ios: t .object({ - ios: t - .object({ - project: t.string(), - sharedLibraries: t.array().items(t.string()), - libraryFolder: t.string(), - }) - .default({}), - android: t - .object({ - sourceDir: t.string(), - manifestPath: t.string(), - packageName: t.string(), - packageFolder: t.string(), - mainFilePath: t.string(), - stringsPath: t.string(), - settingsGradlePath: t.string(), - assetsPath: t.string(), - buildGradlePath: t.string(), - }) - .default({}), + project: t.string(), + sharedLibraries: t.array().items(t.string()), + libraryFolder: t.string(), }) - .default(), - ).default(), - assets: t - .array() - .items(t.string()) - .default([]), - }), + .default({}), + android: t + .object({ + sourceDir: t.string(), + manifestPath: t.string(), + packageName: t.string(), + packageFolder: t.string(), + mainFilePath: t.string(), + stringsPath: t.string(), + settingsGradlePath: t.string(), + assetsPath: t.string(), + buildGradlePath: t.string(), + }) + .default({}), + }) + .default(), + assets: t + .array() + .items(t.string()) + .default([]), + commands: t + .array() + .items(t.string()) + .default([]), }) .default(); diff --git a/packages/cli/src/tools/config/types.flow.js b/packages/cli/src/tools/config/types.flow.js index f3aa9fbbb..7e679a00a 100644 --- a/packages/cli/src/tools/config/types.flow.js +++ b/packages/cli/src/tools/config/types.flow.js @@ -22,6 +22,7 @@ export type ConfigT = {| ios: ?ProjectConfigIOST, [key: string]: any, }, + assets: string[], dependencies: { [key: string]: { name: string, @@ -75,8 +76,8 @@ export type PlatformsT = $PropertyType; export type UserDependencyConfigT = { dependency: { platforms: { - android?: DependencyParamsAndroidT, - ios?: ProjectParamsIOST, + android: DependencyParamsAndroidT, + ios: ProjectParamsIOST, [key: string]: any, }, assets: string[], @@ -87,13 +88,9 @@ export type UserDependencyConfigT = { platforms: PlatformsT, }; -export type RawConfigT = {| - ...ConfigT, - reactNativePath: ?string, -|}; - export type UserConfigT = { - ...RawConfigT, + ...$Diff, + reactNativePath: ?string, project: { android?: ProjectParamsAndroidT, ios?: ProjectParamsIOST, From bace218af8ec1370a2386ceb7645efa768949476 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 16:08:04 +0200 Subject: [PATCH 11/46] Remove unused files --- packages/cli/src/cliEntry.js | 4 +- packages/cli/src/tools/findPlugins.js | 126 ------------------ packages/cli/src/tools/getAssets.js | 34 ----- packages/cli/src/tools/getHooks.js | 44 ------ .../cli/src/tools/getPackageConfiguration.js | 14 -- packages/cli/src/tools/getParams.js | 10 -- packages/cli/src/tools/getPlatforms.js | 56 -------- 7 files changed, 3 insertions(+), 285 deletions(-) delete mode 100644 packages/cli/src/tools/findPlugins.js delete mode 100644 packages/cli/src/tools/getAssets.js delete mode 100644 packages/cli/src/tools/getHooks.js delete mode 100644 packages/cli/src/tools/getPackageConfiguration.js delete mode 100644 packages/cli/src/tools/getParams.js delete mode 100644 packages/cli/src/tools/getPlatforms.js diff --git a/packages/cli/src/cliEntry.js b/packages/cli/src/cliEntry.js index 1b69ccee7..fbbaa8c64 100644 --- a/packages/cli/src/cliEntry.js +++ b/packages/cli/src/cliEntry.js @@ -18,7 +18,6 @@ import {getCommands} from './commands'; import init from './commands/init/init'; import assertRequiredOptions from './tools/assertRequiredOptions'; import logger from './tools/logger'; -import findPlugins from './tools/findPlugins'; import {setProjectDir} from './tools/PackageManager'; import pkgJson from '../package.json'; import loadConfig from './tools/config'; @@ -170,6 +169,9 @@ async function setupAndRun() { logger.setVerbose(commander.verbose); } +// @todo replace this +const findPlugins = () => {}; + export default { run, init, diff --git a/packages/cli/src/tools/findPlugins.js b/packages/cli/src/tools/findPlugins.js deleted file mode 100644 index 3ae92775c..000000000 --- a/packages/cli/src/tools/findPlugins.js +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import path from 'path'; -import {union, uniq, flatten} from 'lodash'; - -const RNPM_PLUGIN_PATTERNS = [/^rnpm-plugin-/, /^@(.*)\/rnpm-plugin-/]; - -const REACT_NATIVE_PLUGIN_PATTERNS = [ - /^react-native-/, - /^@(.*)\/react-native-/, - /^@react-native(.*)\/(?!rnpm-plugin-)/, -]; - -/** - * Filter dependencies by name pattern - * @param {String} dependency Name of the dependency - * @return {Boolean} If dependency is a rnpm plugin - */ -const isRNPMPlugin = dependency => - RNPM_PLUGIN_PATTERNS.some(pattern => pattern.test(dependency)); -const isReactNativePlugin = dependency => - REACT_NATIVE_PLUGIN_PATTERNS.some(pattern => pattern.test(dependency)); - -const readPackage = folder => { - try { - return require(path.join(folder, 'package.json')); - } catch (e) { - return null; - } -}; - -const findPluginsInReactNativePackage = pjson => { - if (!pjson.rnpm || !pjson.rnpm.plugin) { - return []; - } - - return path.join(pjson.name, pjson.rnpm.plugin); -}; - -const findPlatformsInPackage = pjson => { - if (!pjson.rnpm || !pjson.rnpm.platform) { - return []; - } - - return path.join(pjson.name, pjson.rnpm.platform); -}; - -const getEmptyPluginConfig = () => ({ - commands: [], - platforms: [], - haste: { - platforms: [], - providesModuleNodeModules: [], - }, -}); - -const findHasteConfigInPackageAndConcat = (pjson, haste) => { - if (!pjson.rnpm || !pjson.rnpm.haste) { - return; - } - const pkgHaste = pjson.rnpm.haste; - - if (pkgHaste.platforms) { - haste.platforms = haste.platforms.concat(pkgHaste.platforms); - } - - if (pkgHaste.providesModuleNodeModules) { - haste.providesModuleNodeModules = haste.providesModuleNodeModules.concat( - pkgHaste.providesModuleNodeModules, - ); - } -}; - -const findPluginsInFolder = folder => { - const pjson = readPackage(folder); - - if (!pjson) { - return getEmptyPluginConfig(); - } - - const deps = union( - Object.keys(pjson.dependencies || {}), - Object.keys(pjson.devDependencies || {}), - ); - - return deps.reduce((acc, pkg) => { - let {commands, platforms} = acc; - if (isRNPMPlugin(pkg)) { - commands = commands.concat(pkg); - } - if (isReactNativePlugin(pkg)) { - const pkgJson = readPackage(path.join(folder, 'node_modules', pkg)); - if (pkgJson) { - commands = commands.concat(findPluginsInReactNativePackage(pkgJson)); - platforms = platforms.concat(findPlatformsInPackage(pkgJson)); - findHasteConfigInPackageAndConcat(pkgJson, acc.haste); - } - } - return {commands, platforms, haste: acc.haste}; - }, getEmptyPluginConfig()); -}; - -/** - * Find plugins in package.json of the given folder - * @param {String} folder Path to the folder to get the package.json from - */ -export default function findPlugins(folder: string) { - const plugin = findPluginsInFolder(folder); - return { - commands: uniq(flatten(plugin.commands)), - platforms: uniq(flatten(plugin.platforms)), - haste: { - platforms: uniq(flatten(plugin.haste.platforms)), - providesModuleNodeModules: uniq( - flatten(plugin.haste.providesModuleNodeModules), - ), - }, - }; -} diff --git a/packages/cli/src/tools/getAssets.js b/packages/cli/src/tools/getAssets.js deleted file mode 100644 index d0927ea61..000000000 --- a/packages/cli/src/tools/getAssets.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @flow - */ - -import glob from 'glob'; -import path from 'path'; -import getPackageConfiguration from './getPackageConfiguration'; - -const findAssetsInFolder = folder => - glob.sync(path.join(folder, '**'), {nodir: true}); - -/** - * Given an array of assets folders, e.g. ['Fonts', 'Images'], - * it globs in them to find all files that can be copied. - * - * It returns an array of absolute paths to files found. - */ -export function findAssets(folder: string, assets?: string[]) { - return (assets || []) - .map(asset => path.join(folder, asset)) - .reduce( - (acc, assetPath) => - (acc.concat(findAssetsInFolder(assetPath)): Array), - [], - ); -} - -/** - * Returns a project configuration in a given folder - */ -export default function getAssets(root: string) { - const config = getPackageConfiguration(root); - return findAssets(root, config.assets); -} diff --git a/packages/cli/src/tools/getHooks.js b/packages/cli/src/tools/getHooks.js deleted file mode 100644 index aac342808..000000000 --- a/packages/cli/src/tools/getHooks.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @flow - */ - -import {spawn} from 'child_process'; -import getPackageConfiguration from './getPackageConfiguration'; - -export function makeCommand(command: string) { - return (cb: Function) => { - if (!cb) { - throw new Error( - `You missed a callback function for the ${command} command`, - ); - } - - const args = command.split(' '); - const cmd = args.shift(); - - const commandProcess = spawn(cmd, args, { - stdio: 'inherit', - stdin: 'inherit', - }); - - commandProcess.on('close', code => { - if (code) { - throw new Error(`Error occurred during executing "${command}" command`); - } - - cb(); - }); - }; -} - -export default function getHooks(root: string) { - const commands = getPackageConfiguration(root).commands || {}; - - const acc = {}; - - Object.keys(commands).forEach(command => { - acc[command] = makeCommand(commands[command]); - }); - - return acc; -} diff --git a/packages/cli/src/tools/getPackageConfiguration.js b/packages/cli/src/tools/getPackageConfiguration.js deleted file mode 100644 index b1ce140e5..000000000 --- a/packages/cli/src/tools/getPackageConfiguration.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @flow - */ -import path from 'path'; -import type {PackageConfigurationT} from './types.flow'; - -/** - * Returns configuration of the CLI from `package.json`. - */ -export default function getPackageConfiguration( - folder: string, -): PackageConfigurationT { - return require(path.join(folder, './package.json')).rnpm || {}; -} diff --git a/packages/cli/src/tools/getParams.js b/packages/cli/src/tools/getParams.js deleted file mode 100644 index d8a528b60..000000000 --- a/packages/cli/src/tools/getParams.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * @flow - */ - -import getPackageConfiguration from './getPackageConfiguration'; - -export default function getParams(root: string) { - const config = getPackageConfiguration(root); - return config.params || []; -} diff --git a/packages/cli/src/tools/getPlatforms.js b/packages/cli/src/tools/getPlatforms.js deleted file mode 100644 index 2aefde45d..000000000 --- a/packages/cli/src/tools/getPlatforms.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @flow - */ - -import path from 'path'; -import type {PlatformsT} from './types.flow'; - -import findPlugins from './findPlugins'; - -/** - * Support for `ios` and `android` platforms is built-in - * - * @todo(grabbou): Move this out of the core to increase "interoperability" - * with other platforms - */ -const builtInPlatforms = { - ios: require('./ios'), - android: require('./android'), -}; - -/** - * Returns an object with available platforms - */ -export default function getPlatforms(root: string): PlatformsT { - const plugins = findPlugins(root); - - /** - * Each `platfom` is a file that should define an object with platforms available - * and the config required. - * - * @todo(grabbou): We should validate if the config loaded is correct, warn and skip - * using it if it's invalid. - */ - const projectPlatforms = plugins.platforms.reduce( - (acc, pathToPlatform) => - Object.assign( - acc, - require(path.join(root, 'node_modules', pathToPlatform)), - ), - {}, - ); - - return { - ...builtInPlatforms, - ...projectPlatforms, - }; -} - -const names = { - ios: 'iOS', - android: 'Android', -}; - -export function getPlatformName(name: string) { - return names[name] || name; -} From f5d92b8a96a581fe8018c04b024c3b2767dd6b2f Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 16:39:21 +0200 Subject: [PATCH 12/46] Fix types for platforms and upgrade test --- packages/cli/src/commands/link/linkDependency.js | 2 +- .../cli/src/commands/upgrade/__tests__/upgrade.test.js | 10 +++++++++- packages/cli/src/tools/types.flow.js | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/commands/link/linkDependency.js b/packages/cli/src/commands/link/linkDependency.js index 3ba0221d7..e71526c02 100644 --- a/packages/cli/src/commands/link/linkDependency.js +++ b/packages/cli/src/commands/link/linkDependency.js @@ -7,7 +7,7 @@ import type { } from '../../tools/config/types.flow'; import logger from '../../tools/logger'; import pollParams from './pollParams'; -import {getPlatformName} from '../../tools/getPlatforms'; +import getPlatformName from './getPlatformName'; const linkDependency = async ( platforms: PlatformsT, diff --git a/packages/cli/src/commands/upgrade/__tests__/upgrade.test.js b/packages/cli/src/commands/upgrade/__tests__/upgrade.test.js index aa1569a17..3f727596f 100644 --- a/packages/cli/src/commands/upgrade/__tests__/upgrade.test.js +++ b/packages/cli/src/commands/upgrade/__tests__/upgrade.test.js @@ -56,8 +56,16 @@ const ctx = { root: '/project/root', reactNativePath: '', commands: [], - platforms: {}, + platforms: { + ios: {projectConfig: jest.fn(), dependencyConfig: jest.fn()}, + android: {projectConfig: jest.fn(), dependencyConfig: jest.fn()}, + }, + project: { + ios: null, + android: null, + }, dependencies: {}, + assets: [], haste: { providesModuleNodeModules: [], platforms: [], diff --git a/packages/cli/src/tools/types.flow.js b/packages/cli/src/tools/types.flow.js index 63669d4a7..6a46b82fc 100644 --- a/packages/cli/src/tools/types.flow.js +++ b/packages/cli/src/tools/types.flow.js @@ -56,7 +56,7 @@ export type PlatformConfigT< * @todo(grabbou): This should not be part of the "core". It should be * specific to `link` and `unlink`. Remove it from here soon. */ - linkConfig: () => { + linkConfig?: () => { /** * @todo(grabbou): Revert the arguments order to align with the rest */ From e845c724f2a343d5aec006d3753626242f3ce260 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 16:47:36 +0200 Subject: [PATCH 13/46] Fix flow errors --- .../src/commands/info/__tests__/info.test.js | 17 ++++-------- .../upgrade/__tests__/upgrade.test.js | 25 +++++------------- .../cli/src/tools/config/__mocks__/index.js | 26 +++++++++++++++++++ 3 files changed, 37 insertions(+), 31 deletions(-) create mode 100644 packages/cli/src/tools/config/__mocks__/index.js diff --git a/packages/cli/src/commands/info/__tests__/info.test.js b/packages/cli/src/commands/info/__tests__/info.test.js index 7b19753b0..fdd99c865 100644 --- a/packages/cli/src/commands/info/__tests__/info.test.js +++ b/packages/cli/src/commands/info/__tests__/info.test.js @@ -1,6 +1,7 @@ // @flow import info from '../info'; import logger from '../../../tools/logger'; +import loadConfig from '../../../tools/config'; jest.mock('../../../tools/logger', () => ({ info: jest.fn(), @@ -8,24 +9,16 @@ jest.mock('../../../tools/logger', () => ({ log: jest.fn(), })); -const ctx = { - root: '', - reactNativePath: '', - dependencies: {}, - platforms: {}, - commands: [], - haste: { - platforms: [], - providesModuleNodeModules: [], - }, -}; +jest.mock('../../../tools/config'); beforeEach(() => { jest.resetAllMocks(); }); +const config = loadConfig(); + test('prints output without arguments', async () => { - await info.func([], ctx, {}); + await info.func([], config, {}); expect(logger.info).toHaveBeenCalledWith( 'Fetching system and libraries information...', ); diff --git a/packages/cli/src/commands/upgrade/__tests__/upgrade.test.js b/packages/cli/src/commands/upgrade/__tests__/upgrade.test.js index 3f727596f..bdfeb1d77 100644 --- a/packages/cli/src/commands/upgrade/__tests__/upgrade.test.js +++ b/packages/cli/src/commands/upgrade/__tests__/upgrade.test.js @@ -6,6 +6,7 @@ import snapshotDiff from 'snapshot-diff'; import upgrade from '../upgrade'; import {fetch} from '../helpers'; import logger from '../../../tools/logger'; +import loadConfig from '../../../tools/config'; jest.mock('https'); jest.mock('fs'); @@ -52,25 +53,11 @@ jest.mock('../../../tools/logger', () => ({ const currentVersion = '0.57.8'; const newVersion = '0.58.4'; const olderVersion = '0.56.0'; -const ctx = { - root: '/project/root', - reactNativePath: '', - commands: [], - platforms: { - ios: {projectConfig: jest.fn(), dependencyConfig: jest.fn()}, - android: {projectConfig: jest.fn(), dependencyConfig: jest.fn()}, - }, - project: { - ios: null, - android: null, - }, - dependencies: {}, - assets: [], - haste: { - providesModuleNodeModules: [], - platforms: [], - }, -}; + +jest.mock('../../../tools/config'); + +const ctx = loadConfig(); + const opts = { legacy: false, }; diff --git a/packages/cli/src/tools/config/__mocks__/index.js b/packages/cli/src/tools/config/__mocks__/index.js new file mode 100644 index 000000000..2635139dd --- /dev/null +++ b/packages/cli/src/tools/config/__mocks__/index.js @@ -0,0 +1,26 @@ +/** + * @flow + */ +import {type ConfigT} from '../types.flow'; + +export default function mockedLoadConfig(): ConfigT { + return { + root: '/project/root', + reactNativePath: '', + commands: [], + platforms: { + ios: {projectConfig: () => null, dependencyConfig: () => null}, + android: {projectConfig: () => null, dependencyConfig: () => null}, + }, + project: { + ios: null, + android: null, + }, + dependencies: {}, + assets: [], + haste: { + providesModuleNodeModules: [], + platforms: [], + }, + }; +} From 7cafc3dce18fa1cea50f5c1f765033ab99e96b36 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 16:54:04 +0200 Subject: [PATCH 14/46] Remove old tests, move rest to new place --- .../__tests__/getDependencyConfig-test.js | 45 ----- .../__tests__/getProjectDependencies-test.js | 44 ----- .../src/tools/__tests__/findPlugins-test.js | 99 ----------- .../__snapshots__/index-test.js.snap | 166 ++++++++++++++++++ .../{ => config}/__tests__/findAssets-test.js | 5 +- .../__tests__/{index.js => index-test.js} | 0 .../__tests__/makeHook-test.js} | 23 +-- 7 files changed, 176 insertions(+), 206 deletions(-) delete mode 100644 packages/cli/src/commands/link/__tests__/getDependencyConfig-test.js delete mode 100644 packages/cli/src/commands/link/__tests__/getProjectDependencies-test.js delete mode 100644 packages/cli/src/tools/__tests__/findPlugins-test.js create mode 100644 packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap rename packages/cli/src/tools/{ => config}/__tests__/findAssets-test.js (90%) rename packages/cli/src/tools/config/__tests__/{index.js => index-test.js} (100%) rename packages/cli/src/tools/{__tests__/makeCommand-test.js => config/__tests__/makeHook-test.js} (54%) diff --git a/packages/cli/src/commands/link/__tests__/getDependencyConfig-test.js b/packages/cli/src/commands/link/__tests__/getDependencyConfig-test.js deleted file mode 100644 index 73cd1f7a2..000000000 --- a/packages/cli/src/commands/link/__tests__/getDependencyConfig-test.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @emails oncall+javascript_foundation - */ - -const platforms = { - ios: { - dependencyConfig: () => ({sampleiOSKey: ''}), - }, - android: { - dependencyConfig: () => ({sampleAndroidKey: ''}), - }, -}; - -jest.setMock('../../../tools/getPackageConfiguration', folder => { - if (folder === '/root/node_modules/abcd') { - throw new Error('Cannot require'); - } - return {}; -}); - -const getDependencyConfig = require('../getDependencyConfig').default; - -describe('getDependencyConfig', () => { - it("should return an array of dependencies' config", () => { - const dependencies = getDependencyConfig( - {root: '/root'}, - platforms, - 'react-native-windows', - ); - - expect(dependencies).toMatchSnapshot(); - }); - - it('should throw on invalid react-native dependency', () => { - expect(() => - getDependencyConfig({root: '/root'}, platforms, 'abcd'), - ).toThrowError(); - }); -}); diff --git a/packages/cli/src/commands/link/__tests__/getProjectDependencies-test.js b/packages/cli/src/commands/link/__tests__/getProjectDependencies-test.js deleted file mode 100644 index 5eac43b0b..000000000 --- a/packages/cli/src/commands/link/__tests__/getProjectDependencies-test.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @emails oncall+javascript_foundation - * @format - */ - -import getProjectDependencies from '../getProjectDependencies'; - -const path = require('path'); - -const CWD = path.resolve(__dirname, '../../'); - -describe('getProjectDependencies', () => { - beforeEach(() => { - jest.resetModules(); - }); - it('should return an array of project dependencies', () => { - jest.doMock( - path.join(CWD, './package.json'), - () => ({ - dependencies: { - lodash: '^6.0.0', - 'react-native': '^16.0.0', - '@react-native-community/cli': '*', - }, - }), - {virtual: true}, - ); - - expect(getProjectDependencies(CWD)).toEqual(['lodash']); - }); - - it('should return an empty array when no dependencies set', () => { - jest.doMock(path.join(CWD, './package.json'), () => ({}), { - virtual: true, - }); - expect(getProjectDependencies(CWD)).toEqual([]); - }); -}); diff --git a/packages/cli/src/tools/__tests__/findPlugins-test.js b/packages/cli/src/tools/__tests__/findPlugins-test.js deleted file mode 100644 index c1cee2079..000000000 --- a/packages/cli/src/tools/__tests__/findPlugins-test.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @emails oncall+javascript_foundation - */ - -import findPlugins from '../findPlugins'; - -const path = require('path'); - -const ROOT = path.join(__dirname, '..', '..'); -const pjsonPath = path.join(ROOT, './package.json'); - -describe('findPlugins', () => { - beforeEach(() => { - jest.resetModules(); - }); - - it('returns an array of dependencies', () => { - jest.doMock( - pjsonPath, - () => ({ - dependencies: {'rnpm-plugin-test': '*'}, - }), - {virtual: true}, - ); - - expect(findPlugins(ROOT)).toHaveProperty('commands'); - expect(findPlugins(ROOT)).toHaveProperty('platforms'); - expect(findPlugins(ROOT).commands).toHaveLength(1); - expect(findPlugins(ROOT).commands[0]).toBe('rnpm-plugin-test'); - expect(findPlugins(ROOT).platforms).toHaveLength(0); - }); - - it('returns an empty array if there are no plugins in this folder', () => { - jest.doMock(pjsonPath, () => ({}), {virtual: true}); - expect(findPlugins(ROOT)).toHaveProperty('commands'); - expect(findPlugins(ROOT)).toHaveProperty('platforms'); - expect(findPlugins(ROOT).commands).toHaveLength(0); - expect(findPlugins(ROOT).platforms).toHaveLength(0); - }); - - it('returns an object with empty arrays if there is no package.json in the supplied folder', () => { - expect(findPlugins('fake-path')).toHaveProperty('commands'); - expect(findPlugins('fake-path')).toHaveProperty('platforms'); - expect(findPlugins('fake-path').commands).toHaveLength(0); - expect(findPlugins('fake-path').platforms).toHaveLength(0); - }); - - it('returns plugins from both dependencies and dev dependencies', () => { - jest.doMock( - pjsonPath, - () => ({ - dependencies: {'rnpm-plugin-test': '*'}, - devDependencies: {'rnpm-plugin-test-2': '*'}, - }), - {virtual: true}, - ); - expect(findPlugins(ROOT)).toHaveProperty('commands'); - expect(findPlugins(ROOT)).toHaveProperty('platforms'); - expect(findPlugins(ROOT).commands).toHaveLength(2); - expect(findPlugins(ROOT).platforms).toHaveLength(0); - }); - - it('returns unique list of plugins', () => { - jest.doMock( - pjsonPath, - () => ({ - dependencies: {'rnpm-plugin-test': '*'}, - devDependencies: {'rnpm-plugin-test': '*'}, - }), - {virtual: true}, - ); - expect(findPlugins(ROOT).commands).toHaveLength(1); - }); - - it('returns plugins in scoped modules', () => { - jest.doMock( - pjsonPath, - () => ({ - dependencies: { - '@org/rnpm-plugin-test': '*', - '@org/react-native-test': '*', - '@react-native/test': '*', - '@react-native-org/test': '*', - }, - }), - {virtual: true}, - ); - - expect(findPlugins(ROOT)).toHaveProperty('commands'); - expect(findPlugins(ROOT)).toHaveProperty('platforms'); - expect(findPlugins(ROOT).commands[0]).toBe('@org/rnpm-plugin-test'); - }); -}); diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap new file mode 100644 index 000000000..e26a23c3a --- /dev/null +++ b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap @@ -0,0 +1,166 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should deep merge project configuration with default values 1`] = ` +Object { + "assets": Array [], + "commands": Array [], + "dependencies": Object { + "react-native-test": Object { + "assets": Array [], + "hooks": Object {}, + "name": "react-native-test", + "params": Array [], + "platforms": Object { + "android": null, + "ios": Object { + "folder": "<>/node_modules/react-native-test", + "libraryFolder": "Libraries", + "pbxprojPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj/project.pbxproj", + "plist": Array [], + "podfile": null, + "podspec": null, + "projectName": "HelloWorld.xcodeproj", + "projectPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj", + "sharedLibraries": Array [], + "sourceDir": "./abc", + }, + }, + }, + }, + "haste": Object { + "platforms": Array [], + "providesModuleNodeModules": Array [], + }, + "platforms": Object { + "android": Object {}, + "ios": Object {}, + }, + "project": Object { + "android": null, + "ios": null, + }, + "reactNativePath": ".", + "root": "<>", +} +`; + +exports[`should have a valid structure by default 1`] = ` +Object { + "assets": Array [], + "commands": Array [], + "dependencies": Object {}, + "haste": Object { + "platforms": Array [], + "providesModuleNodeModules": Array [], + }, + "platforms": Object { + "android": Object {}, + "ios": Object {}, + }, + "project": Object { + "android": null, + "ios": null, + }, + "reactNativePath": ".", + "root": "<>", +} +`; + +exports[`should load an out-of-tree "windows" platform that ships with a dependency 1`] = ` +Object { + "haste": Object { + "platforms": Array [ + "windows", + ], + "providesModuleNodeModules": Array [ + "react-native-windows", + ], + }, + "platforms": Object { + "android": Object {}, + "ios": Object {}, + "windows": Object {}, + }, +} +`; + +exports[`should load commands from "react-native-foo" and "react-native-bar" packages 1`] = ` +Array [ + "react-native-foo/command-foo.js", + "react-native-bar/command-bar.js", +] +`; + +exports[`should read \`rnpm\` config from a dependency and transform it to a new format 1`] = ` +Object { + "assets": Array [], + "hooks": Object {}, + "name": "react-native-foo", + "params": Array [], + "platforms": Object { + "android": null, + "ios": Object { + "folder": "<>/node_modules/react-native-foo", + "libraryFolder": "Libraries", + "pbxprojPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj/project.pbxproj", + "plist": Array [], + "podfile": null, + "podspec": null, + "projectName": "customProject.xcodeproj", + "projectPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj", + "sharedLibraries": Array [], + "sourceDir": "<>/node_modules/react-native-foo/customLocation", + }, + }, +} +`; + +exports[`should read a config of a dependency and use it to load other settings 1`] = ` +Object { + "assets": Array [], + "hooks": Object {}, + "name": "react-native-test", + "params": Array [], + "platforms": Object { + "android": null, + "ios": Object { + "folder": "<>/node_modules/react-native-test", + "libraryFolder": "Libraries", + "pbxprojPath": "<>/node_modules/react-native-test/customLocation/customProject.xcodeproj/project.pbxproj", + "plist": Array [], + "podfile": null, + "podspec": null, + "projectName": "customProject.xcodeproj", + "projectPath": "<>/node_modules/react-native-test/customLocation/customProject.xcodeproj", + "sharedLibraries": Array [], + "sourceDir": "<>/node_modules/react-native-test/customLocation", + }, + }, +} +`; + +exports[`should return dependencies from package.json 1`] = ` +Object { + "react-native-test": Object { + "assets": Array [], + "hooks": Object {}, + "name": "react-native-test", + "params": Array [], + "platforms": Object { + "android": null, + "ios": Object { + "folder": "<>/node_modules/react-native-test", + "libraryFolder": "Libraries", + "pbxprojPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj/project.pbxproj", + "plist": Array [], + "podfile": null, + "podspec": null, + "projectName": "HelloWorld.xcodeproj", + "projectPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj", + "sharedLibraries": Array [], + "sourceDir": "<>/node_modules/react-native-test/ios", + }, + }, + }, +} +`; diff --git a/packages/cli/src/tools/__tests__/findAssets-test.js b/packages/cli/src/tools/config/__tests__/findAssets-test.js similarity index 90% rename from packages/cli/src/tools/__tests__/findAssets-test.js rename to packages/cli/src/tools/config/__tests__/findAssets-test.js index a912a846f..ed0358854 100644 --- a/packages/cli/src/tools/__tests__/findAssets-test.js +++ b/packages/cli/src/tools/config/__tests__/findAssets-test.js @@ -8,15 +8,14 @@ * @emails oncall+javascript_foundation */ -import dependencies from '../__fixtures__/dependencies'; +import dependencies from '../../__fixtures__/dependencies'; +import findAssets from '../findAssets'; jest.mock('path'); jest.mock('fs'); const fs = require('fs'); -const {findAssets} = require('../getAssets'); - describe('findAssets', () => { beforeEach(() => { fs.__setMockFilesystem({testDir: dependencies.withAssets}); diff --git a/packages/cli/src/tools/config/__tests__/index.js b/packages/cli/src/tools/config/__tests__/index-test.js similarity index 100% rename from packages/cli/src/tools/config/__tests__/index.js rename to packages/cli/src/tools/config/__tests__/index-test.js diff --git a/packages/cli/src/tools/__tests__/makeCommand-test.js b/packages/cli/src/tools/config/__tests__/makeHook-test.js similarity index 54% rename from packages/cli/src/tools/__tests__/makeCommand-test.js rename to packages/cli/src/tools/config/__tests__/makeHook-test.js index 6eee9758e..71173934c 100644 --- a/packages/cli/src/tools/__tests__/makeCommand-test.js +++ b/packages/cli/src/tools/config/__tests__/makeHook-test.js @@ -1,12 +1,7 @@ /** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @emails oncall+javascript_foundation + * @flow */ +import makeHook from '../makeHook'; let spawnError = false; @@ -16,22 +11,20 @@ jest.setMock('child_process', { }), }); -const {makeCommand} = require('../getHooks'); - -describe('makeCommand', () => { - const command = makeCommand('echo'); +describe('makeHook', () => { + const hook = makeHook('echo'); it('generates a function around shell command', () => { - expect(typeof command).toBe('function'); + expect(typeof hook).toBe('function'); }); it('throws an error if there is no callback provided', () => { - expect(command).toThrow(); + expect(hook).toThrow(); }); it('invokes a callback after command execution', () => { const spy = jest.fn(); - command(spy); + hook(spy); expect(spy.mock.calls).toHaveLength(1); }); @@ -39,7 +32,7 @@ describe('makeCommand', () => { spawnError = true; const cb = jest.fn(); expect(() => { - command(cb); + hook(cb); }).toThrow(); }); }); From 68a546063ab733b383a11d0743f0fad7a4e7bacb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 2 Apr 2019 16:51:28 +0200 Subject: [PATCH 15/46] fix: flaky tests; upgrade Jest to 24.6 (#282) Summary: --------- While working on #241 we discovered some flaky tests. This diff aims to fix those. It also updates Jest to 24.6 which comes with pretty nice perf improvements. Test Plan: ---------- Green CI --- .circleci/config.yml | 2 +- e2e/jest.config.js | 1 + e2e/testSetup.js | 1 + jest.config.js | 4 + package.json | 11 +- .../src/commands/info/__tests__/info.test.js | 2 +- .../android/makeSettingsPatch-test.js | 3 +- .../upgrade/__tests__/upgrade.test.js | 18 +- .../tools/__tests__/PackageManager-test.js | 6 +- .../tools/config/__tests__/makeHook-test.js | 4 + packages/cli/testSetup.js | 2 + yarn.lock | 605 +++++++++--------- 12 files changed, 334 insertions(+), 325 deletions(-) create mode 100644 e2e/testSetup.js create mode 100644 jest.config.js diff --git a/.circleci/config.yml b/.circleci/config.yml index 84e4ac74e..53e390b7e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,7 +38,7 @@ jobs: steps: - attach_workspace: at: ~/react-native-cli - - run: yarn test + - run: yarn test:ci - store_artifacts: path: coverage destination: coverage diff --git a/e2e/jest.config.js b/e2e/jest.config.js index dcda2ee7b..a4a44922a 100644 --- a/e2e/jest.config.js +++ b/e2e/jest.config.js @@ -1,4 +1,5 @@ module.exports = { testEnvironment: 'node', testPathIgnorePatterns: ['/(?:.+?)/__tests__/'], + setupFiles: ['./testSetup.js'], }; diff --git a/e2e/testSetup.js b/e2e/testSetup.js new file mode 100644 index 000000000..09ffd355d --- /dev/null +++ b/e2e/testSetup.js @@ -0,0 +1 @@ +jest.setTimeout(60000); diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 000000000..fca02fb79 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,4 @@ +module.exports = { + testEnvironment: 'node', + projects: ['/packages/*', '/e2e'], +}; diff --git a/package.json b/package.json index 57046bfb0..3aca1c3ff 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "build-clean": "rm -rf ./packages/*/build", "watch": "node ./scripts/watch.js", "test": "jest", + "test:ci": "jest -i", "lint": "eslint . --cache --report-unused-disable-directives", "flow-check": "flow check", "postinstall": "yarn build-clean && yarn build", @@ -20,23 +21,17 @@ "@babel/preset-env": "^7.0.0", "@babel/preset-flow": "^7.0.0", "@react-native-community/eslint-config": "^0.0.3", - "babel-jest": "^24.5.0", + "babel-jest": "^24.6.0", "chalk": "^2.4.2", "eslint": "^5.10.0", "execa": "^1.0.0", "flow-bin": "^0.95.1", "flow-typed": "^2.5.1", "glob": "^7.1.3", - "jest": "^24.5.0", + "jest": "^24.6.0", "lerna": "^3.13.1", "micromatch": "^3.1.10", "mkdirp": "^0.5.1", "string-length": "^2.0.0" - }, - "jest": { - "projects": [ - "packages/*", - "e2e" - ] } } diff --git a/packages/cli/src/commands/info/__tests__/info.test.js b/packages/cli/src/commands/info/__tests__/info.test.js index fdd99c865..cbda1f26f 100644 --- a/packages/cli/src/commands/info/__tests__/info.test.js +++ b/packages/cli/src/commands/info/__tests__/info.test.js @@ -27,6 +27,6 @@ test('prints output without arguments', async () => { // TODO: move to e2e tests and adjust expectations to include npm packages expect(output).toContain('System:'); expect(output).toContain('Binaries:'); -}); +}, 20000); test.todo('prints output with --packages'); diff --git a/packages/cli/src/commands/link/__tests__/android/makeSettingsPatch-test.js b/packages/cli/src/commands/link/__tests__/android/makeSettingsPatch-test.js index 2fc77b2fc..d21bd0b6f 100644 --- a/packages/cli/src/commands/link/__tests__/android/makeSettingsPatch-test.js +++ b/packages/cli/src/commands/link/__tests__/android/makeSettingsPatch-test.js @@ -41,7 +41,8 @@ project(':test').projectDir = new File(rootProject.projectDir, '../node_modules/ // Simulate Windows environment on POSIX filesystem // TODO: scope this test to Windows-only once we setup CI on Windows - it('includes project with correct path on Windows', () => { + // as changing path to be windows-specific breaks global path mock + it.skip('includes project with correct path on Windows', () => { jest.resetModules(); jest.doMock('path', () => { const path = jest.requireActual('path'); diff --git a/packages/cli/src/commands/upgrade/__tests__/upgrade.test.js b/packages/cli/src/commands/upgrade/__tests__/upgrade.test.js index bdfeb1d77..880b56687 100644 --- a/packages/cli/src/commands/upgrade/__tests__/upgrade.test.js +++ b/packages/cli/src/commands/upgrade/__tests__/upgrade.test.js @@ -3,6 +3,7 @@ import execa from 'execa'; import path from 'path'; import fs from 'fs'; import snapshotDiff from 'snapshot-diff'; +import stripAnsi from 'strip-ansi'; import upgrade from '../upgrade'; import {fetch} from '../helpers'; import logger from '../../../tools/logger'; @@ -69,7 +70,7 @@ const samplePatch = jest let logs = []; const mockPushLog = (...args) => logs.push(args.map(x => (Array.isArray(x) ? x.join(' ') : x)).join(' ')); -const flushOutput = () => logs.join('\n'); +const flushOutput = () => stripAnsi(logs.join('\n')); beforeEach(() => { jest.clearAllMocks(); @@ -80,6 +81,13 @@ beforeEach(() => { logs = []; }); +afterEach(() => { + // $FlowFixMe + fs.writeFileSync = jest.requireMock('fs').writeFileSync; + // $FlowFixMe + fs.unlinkSync = jest.requireMock('fs').unlinkSync; +}); + test('uses latest version of react-native when none passed', async () => { await upgrade.func([], ctx, opts); expect(execa).toBeCalledWith('npm', ['info', 'react-native', 'version']); @@ -179,14 +187,14 @@ test('cleans up if patching fails,', async () => { $ execa git apply --check tmp-upgrade-rn.patch --exclude=package.json -p2 --3way info Applying diff (excluding: package.json, .flowconfig)... $ execa git apply tmp-upgrade-rn.patch --exclude=package.json --exclude=.flowconfig -p2 --3way -error: .flowconfig: does not exist in index +error: .flowconfig: does not exist in index error Automatically applying diff failed [fs] unlink tmp-upgrade-rn.patch $ execa git status -s error Patch failed to apply for unknown reason. Please fall back to manual way of upgrading info You may find these resources helpful: -• Release notes: https://github.com/facebook/react-native/releases/tag/v0.58.4 -• Comparison between versions: https://github.com/react-native-community/rn-diff-purge/compare/version/0.57.8..version/0.58.4 -• Git diff: https://github.com/react-native-community/rn-diff-purge/compare/version/0.57.8..version/0.58.4.diff" +• Release notes: https://github.com/facebook/react-native/releases/tag/v0.58.4 +• Comparison between versions: https://github.com/react-native-community/rn-diff-purge/compare/version/0.57.8..version/0.58.4 +• Git diff: https://github.com/react-native-community/rn-diff-purge/compare/version/0.57.8..version/0.58.4.diff" `); }); diff --git a/packages/cli/src/tools/__tests__/PackageManager-test.js b/packages/cli/src/tools/__tests__/PackageManager-test.js index 92a47c24b..33c4ce210 100644 --- a/packages/cli/src/tools/__tests__/PackageManager-test.js +++ b/packages/cli/src/tools/__tests__/PackageManager-test.js @@ -10,6 +10,9 @@ const PROJECT_ROOT = '/some/dir'; beforeEach(() => { jest.spyOn(ChildProcess, 'execSync').mockImplementation(() => {}); }); +afterEach(() => { + (ChildProcess.execSync: any).mockRestore(); +}); describe('yarn', () => { beforeEach(() => { @@ -99,7 +102,8 @@ it('should use npm if project is not using yarn', () => { }); it('should use yarn if project is using yarn', () => { - jest.spyOn(yarn, 'isProjectUsingYarn').mockImplementation(() => false); + jest.spyOn(yarn, 'getYarnVersionIfAvailable').mockImplementation(() => true); + jest.spyOn(yarn, 'isProjectUsingYarn').mockImplementation(() => true); PackageManager.setProjectDir(PROJECT_ROOT); PackageManager.install(PACKAGES); diff --git a/packages/cli/src/tools/config/__tests__/makeHook-test.js b/packages/cli/src/tools/config/__tests__/makeHook-test.js index 71173934c..d16953c4a 100644 --- a/packages/cli/src/tools/config/__tests__/makeHook-test.js +++ b/packages/cli/src/tools/config/__tests__/makeHook-test.js @@ -11,6 +11,10 @@ jest.setMock('child_process', { }), }); +afterAll(() => { + jest.restoreAllMocks(); +}); + describe('makeHook', () => { const hook = makeHook('echo'); diff --git a/packages/cli/testSetup.js b/packages/cli/testSetup.js index 7a043b8b8..36c5620d0 100644 --- a/packages/cli/testSetup.js +++ b/packages/cli/testSetup.js @@ -1,2 +1,4 @@ // @flow jest.mock('./src/tools/logger'); + +jest.setTimeout(20000); diff --git a/yarn.lock b/yarn.lock index 5c7505665..745260fc3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1040,42 +1040,41 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@jest/console@^24.3.0": - version "24.3.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.3.0.tgz#7bd920d250988ba0bf1352c4493a48e1cb97671e" - integrity sha512-NaCty/OOei6rSDcbPdMiCbYCI0KGFGPgGO6B09lwWt5QTxnkuhKYET9El5u5z1GAcSxkQmSMtM63e24YabCWqA== +"@jest/console@^24.6.0": + version "24.6.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.6.0.tgz#63225e6889f3865ab5b7a0d8797e8aed417c4e0b" + integrity sha512-nNZbwtZwW6dr7bvZpRBCdBNvZYi+jr6lfnubSOCELk/Km/5csDmGdqeS4qKwGKIVlHTyZ95MYExYevpdh26tDA== dependencies: "@jest/source-map" "^24.3.0" - "@types/node" "*" chalk "^2.0.1" slash "^2.0.0" -"@jest/core@^24.5.0": - version "24.5.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.5.0.tgz#2cefc6a69e9ebcae1da8f7c75f8a257152ba1ec0" - integrity sha512-RDZArRzAs51YS7dXG1pbXbWGxK53rvUu8mCDYsgqqqQ6uSOaTjcVyBl2Jce0exT2rSLk38ca7az7t2f3b0/oYQ== +"@jest/core@^24.6.0": + version "24.6.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.6.0.tgz#148c2dc60be7daef1e148bf8c0a01bb1391609df" + integrity sha512-rZ/5295Geou6o1+vp2+G+p7nV6wITrCR7KSnZc+Dru8QbWAR+M9SPb0BHiRTzQvfVQFkk0AkbTw1GWjCRUX/GA== dependencies: - "@jest/console" "^24.3.0" - "@jest/reporters" "^24.5.0" - "@jest/test-result" "^24.5.0" - "@jest/transform" "^24.5.0" - "@jest/types" "^24.5.0" + "@jest/console" "^24.6.0" + "@jest/reporters" "^24.6.0" + "@jest/test-result" "^24.6.0" + "@jest/transform" "^24.6.0" + "@jest/types" "^24.6.0" ansi-escapes "^3.0.0" chalk "^2.0.1" exit "^0.1.2" graceful-fs "^4.1.15" - jest-changed-files "^24.5.0" - jest-config "^24.5.0" - jest-haste-map "^24.5.0" - jest-message-util "^24.5.0" + jest-changed-files "^24.6.0" + jest-config "^24.6.0" + jest-haste-map "^24.6.0" + jest-message-util "^24.6.0" jest-regex-util "^24.3.0" - jest-resolve-dependencies "^24.5.0" - jest-runner "^24.5.0" - jest-runtime "^24.5.0" - jest-snapshot "^24.5.0" - jest-util "^24.5.0" - jest-validate "^24.5.0" - jest-watcher "^24.5.0" + jest-resolve-dependencies "^24.6.0" + jest-runner "^24.6.0" + jest-runtime "^24.6.0" + jest-snapshot "^24.6.0" + jest-util "^24.6.0" + jest-validate "^24.6.0" + jest-watcher "^24.6.0" micromatch "^3.1.10" p-each-series "^1.0.0" pirates "^4.0.1" @@ -1083,36 +1082,34 @@ rimraf "^2.5.4" strip-ansi "^5.0.0" -"@jest/environment@^24.5.0": - version "24.5.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.5.0.tgz#a2557f7808767abea3f9e4cc43a172122a63aca8" - integrity sha512-tzUHR9SHjMXwM8QmfHb/EJNbF0fjbH4ieefJBvtwO8YErLTrecc1ROj0uo2VnIT6SlpEGZnvdCK6VgKYBo8LsA== - dependencies: - "@jest/fake-timers" "^24.5.0" - "@jest/transform" "^24.5.0" - "@jest/types" "^24.5.0" - "@types/node" "*" - jest-mock "^24.5.0" - -"@jest/fake-timers@^24.5.0": - version "24.5.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.5.0.tgz#4a29678b91fd0876144a58f8d46e6c62de0266f0" - integrity sha512-i59KVt3QBz9d+4Qr4QxsKgsIg+NjfuCjSOWj3RQhjF5JNy+eVJDhANQ4WzulzNCHd72srMAykwtRn5NYDGVraw== - dependencies: - "@jest/types" "^24.5.0" - "@types/node" "*" - jest-message-util "^24.5.0" - jest-mock "^24.5.0" - -"@jest/reporters@^24.5.0": - version "24.5.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.5.0.tgz#9363a210d0daa74696886d9cb294eb8b3ad9b4d9" - integrity sha512-vfpceiaKtGgnuC3ss5czWOihKOUSyjJA4M4udm6nH8xgqsuQYcyDCi4nMMcBKsHXWgz9/V5G7iisnZGfOh1w6Q== - dependencies: - "@jest/environment" "^24.5.0" - "@jest/test-result" "^24.5.0" - "@jest/transform" "^24.5.0" - "@jest/types" "^24.5.0" +"@jest/environment@^24.6.0": + version "24.6.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.6.0.tgz#6dea095baee2ce23ed05328468f945291f30ed30" + integrity sha512-LccuUfnREDNFbKmMWrtzUJu6fwU1E6ddYlYSDuClEQvboMKQQMUuCSYXvRUQFtDdeVjUfxkHqfSVvBzuph0b7w== + dependencies: + "@jest/fake-timers" "^24.6.0" + "@jest/transform" "^24.6.0" + "@jest/types" "^24.6.0" + jest-mock "^24.6.0" + +"@jest/fake-timers@^24.6.0": + version "24.6.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.6.0.tgz#4eb0b47539883742e9f969e983770230f5a57d7b" + integrity sha512-92nYqkZceki6knls7F6/FrPxKXnQl0QjYXbjLk/EFfp6xcg4ETLQSAur7pMZsiAzazAgQag/XDvMmKwMbunAeg== + dependencies: + "@jest/types" "^24.6.0" + jest-message-util "^24.6.0" + jest-mock "^24.6.0" + +"@jest/reporters@^24.6.0": + version "24.6.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.6.0.tgz#2b4d75255743cbc448ba0a4890912e1e148417b4" + integrity sha512-fx20elfvGcuImjQZrNPS1fl/uj3mjuSf0vQFUoAPhQDarMzSbekLfRH8ZWt4ir1kpE36dLdFeFkeB8dhaTueIA== + dependencies: + "@jest/environment" "^24.6.0" + "@jest/test-result" "^24.6.0" + "@jest/transform" "^24.6.0" + "@jest/types" "^24.6.0" chalk "^2.0.1" exit "^0.1.2" glob "^7.1.2" @@ -1120,11 +1117,11 @@ istanbul-lib-coverage "^2.0.2" istanbul-lib-instrument "^3.0.1" istanbul-lib-source-maps "^3.0.1" - jest-haste-map "^24.5.0" - jest-resolve "^24.5.0" - jest-runtime "^24.5.0" - jest-util "^24.5.0" - jest-worker "^24.4.0" + jest-haste-map "^24.6.0" + jest-resolve "^24.6.0" + jest-runtime "^24.6.0" + jest-util "^24.6.0" + jest-worker "^24.6.0" node-notifier "^5.2.1" slash "^2.0.0" source-map "^0.6.0" @@ -1139,42 +1136,42 @@ graceful-fs "^4.1.15" source-map "^0.6.0" -"@jest/test-result@^24.5.0": - version "24.5.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.5.0.tgz#ab66fb7741a04af3363443084e72ea84861a53f2" - integrity sha512-u66j2vBfa8Bli1+o3rCaVnVYa9O8CAFZeqiqLVhnarXtreSXG33YQ6vNYBogT7+nYiFNOohTU21BKiHlgmxD5A== +"@jest/test-result@^24.6.0": + version "24.6.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.6.0.tgz#fd56c12b031601c282eede8a5ec1317ebe63bd11" + integrity sha512-k6pdgBBJIDbBgQGZgt8IbQC/KrOAC+fsSZrHw62R54FnfoYzuDqnrbB/AfPJS8T4RjDsWvnAHgXLH866yG10Pg== dependencies: - "@jest/console" "^24.3.0" - "@jest/types" "^24.5.0" - "@types/istanbul-lib-coverage" "^1.1.0" + "@jest/console" "^24.6.0" + "@jest/types" "^24.6.0" + "@types/istanbul-lib-coverage" "^2.0.0" -"@jest/transform@^24.5.0": - version "24.5.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.5.0.tgz#6709fc26db918e6af63a985f2cc3c464b4cf99d9" - integrity sha512-XSsDz1gdR/QMmB8UCKlweAReQsZrD/DK7FuDlNo/pE8EcKMrfi2kqLRk8h8Gy/PDzgqJj64jNEzOce9pR8oj1w== +"@jest/transform@^24.6.0": + version "24.6.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.6.0.tgz#dc7a00591651b89c2582602fe5c4ce47a5398148" + integrity sha512-aC7Yff2XREV1C/RQCoP1WzO3NU4EtmImIJXnNm4tTgaLoGGv1HJuXziyd5v7zOjBzn96793rF0iLHlFT4w4ErA== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^24.5.0" + "@jest/types" "^24.6.0" babel-plugin-istanbul "^5.1.0" chalk "^2.0.1" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.1.15" - jest-haste-map "^24.5.0" + jest-haste-map "^24.6.0" jest-regex-util "^24.3.0" - jest-util "^24.5.0" + jest-util "^24.6.0" micromatch "^3.1.10" realpath-native "^1.1.0" slash "^2.0.0" source-map "^0.6.1" write-file-atomic "2.4.1" -"@jest/types@^24.5.0": - version "24.5.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.5.0.tgz#feee214a4d0167b0ca447284e95a57aa10b3ee95" - integrity sha512-kN7RFzNMf2R8UDadPOl6ReyI+MT8xfqRuAnuVL+i4gwjv/zubdDK+EDeLHYwq1j0CSSR2W/MmgaRlMZJzXdmVA== +"@jest/types@^24.6.0": + version "24.6.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.6.0.tgz#cf018e56f3ef45e81119fd613fc20a9819f4eddd" + integrity sha512-hnCMhUokUm6A4HPE9j3pNG9N+bSFfhqje3EbIrW6YjUW2SXuyZxy1QsJdaICo1oN1o2vVSx6qlVqQYkmWVsjiA== dependencies: - "@types/istanbul-lib-coverage" "^1.1.0" + "@types/istanbul-lib-coverage" "^2.0.0" "@types/yargs" "^12.0.9" "@lerna/add@3.13.1": @@ -1917,15 +1914,10 @@ dependencies: "@babel/types" "^7.3.0" -"@types/istanbul-lib-coverage@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz#2cc2ca41051498382b43157c8227fea60363f94a" - integrity sha512-ohkhb9LehJy+PA40rDtGAji61NCgdtKLAlFoYp4cnuuQEswwdK3vz9SOIkkyc3wrk8dzjphQApNs56yyXLStaQ== - -"@types/node@*": - version "11.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" - integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== +"@types/istanbul-lib-coverage@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.0.tgz#1eb8c033e98cf4e1a4cedcaf8bcafe8cb7591e85" + integrity sha512-eAtOAFZefEnfJiRFQBGw1eYqa5GTLCZ1y86N0XSI/D6EB+E8z6VPV/UL7Gi5UEclFqoQk+6NRqEDsfmDLXn8sg== "@types/stack-utils@^1.0.1": version "1.0.1" @@ -2229,16 +2221,16 @@ babel-eslint@10.0.1: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-jest@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.5.0.tgz#0ea042789810c2bec9065f7c8ab4dc18e1d28559" - integrity sha512-0fKCXyRwxFTJL0UXDJiT2xYxO9Lu2vBd9n+cC+eDjESzcVG3s2DRGAxbzJX21fceB1WYoBjAh8pQ83dKcl003g== +babel-jest@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.6.0.tgz#58aa1e6a3d72fdd986644a92529f0ec7d2f1cf61" + integrity sha512-HpI/orChKlJZbWC2p52ghWeK+UYqU9ql+zYw+ctOr3vIuPZowcSL13RwReW5ZeYKxsRr8dZmQozGvPX93Gw1tw== dependencies: - "@jest/transform" "^24.5.0" - "@jest/types" "^24.5.0" + "@jest/transform" "^24.6.0" + "@jest/types" "^24.6.0" "@types/babel__core" "^7.1.0" babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.3.0" + babel-preset-jest "^24.6.0" chalk "^2.4.2" slash "^2.0.0" @@ -2251,10 +2243,10 @@ babel-plugin-istanbul@^5.1.0: istanbul-lib-instrument "^3.0.0" test-exclude "^5.0.0" -babel-plugin-jest-hoist@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.3.0.tgz#f2e82952946f6e40bb0a75d266a3790d854c8b5b" - integrity sha512-nWh4N1mVH55Tzhx2isvUN5ebM5CDUvIpXPZYMRazQughie/EqGnbR+czzoQlhUmJG9pPJmYDRhvocotb2THl1w== +babel-plugin-jest-hoist@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.6.0.tgz#f7f7f7ad150ee96d7a5e8e2c5da8319579e78019" + integrity sha512-3pKNH6hMt9SbOv0F3WVmy5CWQ4uogS3k0GY5XLyQHJ9EGpAT9XWkFd2ZiXXtkwFHdAHa5j7w7kfxSP5lAIwu7w== dependencies: "@types/babel__traverse" "^7.0.6" @@ -2304,13 +2296,13 @@ babel-preset-fbjs@^3.1.2: "@babel/plugin-transform-template-literals" "^7.0.0" babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" -babel-preset-jest@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.3.0.tgz#db88497e18869f15b24d9c0e547d8e0ab950796d" - integrity sha512-VGTV2QYBa/Kn3WCOKdfS31j9qomaXSgJqi65B6o05/1GsJyj9LVhSljM9ro4S+IBGj/ENhNBuH9bpqzztKAQSw== +babel-preset-jest@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz#66f06136eefce87797539c0d63f1769cc3915984" + integrity sha512-pdZqLEdmy1ZK5kyRUfvBb2IfTPb2BUvIJczlPspS8fWmBQslNNDBqVfh7BW5leOVJMDZKzjD8XEyABTk6gQ5yw== dependencies: "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.3.0" + babel-plugin-jest-hoist "^24.6.0" babel-runtime@^6.26.0: version "6.26.0" @@ -3702,16 +3694,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.5.0.tgz#492fb0df8378d8474cc84b827776b069f46294ed" - integrity sha512-p2Gmc0CLxOgkyA93ySWmHFYHUPFIHG6XZ06l7WArWAsrqYVaVEkOU5NtT5i68KUyGKbkQgDCkiT65bWmdoL6Bw== +expect@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.6.0.tgz#0db9c0acd939d939426f7eef272dc69682b71bb0" + integrity sha512-kxe6ALQboiWfbAvY+ApKyQ42ZGksLPfUhF0Nf0k04aBcLjVxwwn47Uz9Kbv4pELUuzJaU7tvWbvzRpNrIXfcQw== dependencies: - "@jest/types" "^24.5.0" + "@jest/types" "^24.6.0" ansi-styles "^3.2.0" jest-get-type "^24.3.0" - jest-matcher-utils "^24.5.0" - jest-message-util "^24.5.0" + jest-matcher-utils "^24.6.0" + jest-message-util "^24.6.0" jest-regex-util "^24.3.0" extend-shallow@^2.0.1: @@ -4974,54 +4966,54 @@ isurl@^1.0.0-alpha5: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" -jest-changed-files@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.5.0.tgz#4075269ee115d87194fd5822e642af22133cf705" - integrity sha512-Ikl29dosYnTsH9pYa1Tv9POkILBhN/TLZ37xbzgNsZ1D2+2n+8oEZS2yP1BrHn/T4Rs4Ggwwbp/x8CKOS5YJOg== +jest-changed-files@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.6.0.tgz#37ff2a60a6057dedc068f26e9ed9b77fb21df828" + integrity sha512-Om7dJrGPcH6mMdEjMZ5XxRhCLk6qe1NVSJKOIn4twrtH7s8Nd++qULEH9bhRsdNduR2cMQOQwJ9GIVucWEKrsQ== dependencies: - "@jest/types" "^24.5.0" + "@jest/types" "^24.6.0" execa "^1.0.0" throat "^4.0.0" -jest-cli@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.5.0.tgz#598139d3446d1942fb7dc93944b9ba766d756d4b" - integrity sha512-P+Jp0SLO4KWN0cGlNtC7JV0dW1eSFR7eRpoOucP2UM0sqlzp/bVHeo71Omonvigrj9AvCKy7NtQANtqJ7FXz8g== +jest-cli@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.6.0.tgz#af326435b6d331dd9868eed9b0b26d5113cb746e" + integrity sha512-0PDd5XgX/KXAAb00c5ATaCEjh7pw3r0D44K/7mqS9qT7ieawsjJe2bU7wDXkTOw4VhPtv9kK0FghIMqTruMDqg== dependencies: - "@jest/core" "^24.5.0" - "@jest/test-result" "^24.5.0" - "@jest/types" "^24.5.0" + "@jest/core" "^24.6.0" + "@jest/test-result" "^24.6.0" + "@jest/types" "^24.6.0" chalk "^2.0.1" exit "^0.1.2" import-local "^2.0.0" is-ci "^2.0.0" - jest-config "^24.5.0" - jest-util "^24.5.0" - jest-validate "^24.5.0" + jest-config "^24.6.0" + jest-util "^24.6.0" + jest-validate "^24.6.0" prompts "^2.0.1" realpath-native "^1.1.0" yargs "^12.0.2" -jest-config@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.5.0.tgz#404d1bc6bb81aed6bd1890d07e2dca9fbba2e121" - integrity sha512-t2UTh0Z2uZhGBNVseF8wA2DS2SuBiLOL6qpLq18+OZGfFUxTM7BzUVKyHFN/vuN+s/aslY1COW95j1Rw81huOQ== +jest-config@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.6.0.tgz#b8da6c4c2e37556b2a415174798eb7d256754dc1" + integrity sha512-NHXt65TlmwlJnTk2LbISFaL5h4sBLK2wDxw06H+ku9UwplEBYfbYg9//8PPDfx4XqF0QncegUD/bXeX0vJ9Euw== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^24.5.0" - babel-jest "^24.5.0" + "@jest/types" "^24.6.0" + babel-jest "^24.6.0" chalk "^2.0.1" glob "^7.1.1" - jest-environment-jsdom "^24.5.0" - jest-environment-node "^24.5.0" + jest-environment-jsdom "^24.6.0" + jest-environment-node "^24.6.0" jest-get-type "^24.3.0" - jest-jasmine2 "^24.5.0" + jest-jasmine2 "^24.6.0" jest-regex-util "^24.3.0" - jest-resolve "^24.5.0" - jest-util "^24.5.0" - jest-validate "^24.5.0" + jest-resolve "^24.6.0" + jest-util "^24.6.0" + jest-validate "^24.6.0" micromatch "^3.1.10" - pretty-format "^24.5.0" + pretty-format "^24.6.0" realpath-native "^1.1.0" jest-diff@^24.0.0: @@ -5034,15 +5026,15 @@ jest-diff@^24.0.0: jest-get-type "^24.0.0" pretty-format "^24.0.0" -jest-diff@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.5.0.tgz#a2d8627964bb06a91893c0fbcb28ab228c257652" - integrity sha512-mCILZd9r7zqL9Uh6yNoXjwGQx0/J43OD2vvWVKwOEOLZliQOsojXwqboubAQ+Tszrb6DHGmNU7m4whGeB9YOqw== +jest-diff@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.6.0.tgz#35858787c07f94ce51df9f865f375c3b4046c25a" + integrity sha512-r+W4NHYot9ywuiO8JJ3WeDxV+8Bu9vNg7YLWmjLx9RQOC7UtiPcODgvLJIckJ2QIwJ4B/EfjiaLGN24Kew/Y2w== dependencies: chalk "^2.0.1" diff-sequences "^24.3.0" jest-get-type "^24.3.0" - pretty-format "^24.5.0" + pretty-format "^24.6.0" jest-docblock@^21.0.0: version "21.2.0" @@ -5056,39 +5048,39 @@ jest-docblock@^24.3.0: dependencies: detect-newline "^2.1.0" -jest-each@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.5.0.tgz#da14d017a1b7d0f01fb458d338314cafe7f72318" - integrity sha512-6gy3Kh37PwIT5sNvNY2VchtIFOOBh8UCYnBlxXMb5sr5wpJUDPTUATX2Axq1Vfk+HWTMpsYPeVYp4TXx5uqUBw== +jest-each@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.6.0.tgz#945699a577fd2362b620ddf31ad1f7699badb2da" + integrity sha512-+LiF4T/sgpAE4j2p449rwHEJUGPcT+aBOo9mbMSqafnOWGY7R4D1O3DZBGtW7ObumSHj7ZuQkigu9vNQqw5oPQ== dependencies: - "@jest/types" "^24.5.0" + "@jest/types" "^24.6.0" chalk "^2.0.1" jest-get-type "^24.3.0" - jest-util "^24.5.0" - pretty-format "^24.5.0" - -jest-environment-jsdom@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.5.0.tgz#1c3143063e1374100f8c2723a8b6aad23b6db7eb" - integrity sha512-62Ih5HbdAWcsqBx2ktUnor/mABBo1U111AvZWcLKeWN/n/gc5ZvDBKe4Og44fQdHKiXClrNGC6G0mBo6wrPeGQ== - dependencies: - "@jest/environment" "^24.5.0" - "@jest/fake-timers" "^24.5.0" - "@jest/types" "^24.5.0" - jest-mock "^24.5.0" - jest-util "^24.5.0" + jest-util "^24.6.0" + pretty-format "^24.6.0" + +jest-environment-jsdom@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.6.0.tgz#96307b56556fb3557dc90e488fdb901b7724c933" + integrity sha512-nRuKr5vKC9hXOGENgKja50SA0+wNEjsl73qqZV1jwzmMcdzOREuMZZ3jTLQT8/ScOo+SNo9q5YpAp0C+m34Rdw== + dependencies: + "@jest/environment" "^24.6.0" + "@jest/fake-timers" "^24.6.0" + "@jest/types" "^24.6.0" + jest-mock "^24.6.0" + jest-util "^24.6.0" jsdom "^11.5.1" -jest-environment-node@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.5.0.tgz#763eebdf529f75b60aa600c6cf8cb09873caa6ab" - integrity sha512-du6FuyWr/GbKLsmAbzNF9mpr2Iu2zWSaq/BNHzX+vgOcts9f2ayXBweS7RAhr+6bLp6qRpMB6utAMF5Ygktxnw== +jest-environment-node@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.6.0.tgz#51e5aa06da43cd0a9652e0072c8247844968c352" + integrity sha512-3JLQ7FVzOqzjCR3Knt7Nk+nYUaBEkS+H/paZDICzGpJidb/Z1tU4JJdM2G9umr08CyUNyH0LWiZ6yghlE2Kv3w== dependencies: - "@jest/environment" "^24.5.0" - "@jest/fake-timers" "^24.5.0" - "@jest/types" "^24.5.0" - jest-mock "^24.5.0" - jest-util "^24.5.0" + "@jest/environment" "^24.6.0" + "@jest/fake-timers" "^24.6.0" + "@jest/types" "^24.6.0" + jest-mock "^24.6.0" + jest-util "^24.6.0" jest-get-type@^24.0.0: version "24.0.0" @@ -5114,49 +5106,49 @@ jest-haste-map@24.0.0: micromatch "^3.1.10" sane "^3.0.0" -jest-haste-map@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.5.0.tgz#3f17d0c548b99c0c96ed2893f9c0ccecb2eb9066" - integrity sha512-mb4Yrcjw9vBgSvobDwH8QUovxApdimGcOkp+V1ucGGw4Uvr3VzZQBJhNm1UY3dXYm4XXyTW2G7IBEZ9pM2ggRQ== +jest-haste-map@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.6.0.tgz#c6aa40999129fd5cdb52af4ac6c1e8ab653c00d3" + integrity sha512-P0Lhy/vZ/4S7DzVS3KeWMT1FFQ9Qo3QdiqywPoG3FE74iNk44nGzwin3pYnR8dzrfd+SBmutdXLaIfywuU1XxQ== dependencies: - "@jest/types" "^24.5.0" + "@jest/types" "^24.6.0" fb-watchman "^2.0.0" graceful-fs "^4.1.15" invariant "^2.2.4" jest-serializer "^24.4.0" - jest-util "^24.5.0" - jest-worker "^24.4.0" + jest-util "^24.6.0" + jest-worker "^24.6.0" micromatch "^3.1.10" sane "^4.0.3" -jest-jasmine2@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.5.0.tgz#e6af4d7f73dc527d007cca5a5b177c0bcc29d111" - integrity sha512-sfVrxVcx1rNUbBeyIyhkqZ4q+seNKyAG6iM0S2TYBdQsXjoFDdqWFfsUxb6uXSsbimbXX/NMkJIwUZ1uT9+/Aw== +jest-jasmine2@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.6.0.tgz#e8aa40497d7739de84b93af4383fc62381526a06" + integrity sha512-Tx1EqstTsiQ92J5vjHB357W87BrNIKaBab2xgG0Ffu7ZJx9R+RnCKuyKzkIEMRcSso+A70f3Memfsqp7idi4sw== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^24.5.0" - "@jest/test-result" "^24.5.0" - "@jest/types" "^24.5.0" + "@jest/environment" "^24.6.0" + "@jest/test-result" "^24.6.0" + "@jest/types" "^24.6.0" chalk "^2.0.1" co "^4.6.0" - expect "^24.5.0" + expect "^24.6.0" is-generator-fn "^2.0.0" - jest-each "^24.5.0" - jest-matcher-utils "^24.5.0" - jest-message-util "^24.5.0" - jest-runtime "^24.5.0" - jest-snapshot "^24.5.0" - jest-util "^24.5.0" - pretty-format "^24.5.0" + jest-each "^24.6.0" + jest-matcher-utils "^24.6.0" + jest-message-util "^24.6.0" + jest-runtime "^24.6.0" + jest-snapshot "^24.6.0" + jest-util "^24.6.0" + pretty-format "^24.6.0" throat "^4.0.0" -jest-leak-detector@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.5.0.tgz#21ae2b3b0da252c1171cd494f75696d65fb6fa89" - integrity sha512-LZKBjGovFRx3cRBkqmIg+BZnxbrLqhQl09IziMk3oeh1OV81Hg30RUIx885mq8qBv1PA0comB9bjKcuyNO1bCQ== +jest-leak-detector@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.6.0.tgz#4e85938b754a7164271c1f8e3875f0321b37c43f" + integrity sha512-lBYsv8IyBjH4bVdMxT4tZRKwBMLIMl6tKyeQ9htSGkTatmnCI8cvRal/P1x8TJsxFvTo0HLhBUQdmkGWNMu2qg== dependencies: - pretty-format "^24.5.0" + pretty-format "^24.6.0" jest-matcher-utils@^24.0.0: version "24.0.0" @@ -5168,15 +5160,15 @@ jest-matcher-utils@^24.0.0: jest-get-type "^24.0.0" pretty-format "^24.0.0" -jest-matcher-utils@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.5.0.tgz#5995549dcf09fa94406e89526e877b094dad8770" - integrity sha512-QM1nmLROjLj8GMGzg5VBra3I9hLpjMPtF1YqzQS3rvWn2ltGZLrGAO1KQ9zUCVi5aCvrkbS5Ndm2evIP9yZg1Q== +jest-matcher-utils@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.6.0.tgz#8562d38a760238656806df2f77daeca9a0c5851a" + integrity sha512-bXC5aDKXd1t7FfRiEahVoDWuvZI7NMWPd5u8Mn6aPMmQ0k+wG8RmASKjfuCGUOQJ4egV2hTx3wBQ8aipz3qFoA== dependencies: chalk "^2.0.1" - jest-diff "^24.5.0" + jest-diff "^24.6.0" jest-get-type "^24.3.0" - pretty-format "^24.5.0" + pretty-format "^24.6.0" jest-message-util@^24.0.0: version "24.0.0" @@ -5189,26 +5181,26 @@ jest-message-util@^24.0.0: slash "^2.0.0" stack-utils "^1.0.1" -jest-message-util@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.5.0.tgz#181420a65a7ef2e8b5c2f8e14882c453c6d41d07" - integrity sha512-6ZYgdOojowCGiV0D8WdgctZEAe+EcFU+KrVds+0ZjvpZurUW2/oKJGltJ6FWY2joZwYXN5VL36GPV6pNVRqRnQ== +jest-message-util@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.6.0.tgz#585b8dd65c34a9d0e6f68b3feeb46918ee40b976" + integrity sha512-5VEaI9jAm78YlMqNa92670QU/+d4F5TK0eiKEVQ3KwYbVL1kp8RmHg/2oqiKC3LMulyzlIiaqZTnJPk3hcqxwQ== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^24.5.0" - "@jest/types" "^24.5.0" + "@jest/test-result" "^24.6.0" + "@jest/types" "^24.6.0" "@types/stack-utils" "^1.0.1" chalk "^2.0.1" micromatch "^3.1.10" slash "^2.0.0" stack-utils "^1.0.1" -jest-mock@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.5.0.tgz#976912c99a93f2a1c67497a9414aa4d9da4c7b76" - integrity sha512-ZnAtkWrKf48eERgAOiUxVoFavVBziO2pAi2MfZ1+bGXVkDfxWLxU0//oJBkgwbsv6OAmuLBz4XFFqvCFMqnGUw== +jest-mock@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.6.0.tgz#fd21d9f0c4b77d6b1cbd320223a56c5ae294b86b" + integrity sha512-GoJKwJrQUlI0yYLUO6fhR+s+aBqgCBERCdA8nDbMuqntkuydwLtMcYJI05eEWXL4zsH5Hw4Z5wfiMLjZsZZ3QA== dependencies: - "@jest/types" "^24.5.0" + "@jest/types" "^24.6.0" jest-pnp-resolver@^1.2.1: version "1.2.1" @@ -5220,14 +5212,14 @@ jest-regex-util@^24.3.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.3.0.tgz#d5a65f60be1ae3e310d5214a0307581995227b36" integrity sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg== -jest-resolve-dependencies@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.5.0.tgz#1a0dae9cdd41349ca4a84148b3e78da2ba33fd4b" - integrity sha512-dRVM1D+gWrFfrq2vlL5P9P/i8kB4BOYqYf3S7xczZ+A6PC3SgXYSErX/ScW/469pWMboM1uAhgLF+39nXlirCQ== +jest-resolve-dependencies@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.6.0.tgz#227c685b09a4a354615624069877de8070795daa" + integrity sha512-2QVOYOJVTI4sNcXAL1P22/qW7A2u2V7Y69OlVWAyUmN+XVoVjCbz7AwUCJjIOLyg5isxQqSJBPQC0tXUUGl0xA== dependencies: - "@jest/types" "^24.5.0" + "@jest/types" "^24.6.0" jest-regex-util "^24.3.0" - jest-snapshot "^24.5.0" + jest-snapshot "^24.6.0" jest-resolve@^24.0.0: version "24.0.0" @@ -5238,66 +5230,66 @@ jest-resolve@^24.0.0: chalk "^2.0.1" realpath-native "^1.0.0" -jest-resolve@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.5.0.tgz#8c16ba08f60a1616c3b1cd7afb24574f50a24d04" - integrity sha512-ZIfGqLX1Rg8xJpQqNjdoO8MuxHV1q/i2OO1hLXjgCWFWs5bsedS8UrOdgjUqqNae6DXA+pCyRmdcB7lQEEbXew== +jest-resolve@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.6.0.tgz#7ab8e6b274d5dac6df5c4911f0cd0af0124b44f7" + integrity sha512-d72QLxKtVb4M+3GRyxSWMQ2umgTktleqrgarSwpRkRECYE7xg55655cgPEj2cfhBjFkj6Pq4mAU2P3GRploMmQ== dependencies: - "@jest/types" "^24.5.0" + "@jest/types" "^24.6.0" browser-resolve "^1.11.3" chalk "^2.0.1" jest-pnp-resolver "^1.2.1" realpath-native "^1.1.0" -jest-runner@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.5.0.tgz#9be26ece4fd4ab3dfb528b887523144b7c5ffca8" - integrity sha512-oqsiS9TkIZV5dVkD+GmbNfWBRPIvxqmlTQ+AQUJUQ07n+4xTSDc40r+aKBynHw9/tLzafC00DIbJjB2cOZdvMA== +jest-runner@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.6.0.tgz#0ac88de5493333a2c8bd7254adfab8f547d37bef" + integrity sha512-CFvh7LT4ROqm6Nj0mynUSGA/6QXXoUHij+9GRE2YYp/oY5qntJPmwTXewrEH7bx5LBV8F3EEFSW0c5YavV5X6w== dependencies: - "@jest/console" "^24.3.0" - "@jest/environment" "^24.5.0" - "@jest/test-result" "^24.5.0" - "@jest/types" "^24.5.0" + "@jest/console" "^24.6.0" + "@jest/environment" "^24.6.0" + "@jest/test-result" "^24.6.0" + "@jest/types" "^24.6.0" chalk "^2.4.2" exit "^0.1.2" graceful-fs "^4.1.15" - jest-config "^24.5.0" + jest-config "^24.6.0" jest-docblock "^24.3.0" - jest-haste-map "^24.5.0" - jest-jasmine2 "^24.5.0" - jest-leak-detector "^24.5.0" - jest-message-util "^24.5.0" - jest-resolve "^24.5.0" - jest-runtime "^24.5.0" - jest-util "^24.5.0" - jest-worker "^24.4.0" + jest-haste-map "^24.6.0" + jest-jasmine2 "^24.6.0" + jest-leak-detector "^24.6.0" + jest-message-util "^24.6.0" + jest-resolve "^24.6.0" + jest-runtime "^24.6.0" + jest-util "^24.6.0" + jest-worker "^24.6.0" source-map-support "^0.5.6" throat "^4.0.0" -jest-runtime@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.5.0.tgz#3a76e0bfef4db3896d5116e9e518be47ba771aa2" - integrity sha512-GTFHzfLdwpaeoDPilNpBrorlPoNZuZrwKKzKJs09vWwHo+9TOsIIuszK8cWOuKC7ss07aN1922Ge8fsGdsqCuw== +jest-runtime@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.6.0.tgz#ec697c4a2b5e4128972c004a5dcfbbdd0979998b" + integrity sha512-DkMEP5ygtW1MSvjAEJ2euV8Z5UUm/G8RlJN2vH5kmsV+J/Snm32JD3LuaD8NuTeO7iKnUPEU70dFTtJsd8n5xg== dependencies: - "@jest/console" "^24.3.0" - "@jest/environment" "^24.5.0" + "@jest/console" "^24.6.0" + "@jest/environment" "^24.6.0" "@jest/source-map" "^24.3.0" - "@jest/transform" "^24.5.0" - "@jest/types" "^24.5.0" + "@jest/transform" "^24.6.0" + "@jest/types" "^24.6.0" "@types/yargs" "^12.0.2" chalk "^2.0.1" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.1.15" - jest-config "^24.5.0" - jest-haste-map "^24.5.0" - jest-message-util "^24.5.0" - jest-mock "^24.5.0" + jest-config "^24.6.0" + jest-haste-map "^24.6.0" + jest-message-util "^24.6.0" + jest-mock "^24.6.0" jest-regex-util "^24.3.0" - jest-resolve "^24.5.0" - jest-snapshot "^24.5.0" - jest-util "^24.5.0" - jest-validate "^24.5.0" + jest-resolve "^24.6.0" + jest-snapshot "^24.6.0" + jest-util "^24.6.0" + jest-validate "^24.6.0" realpath-native "^1.1.0" slash "^2.0.0" strip-bom "^3.0.0" @@ -5329,22 +5321,22 @@ jest-snapshot@^24.0.0: pretty-format "^24.0.0" semver "^5.5.0" -jest-snapshot@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.5.0.tgz#e5d224468a759fd19e36f01217aac912f500f779" - integrity sha512-eBEeJb5ROk0NcpodmSKnCVgMOo+Qsu5z9EDl3tGffwPzK1yV37mjGWF2YeIz1NkntgTzP+fUL4s09a0+0dpVWA== +jest-snapshot@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.6.0.tgz#ec68e0982c1e38cbaefd2cff2c9ac99fdfe5c206" + integrity sha512-G+1q27n6lOdzqpcmP5GnpCfwz4t0E/wasoyNdqvjb6gbLCdfo6Y5ZcPxiclYNOBtGATbbb3IVXeR+ey3aWjSFg== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^24.5.0" + "@jest/types" "^24.6.0" chalk "^2.0.1" - expect "^24.5.0" - jest-diff "^24.5.0" - jest-matcher-utils "^24.5.0" - jest-message-util "^24.5.0" - jest-resolve "^24.5.0" + expect "^24.6.0" + jest-diff "^24.6.0" + jest-matcher-utils "^24.6.0" + jest-message-util "^24.6.0" + jest-resolve "^24.6.0" mkdirp "^0.5.1" natural-compare "^1.4.0" - pretty-format "^24.5.0" + pretty-format "^24.6.0" semver "^5.5.0" jest-util@^24.0.0: @@ -5361,17 +5353,16 @@ jest-util@^24.0.0: slash "^2.0.0" source-map "^0.6.0" -jest-util@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.5.0.tgz#9d9cb06d9dcccc8e7cc76df91b1635025d7baa84" - integrity sha512-Xy8JsD0jvBz85K7VsTIQDuY44s+hYJyppAhcsHsOsGisVtdhar6fajf2UOf2mEVEgh15ZSdA0zkCuheN8cbr1Q== +jest-util@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.6.0.tgz#725a380e8f21fcdf53bd5bd5829ee78903ffc756" + integrity sha512-f7JbP/tfJuc955+PMvCI49Mn8wCPe+5CV4vSfc2Pi06jrSDGlsTj6mmc5+UF8ApzIQ7ficTUv4JXXcjplbm9TA== dependencies: - "@jest/console" "^24.3.0" - "@jest/fake-timers" "^24.5.0" + "@jest/console" "^24.6.0" + "@jest/fake-timers" "^24.6.0" "@jest/source-map" "^24.3.0" - "@jest/test-result" "^24.5.0" - "@jest/types" "^24.5.0" - "@types/node" "*" + "@jest/test-result" "^24.6.0" + "@jest/types" "^24.6.0" callsites "^3.0.0" chalk "^2.0.1" graceful-fs "^4.1.15" @@ -5380,30 +5371,29 @@ jest-util@^24.5.0: slash "^2.0.0" source-map "^0.6.0" -jest-validate@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.5.0.tgz#62fd93d81214c070bb2d7a55f329a79d8057c7de" - integrity sha512-gg0dYszxjgK2o11unSIJhkOFZqNRQbWOAB2/LOUdsd2LfD9oXiMeuee8XsT0iRy5EvSccBgB4h/9HRbIo3MHgQ== +jest-validate@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.6.0.tgz#7ad68c68bf2639295cd727817f468e840e950507" + integrity sha512-iBbRzTCyjHidvRUor2KM8FeMAFDWok6/c39fGwRDaLwjlPhDVPy44RLZst8wMRSj1W/Ujdd570btK9SS71CKjw== dependencies: - "@jest/types" "^24.5.0" + "@jest/types" "^24.6.0" camelcase "^5.0.0" chalk "^2.0.1" jest-get-type "^24.3.0" leven "^2.1.0" - pretty-format "^24.5.0" + pretty-format "^24.6.0" -jest-watcher@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.5.0.tgz#da7bd9cb5967e274889b42078c8f501ae1c47761" - integrity sha512-/hCpgR6bg0nKvD3nv4KasdTxuhwfViVMHUATJlnGCD0r1QrmIssimPbmc5KfAQblAVxkD8xrzuij9vfPUk1/rA== +jest-watcher@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.6.0.tgz#f66a49a4c89f60626730121d74e36dc006c53c2f" + integrity sha512-u9YFF8VjGh8vRwuNpuVUAwZFZno+lZuqayITjXkwEsWumuUNx0s9/6+DvB/AiQx/FxcpbXlMDNAflFa7vs7UHg== dependencies: - "@jest/test-result" "^24.5.0" - "@jest/types" "^24.5.0" - "@types/node" "*" + "@jest/test-result" "^24.6.0" + "@jest/types" "^24.6.0" "@types/yargs" "^12.0.9" ansi-escapes "^3.0.0" chalk "^2.0.1" - jest-util "^24.5.0" + jest-util "^24.6.0" string-length "^2.0.0" jest-worker@24.0.0, jest-worker@^24.0.0: @@ -5414,22 +5404,21 @@ jest-worker@24.0.0, jest-worker@^24.0.0: merge-stream "^1.0.1" supports-color "^6.1.0" -jest-worker@^24.4.0: - version "24.4.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.4.0.tgz#fbc452b0120bb5c2a70cdc88fa132b48eeb11dd0" - integrity sha512-BH9X/klG9vxwoO99ZBUbZFfV8qO0XNZ5SIiCyYK2zOuJBl6YJVAeNIQjcoOVNu4HGEHeYEKsUWws8kSlSbZ9YQ== +jest-worker@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.6.0.tgz#7f81ceae34b7cde0c9827a6980c35b7cdc0161b3" + integrity sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ== dependencies: - "@types/node" "*" merge-stream "^1.0.1" supports-color "^6.1.0" -jest@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.5.0.tgz#38f11ae2c2baa2f86c2bc4d8a91d2b51612cd19a" - integrity sha512-lxL+Fq5/RH7inxxmfS2aZLCf8MsS+YCUBfeiNO6BWz/MmjhDGaIEA/2bzEf9q4Q0X+mtFHiinHFvQ0u+RvW/qQ== +jest@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.6.0.tgz#133e46c3f92450402e5b6737f5a07620c3f8201e" + integrity sha512-09Y/1FUQIGRVY2hdt0VpiL5mH0MGKeNM+Rhd1qWUZEBI/HwI6upHQR5XxlTm5d0BpXvhB/8bDpHu5ehL7JGi1g== dependencies: import-local "^2.0.0" - jest-cli "^24.5.0" + jest-cli "^24.6.0" joi@^14.3.1: version "14.3.1" @@ -7116,12 +7105,12 @@ pretty-format@^24.0.0: ansi-regex "^4.0.0" ansi-styles "^3.2.0" -pretty-format@^24.5.0: - version "24.5.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.5.0.tgz#cc69a0281a62cd7242633fc135d6930cd889822d" - integrity sha512-/3RuSghukCf8Riu5Ncve0iI+BzVkbRU5EeUoArKARZobREycuH5O4waxvaNIloEXdb0qwgmEAed5vTpX1HNROQ== +pretty-format@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.6.0.tgz#66124fe5ea5c4d473337a204ece220e8fdc9806c" + integrity sha512-xEeJZFqXgvzSEMxoZ3j4aTaax/pl1upVsfMstcIC048Id84Ve5aqX0WkAta/wFIBLDRz6Tbuj6HcoBXRNk7rtA== dependencies: - "@jest/types" "^24.5.0" + "@jest/types" "^24.6.0" ansi-regex "^4.0.0" ansi-styles "^3.2.0" react-is "^16.8.4" From b899993e99b0ef668b8c204764a589c4ada5cc9f Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 18:53:13 +0200 Subject: [PATCH 16/46] Add findDependencies suite and fix one bugg --- .../config/__tests__/findDependencies-test.js | 50 +++++++++++++++++++ .../cli/src/tools/config/findDependencies.js | 5 ++ 2 files changed, 55 insertions(+) create mode 100644 packages/cli/src/tools/config/__tests__/findDependencies-test.js diff --git a/packages/cli/src/tools/config/__tests__/findDependencies-test.js b/packages/cli/src/tools/config/__tests__/findDependencies-test.js new file mode 100644 index 000000000..684251600 --- /dev/null +++ b/packages/cli/src/tools/config/__tests__/findDependencies-test.js @@ -0,0 +1,50 @@ +/** + * @flow + */ + +import findDependencies from '../findDependencies'; + +const path = require('path'); + +import { + cleanup, + writeFiles, + getTempDirectory, +} from '../../../../../../e2e/helpers'; + +beforeEach(() => { + cleanup(DIR); + jest.resetModules(); +}); + +afterEach(() => cleanup(DIR)); + +const DIR = getTempDirectory('find_dependencies_test'); + +test('returns plugins from both dependencies and dev dependencies', () => { + writeFiles(DIR, { + 'package.json': ` + { + "dependencies": {"rnpm-plugin-test": "*"}, + "devDependencies": {"rnpm-plugin-test-2": "*"} + } + `, + }); + expect(findDependencies(DIR)).toHaveLength(2); +}); + +test('returns plugins in scoped modules', () => { + writeFiles(DIR, { + 'package.json': ` + { + "dependencies": { + "@org/rnpm-plugin-test": "*", + "@org/react-native-test": "*", + "@react-native/test": "*", + "@react-native-org/test": "*" + } + } + `, + }); + expect(findDependencies(DIR)).toHaveLength(4); +}); diff --git a/packages/cli/src/tools/config/findDependencies.js b/packages/cli/src/tools/config/findDependencies.js index 7fda35955..acbdda475 100644 --- a/packages/cli/src/tools/config/findDependencies.js +++ b/packages/cli/src/tools/config/findDependencies.js @@ -6,9 +6,14 @@ import path from 'path'; const pluginRe = new RegExp( [ + // React Native patterns '^react-native-', '^@(.*)/react-native-', '^@react-native(.*)/(?!rnpm-plugin-)', + + // RNPM patterns to be deprecated + '^rnpm-plugin-', + '^@(.*)/rnpm-plugin-', ].join('|'), ); From c82824bfb69ae0d1e9e8b041e49189e2b2675867 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 18:55:32 +0200 Subject: [PATCH 17/46] Rename snapshots instead of creating a new one --- .../__snapshots__/index-test.js.snap | 6 - .../__tests__/__snapshots__/index.js.snap | 160 ------------------ 2 files changed, 166 deletions(-) delete mode 100644 packages/cli/src/tools/config/__tests__/__snapshots__/index.js.snap diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap index e26a23c3a..1efb53808 100644 --- a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap +++ b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap @@ -2,13 +2,11 @@ exports[`should deep merge project configuration with default values 1`] = ` Object { - "assets": Array [], "commands": Array [], "dependencies": Object { "react-native-test": Object { "assets": Array [], "hooks": Object {}, - "name": "react-native-test", "params": Array [], "platforms": Object { "android": null, @@ -46,7 +44,6 @@ Object { exports[`should have a valid structure by default 1`] = ` Object { - "assets": Array [], "commands": Array [], "dependencies": Object {}, "haste": Object { @@ -95,7 +92,6 @@ exports[`should read \`rnpm\` config from a dependency and transform it to a new Object { "assets": Array [], "hooks": Object {}, - "name": "react-native-foo", "params": Array [], "platforms": Object { "android": null, @@ -119,7 +115,6 @@ exports[`should read a config of a dependency and use it to load other settings Object { "assets": Array [], "hooks": Object {}, - "name": "react-native-test", "params": Array [], "platforms": Object { "android": null, @@ -144,7 +139,6 @@ Object { "react-native-test": Object { "assets": Array [], "hooks": Object {}, - "name": "react-native-test", "params": Array [], "platforms": Object { "android": null, diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index.js.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index.js.snap deleted file mode 100644 index 1efb53808..000000000 --- a/packages/cli/src/tools/config/__tests__/__snapshots__/index.js.snap +++ /dev/null @@ -1,160 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should deep merge project configuration with default values 1`] = ` -Object { - "commands": Array [], - "dependencies": Object { - "react-native-test": Object { - "assets": Array [], - "hooks": Object {}, - "params": Array [], - "platforms": Object { - "android": null, - "ios": Object { - "folder": "<>/node_modules/react-native-test", - "libraryFolder": "Libraries", - "pbxprojPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj/project.pbxproj", - "plist": Array [], - "podfile": null, - "podspec": null, - "projectName": "HelloWorld.xcodeproj", - "projectPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj", - "sharedLibraries": Array [], - "sourceDir": "./abc", - }, - }, - }, - }, - "haste": Object { - "platforms": Array [], - "providesModuleNodeModules": Array [], - }, - "platforms": Object { - "android": Object {}, - "ios": Object {}, - }, - "project": Object { - "android": null, - "ios": null, - }, - "reactNativePath": ".", - "root": "<>", -} -`; - -exports[`should have a valid structure by default 1`] = ` -Object { - "commands": Array [], - "dependencies": Object {}, - "haste": Object { - "platforms": Array [], - "providesModuleNodeModules": Array [], - }, - "platforms": Object { - "android": Object {}, - "ios": Object {}, - }, - "project": Object { - "android": null, - "ios": null, - }, - "reactNativePath": ".", - "root": "<>", -} -`; - -exports[`should load an out-of-tree "windows" platform that ships with a dependency 1`] = ` -Object { - "haste": Object { - "platforms": Array [ - "windows", - ], - "providesModuleNodeModules": Array [ - "react-native-windows", - ], - }, - "platforms": Object { - "android": Object {}, - "ios": Object {}, - "windows": Object {}, - }, -} -`; - -exports[`should load commands from "react-native-foo" and "react-native-bar" packages 1`] = ` -Array [ - "react-native-foo/command-foo.js", - "react-native-bar/command-bar.js", -] -`; - -exports[`should read \`rnpm\` config from a dependency and transform it to a new format 1`] = ` -Object { - "assets": Array [], - "hooks": Object {}, - "params": Array [], - "platforms": Object { - "android": null, - "ios": Object { - "folder": "<>/node_modules/react-native-foo", - "libraryFolder": "Libraries", - "pbxprojPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj/project.pbxproj", - "plist": Array [], - "podfile": null, - "podspec": null, - "projectName": "customProject.xcodeproj", - "projectPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj", - "sharedLibraries": Array [], - "sourceDir": "<>/node_modules/react-native-foo/customLocation", - }, - }, -} -`; - -exports[`should read a config of a dependency and use it to load other settings 1`] = ` -Object { - "assets": Array [], - "hooks": Object {}, - "params": Array [], - "platforms": Object { - "android": null, - "ios": Object { - "folder": "<>/node_modules/react-native-test", - "libraryFolder": "Libraries", - "pbxprojPath": "<>/node_modules/react-native-test/customLocation/customProject.xcodeproj/project.pbxproj", - "plist": Array [], - "podfile": null, - "podspec": null, - "projectName": "customProject.xcodeproj", - "projectPath": "<>/node_modules/react-native-test/customLocation/customProject.xcodeproj", - "sharedLibraries": Array [], - "sourceDir": "<>/node_modules/react-native-test/customLocation", - }, - }, -} -`; - -exports[`should return dependencies from package.json 1`] = ` -Object { - "react-native-test": Object { - "assets": Array [], - "hooks": Object {}, - "params": Array [], - "platforms": Object { - "android": null, - "ios": Object { - "folder": "<>/node_modules/react-native-test", - "libraryFolder": "Libraries", - "pbxprojPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj/project.pbxproj", - "plist": Array [], - "podfile": null, - "podspec": null, - "projectName": "HelloWorld.xcodeproj", - "projectPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj", - "sharedLibraries": Array [], - "sourceDir": "<>/node_modules/react-native-test/ios", - }, - }, - }, -} -`; From fa83f1fd4f723df5e4a7a96c5c7212ba854f202e Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 18:59:14 +0200 Subject: [PATCH 18/46] Update snapshots with new fields --- .../tools/config/__tests__/__snapshots__/index-test.js.snap | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap index 1efb53808..0d2af93f6 100644 --- a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap +++ b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap @@ -2,11 +2,13 @@ exports[`should deep merge project configuration with default values 1`] = ` Object { + "assets": [], "commands": Array [], "dependencies": Object { "react-native-test": Object { "assets": Array [], "hooks": Object {}, + "name": "react-native-test", "params": Array [], "platforms": Object { "android": null, @@ -44,6 +46,7 @@ Object { exports[`should have a valid structure by default 1`] = ` Object { + "assets": Array [], "commands": Array [], "dependencies": Object {}, "haste": Object { @@ -91,6 +94,7 @@ Array [ exports[`should read \`rnpm\` config from a dependency and transform it to a new format 1`] = ` Object { "assets": Array [], + "name": "react-native-foo", "hooks": Object {}, "params": Array [], "platforms": Object { @@ -115,6 +119,7 @@ exports[`should read a config of a dependency and use it to load other settings Object { "assets": Array [], "hooks": Object {}, + "name": "react-native-test", "params": Array [], "platforms": Object { "android": null, @@ -139,6 +144,7 @@ Object { "react-native-test": Object { "assets": Array [], "hooks": Object {}, + "name": "react-native-test", "params": Array [], "platforms": Object { "android": null, From 72485a559b59b76eacfabc42a352ed9ecfb6056b Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 19:02:32 +0200 Subject: [PATCH 19/46] Update snapshots --- .../getDependencyConfig-test.js.snap | 19 ------- .../__snapshots__/index-test.js.snap | 57 +------------------ 2 files changed, 1 insertion(+), 75 deletions(-) delete mode 100644 packages/cli/src/commands/link/__tests__/__snapshots__/getDependencyConfig-test.js.snap diff --git a/packages/cli/src/commands/link/__tests__/__snapshots__/getDependencyConfig-test.js.snap b/packages/cli/src/commands/link/__tests__/__snapshots__/getDependencyConfig-test.js.snap deleted file mode 100644 index 9fc3eecc9..000000000 --- a/packages/cli/src/commands/link/__tests__/__snapshots__/getDependencyConfig-test.js.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`getDependencyConfig should return an array of dependencies' config 1`] = ` -Object { - "assets": Array [], - "commands": Object {}, - "config": Object { - "android": Object { - "sampleAndroidKey": "", - }, - "ios": Object { - "sampleiOSKey": "", - }, - }, - "name": "react-native-windows", - "params": Array [], - "path": "/root/node_modules/react-native-windows", -} -`; diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap index 0d2af93f6..55267e27f 100644 --- a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap +++ b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap @@ -2,7 +2,7 @@ exports[`should deep merge project configuration with default values 1`] = ` Object { - "assets": [], + "assets": Array [], "commands": Array [], "dependencies": Object { "react-native-test": Object { @@ -84,61 +84,6 @@ Object { } `; -exports[`should load commands from "react-native-foo" and "react-native-bar" packages 1`] = ` -Array [ - "react-native-foo/command-foo.js", - "react-native-bar/command-bar.js", -] -`; - -exports[`should read \`rnpm\` config from a dependency and transform it to a new format 1`] = ` -Object { - "assets": Array [], - "name": "react-native-foo", - "hooks": Object {}, - "params": Array [], - "platforms": Object { - "android": null, - "ios": Object { - "folder": "<>/node_modules/react-native-foo", - "libraryFolder": "Libraries", - "pbxprojPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj/project.pbxproj", - "plist": Array [], - "podfile": null, - "podspec": null, - "projectName": "customProject.xcodeproj", - "projectPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj", - "sharedLibraries": Array [], - "sourceDir": "<>/node_modules/react-native-foo/customLocation", - }, - }, -} -`; - -exports[`should read a config of a dependency and use it to load other settings 1`] = ` -Object { - "assets": Array [], - "hooks": Object {}, - "name": "react-native-test", - "params": Array [], - "platforms": Object { - "android": null, - "ios": Object { - "folder": "<>/node_modules/react-native-test", - "libraryFolder": "Libraries", - "pbxprojPath": "<>/node_modules/react-native-test/customLocation/customProject.xcodeproj/project.pbxproj", - "plist": Array [], - "podfile": null, - "podspec": null, - "projectName": "customProject.xcodeproj", - "projectPath": "<>/node_modules/react-native-test/customLocation/customProject.xcodeproj", - "sharedLibraries": Array [], - "sourceDir": "<>/node_modules/react-native-test/customLocation", - }, - }, -} -`; - exports[`should return dependencies from package.json 1`] = ` Object { "react-native-test": Object { From b60a3818b411c62b0320c9e6a976c045d310ca8c Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 20:15:11 +0200 Subject: [PATCH 20/46] Update link tests --- .../src/commands/link/__tests__/link-test.js | 401 ++++++++---------- 1 file changed, 174 insertions(+), 227 deletions(-) diff --git a/packages/cli/src/commands/link/__tests__/link-test.js b/packages/cli/src/commands/link/__tests__/link-test.js index 59e905d9f..b94f266bb 100644 --- a/packages/cli/src/commands/link/__tests__/link-test.js +++ b/packages/cli/src/commands/link/__tests__/link-test.js @@ -1,18 +1,21 @@ /** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @emails oncall+javascript_foundation + * @flow */ +import {func as link} from '../link'; +import loadConfig from '../../../tools/config'; jest.mock('chalk', () => ({grey: str => str})); +jest.mock('../../../tools/config'); jest.mock('../../../tools/logger'); -const context = { - root: process.cwd(), +const baseConfig = loadConfig(); + +const baseDependencyConfig = { + name: 'react-native-gradient', + assets: [], + hooks: {}, + params: [], + platforms: {ios: {}, android: {}}, }; describe('link', () => { @@ -20,89 +23,74 @@ describe('link', () => { jest.resetModules(); }); - it('should reject when run in a folder without package.json', done => { - const link = require('../link').func; - link([], {root: '/'}, {}).catch(() => done()); - }); - - it('should accept a name of a dependency to link', done => { - const getDependencyConfig = jest.fn(() => ({ - config: { - ios: null, - android: null, + it('should accept a name of a dependency to link', async () => { + const config = { + ...baseConfig, + dependencies: { + get ['react-native-gradient']() { + return baseDependencyConfig; + }, }, - assets: [], - commands: {}, - })); + }; - jest.doMock('../getDependencyConfig', () => getDependencyConfig); + const spy = jest.spyOn(config.dependencies, 'react-native-gradient', 'get'); - const link = require('../link').func; - link(['react-native-gradient'], context, {}).then(() => { - expect(getDependencyConfig.mock.calls[0][2]).toEqual( - 'react-native-gradient', - ); - done(); - }); + await link(['react-native-gradient'], config, {}); + + expect(spy).toHaveBeenCalled(); }); it('should accept the name of a dependency with a scope / tag', async () => { - const getDependencyConfig = jest.fn(() => ({ - config: { - ios: null, - android: null, + const config = { + ...baseConfig, + dependencies: { + get ['@scope/something']() { + return baseDependencyConfig; + }, }, - assets: [], - commands: {}, - })); + }; - jest.doMock('../getDependencyConfig', () => getDependencyConfig); + const spy = jest.spyOn(config.dependencies, '@scope/something', 'get'); - const link = require('../link').func; - await link(['@scope/something@latest'], context, {}); + await link(['@scope/something@latest'], config, {}); - expect(getDependencyConfig.mock.calls[0][2]).toEqual('@scope/something'); + expect(spy).toHaveBeenCalled(); }); it('should register native module when android/ios projects are present', done => { const prelink = jest.fn().mockImplementation(cb => cb()); const postlink = jest.fn().mockImplementation(cb => cb()); + const registerNativeModule = jest.fn(); - jest.doMock('../getProjectConfig', () => () => ({ - ios: {}, - android: {}, - })); - - const getDependencyConfig = jest.fn(() => ({ - config: { + const config = { + ...baseConfig, + project: { ios: {}, android: {}, }, - assets: [], - commands: {prelink, postlink}, - })); - - jest.doMock('../getDependencyConfig', () => getDependencyConfig); - - const registerNativeModule = jest.fn(); - - jest.doMock('../android/isInstalled.js', () => - jest.fn().mockReturnValue(false), - ); - jest.doMock( - '../android/registerNativeModule.js', - () => registerNativeModule, - ); - - jest.doMock('../ios/isInstalled.js', () => - jest.fn().mockReturnValue(false), - ); - jest.doMock('../ios/registerNativeModule.js', () => registerNativeModule); - - const link = require('../link').func; - registerNativeModule.mockClear(); + platforms: { + ios: { + linkConfig: () => ({ + register: registerNativeModule, + isInstalled: jest.fn().mockReturnValue(false), + }), + }, + android: { + linkConfig: () => ({ + register: registerNativeModule, + isInstalled: jest.fn().mockReturnValue(false), + }), + }, + }, + dependencies: { + 'react-native-blur': { + ...baseDependencyConfig, + hooks: {prelink, postlink}, + }, + }, + }; - link(['react-native-blur'], context, {}).then(() => { + link(['react-native-blur'], config, {}).then(() => { expect(registerNativeModule.mock.calls).toHaveLength(2); expect(prelink.mock.invocationCallOrder[0]).toBeLessThan( @@ -121,199 +109,158 @@ describe('link', () => { const dependencyAssets = ['Fonts/Font.ttf']; const projectAssets = ['Fonts/FontC.ttf']; - jest.doMock('../getProjectConfig', () => () => ({ - ios: {}, - android: {}, - })); + const copyAssets = jest.fn(); + const dependency = { + ...baseDependencyConfig, + assets: dependencyAssets, + }; - jest.doMock('../getDependencyConfig', () => () => ({ - config: { + const config = { + ...baseConfig, + project: { ios: {}, android: {}, }, - assets: dependencyAssets, - commands: {}, - })); - - jest.doMock('../android/isInstalled.js', () => - jest.fn().mockReturnValue(false), - ); - jest.doMock('../android/registerNativeModule.js', () => jest.fn()); - - jest.doMock('../ios/isInstalled.js', () => - jest.fn().mockReturnValue(false), - ); - jest.doMock('../ios/registerNativeModule.js', () => jest.fn()); - - jest.doMock('../../../tools/getAssets', () => projectAssets); - - const copyAssets = jest.fn(); - - jest.doMock('../ios/copyAssets.js', () => copyAssets); - jest.doMock('../android/copyAssets.js', () => copyAssets); - - const link = require('../link').func; + platforms: { + ios: { + linkConfig: () => ({ + register: jest.fn(), + copyAssets, + isInstalled: jest.fn().mockReturnValue(false), + }), + }, + android: { + linkConfig: () => ({ + register: jest.fn(), + copyAssets, + isInstalled: jest.fn().mockReturnValue(false), + }), + }, + }, + dependencies: { + 'react-native-blur': dependency, + }, + assets: projectAssets, + }; - link(['react-native-blur'], context, {}).then(() => { + link(['react-native-blur'], config, {}).then(() => { expect(copyAssets.mock.calls).toHaveLength(2); expect(copyAssets.mock.calls[0][0]).toEqual(dependencyAssets); - jest.unmock('../../../tools/getAssets'); done(); }); }); it('should not register modules when they are already installed', done => { - jest.doMock('../getProjectConfig', () => () => ({ - ios: {}, - android: {}, - })); + const registerNativeModule = jest.fn(); - const getDependencyConfig = jest.fn(() => ({ - config: { + const config = { + ...baseConfig, + project: { ios: {}, android: {}, }, - assets: [], - commands: {}, - })); - - jest.doMock('../getDependencyConfig', () => getDependencyConfig); - - const registerNativeModule = jest.fn(); - - jest.doMock('../android/isInstalled.js', () => - jest.fn().mockReturnValue(true), - ); - jest.doMock( - '../android/registerNativeModule.js', - () => registerNativeModule, - ); - - jest.doMock('../ios/isInstalled.js', () => jest.fn().mockReturnValue(true)); - jest.doMock('../ios/registerNativeModule.js', () => registerNativeModule); - - const link = require('../link').func; + platforms: { + ios: { + linkConfig: () => ({ + register: registerNativeModule, + isInstalled: jest.fn().mockReturnValue(true), + }), + }, + android: { + linkConfig: () => ({ + register: registerNativeModule, + isInstalled: jest.fn().mockReturnValue(true), + }), + }, + }, + dependencies: { + 'react-native-blur': baseDependencyConfig, + }, + }; - link(['react-native-blur', {}], context, {}).then(() => { + link(['react-native-blur', {}], config, {}).then(() => { expect(registerNativeModule.mock.calls).toHaveLength(0); done(); }); }); it('should register native modules for additional platforms', done => { - jest.doMock('../getProjectConfig', () => () => ({ - ios: {}, - android: {}, - windows: {}, - })); - const registerNativeModule = jest.fn(); - const genericLinkConfig = () => ({ - isInstalled: () => false, - register: registerNativeModule, - }); - - const getDependencyConfig = jest.fn(() => ({ - config: { + const config = { + ...baseConfig, + project: { ios: {}, android: {}, windows: {}, }, - assets: [], - commands: {}, - })); - - jest.doMock('../../../tools/getPlatforms', () => { - const fn = () => ({ - ios: {linkConfig: require('../ios').default}, - android: {linkConfig: require('../android').default}, - windows: {linkConfig: genericLinkConfig}, - }); - fn.getPlatformName = jest.fn(); - return fn; - }); - - jest.doMock('../getDependencyConfig', () => getDependencyConfig); - - jest.doMock('../android/isInstalled.js', () => - jest.fn().mockReturnValue(true), - ); - jest.doMock( - '../android/registerNativeModule.js', - () => registerNativeModule, - ); - - jest.doMock('../ios/isInstalled.js', () => jest.fn().mockReturnValue(true)); - jest.doMock('../ios/registerNativeModule.js', () => registerNativeModule); + platforms: { + ios: { + linkConfig: () => ({ + register: registerNativeModule, + isInstalled: jest.fn().mockReturnValue(true), + }), + }, + android: { + linkConfig: () => ({ + register: registerNativeModule, + isInstalled: jest.fn().mockReturnValue(true), + }), + }, + windows: { + linkConfig: () => ({ + register: registerNativeModule, + isInstalled: jest.fn().mockReturnValue(false), + }), + }, + }, + dependencies: { + 'react-native-blur': { + ...baseDependencyConfig, + platforms: { + ...baseDependencyConfig.platforms, + windows: {}, + }, + }, + }, + }; - const link = require('../link').func; - link(['react-native-blur'], context, {}).then(() => { + link(['react-native-blur'], config, {}).then(() => { expect(registerNativeModule.mock.calls).toHaveLength(1); done(); }); }); it('should link only for specific platforms if --platforms is used', async () => { - jest.doMock('../getProjectDependencies', () => () => ['react-native-maps']); - jest.doMock('../../../tools/getPackageConfiguration', () => () => ({ - assets: [], - })); - - const registerAndroidNativeModule = jest.fn(); - const registerIOSNativeModule = jest.fn(); - - const genericAndroidLinkConfig = () => ({ - isInstalled: () => false, - register: registerAndroidNativeModule, - }); - - const genericIOSLinkConfig = () => ({ - isInstalled: () => false, - register: registerIOSNativeModule, - }); - - jest.doMock('../../../tools/getPlatforms', () => { - const fn = () => ({ - android: {linkConfig: genericAndroidLinkConfig}, - ios: {linkConfig: genericIOSLinkConfig}, - }); - fn.getPlatformName = jest.fn(); - return fn; - }); + const registerNativeModule = jest.fn(); - jest.doMock( - '../android/registerNativeModule.js', - () => registerAndroidNativeModule, - ); - jest.doMock( - '../ios/registerNativeModule.js', - () => registerIOSNativeModule, - ); - - const link = require('../link').func; - const assertPlaftormsCalledTimes = (android, ios) => { - expect(registerAndroidNativeModule).toHaveBeenCalledTimes(android); - expect(registerIOSNativeModule).toHaveBeenCalledTimes(ios); - registerAndroidNativeModule.mockClear(); - registerIOSNativeModule.mockClear(); + const config = { + ...baseConfig, + project: { + ios: {}, + android: {}, + }, + platforms: { + ios: { + linkConfig: () => ({ + register: registerNativeModule, + isInstalled: jest.fn().mockReturnValue(false), + }), + }, + android: { + linkConfig: () => ({ + register: registerNativeModule, + isInstalled: jest.fn().mockReturnValue(false), + }), + }, + }, + dependencies: { + 'react-native-blur': baseDependencyConfig, + }, }; - await link( - ['react-native-gradient'], - {root: '/'}, - {platforms: ['android']}, - ); - assertPlaftormsCalledTimes(1, 0); - - await link(['react-native-gradient'], {root: '/'}, {platforms: ['ios']}); - assertPlaftormsCalledTimes(0, 1); - - await link( - ['react-native-gradient'], - {root: '/'}, - {platforms: ['android', 'ios']}, - ); - assertPlaftormsCalledTimes(1, 1); + await link(['react-native-blur'], config, {platforms: ['android']}); + + expect(registerNativeModule.mock.calls).toHaveLength(1); }); }); From d95e286109b75fd18c48a87b8469eb0bfdfd9680 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 20:22:51 +0200 Subject: [PATCH 21/46] Bring missing snapshots back --- .../__snapshots__/index-test.js.snap | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap index 55267e27f..50ddbf244 100644 --- a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap +++ b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap @@ -84,6 +84,61 @@ Object { } `; +exports[`should load commands from "react-native-foo" and "react-native-bar" packages 1`] = ` +Array [ + "react-native-foo/command-foo.js", + "react-native-bar/command-bar.js", +] +`; + +exports[`should read \`rnpm\` config from a dependency and transform it to a new format 1`] = ` +Object { + "assets": Array [], + "hooks": Object {}, + "name": "react-native-foo", + "params": Array [], + "platforms": Object { + "android": null, + "ios": Object { + "folder": "<>/node_modules/react-native-foo", + "libraryFolder": "Libraries", + "pbxprojPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj/project.pbxproj", + "plist": Array [], + "podfile": null, + "podspec": null, + "projectName": "customProject.xcodeproj", + "projectPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj", + "sharedLibraries": Array [], + "sourceDir": "<>/node_modules/react-native-foo/customLocation", + }, + }, +} +`; + +exports[`should read a config of a dependency and use it to load other settings 1`] = ` +Object { + "assets": Array [], + "hooks": Object {}, + "name": "react-native-foo", + "params": Array [], + "platforms": Object { + "android": null, + "ios": Object { + "folder": "<>/node_modules/react-native-test", + "libraryFolder": "Libraries", + "pbxprojPath": "<>/node_modules/react-native-test/customLocation/customProject.xcodeproj/project.pbxproj", + "plist": Array [], + "podfile": null, + "podspec": null, + "projectName": "customProject.xcodeproj", + "projectPath": "<>/node_modules/react-native-test/customLocation/customProject.xcodeproj", + "sharedLibraries": Array [], + "sourceDir": "<>/node_modules/react-native-test/customLocation", + }, + }, +} +`; + exports[`should return dependencies from package.json 1`] = ` Object { "react-native-test": Object { From 11bae0638805da081f22da88e2d1b2f59df0e522 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 20:25:52 +0200 Subject: [PATCH 22/46] Turn off Flow for link test as its causing too much troubles --- packages/cli/src/commands/link/__tests__/link-test.js | 3 --- packages/cli/src/tools/config/__tests__/index-test.js | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/cli/src/commands/link/__tests__/link-test.js b/packages/cli/src/commands/link/__tests__/link-test.js index b94f266bb..74002d0a2 100644 --- a/packages/cli/src/commands/link/__tests__/link-test.js +++ b/packages/cli/src/commands/link/__tests__/link-test.js @@ -1,6 +1,3 @@ -/** - * @flow - */ import {func as link} from '../link'; import loadConfig from '../../../tools/config'; diff --git a/packages/cli/src/tools/config/__tests__/index-test.js b/packages/cli/src/tools/config/__tests__/index-test.js index be2173b51..6af024d0f 100644 --- a/packages/cli/src/tools/config/__tests__/index-test.js +++ b/packages/cli/src/tools/config/__tests__/index-test.js @@ -2,7 +2,7 @@ * @flow */ -import loadConfig from '../'; +import loadConfig from '..'; import { cleanup, From 416c0bb371ead94208869da8489867ba552b4540 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 20:27:03 +0200 Subject: [PATCH 23/46] Fix formatting and update snapshot --- .../src/commands/info/__tests__/info.test.js | 26 +++++++++++-------- .../__snapshots__/index-test.js.snap | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/cli/src/commands/info/__tests__/info.test.js b/packages/cli/src/commands/info/__tests__/info.test.js index cbda1f26f..b19c25aa7 100644 --- a/packages/cli/src/commands/info/__tests__/info.test.js +++ b/packages/cli/src/commands/info/__tests__/info.test.js @@ -17,16 +17,20 @@ beforeEach(() => { const config = loadConfig(); -test('prints output without arguments', async () => { - await info.func([], config, {}); - expect(logger.info).toHaveBeenCalledWith( - 'Fetching system and libraries information...', - ); - const output = (logger.log: any).mock.calls[0][0]; - // Checking on output that should be present on all OSes. - // TODO: move to e2e tests and adjust expectations to include npm packages - expect(output).toContain('System:'); - expect(output).toContain('Binaries:'); -}, 20000); +test( + 'prints output without arguments', + async () => { + await info.func([], config, {}); + expect(logger.info).toHaveBeenCalledWith( + 'Fetching system and libraries information...', + ); + const output = (logger.log: any).mock.calls[0][0]; + // Checking on output that should be present on all OSes. + // TODO: move to e2e tests and adjust expectations to include npm packages + expect(output).toContain('System:'); + expect(output).toContain('Binaries:'); + }, + 20000, +); test.todo('prints output with --packages'); diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap index 50ddbf244..8f077df2d 100644 --- a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap +++ b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap @@ -119,7 +119,7 @@ exports[`should read a config of a dependency and use it to load other settings Object { "assets": Array [], "hooks": Object {}, - "name": "react-native-foo", + "name": "react-native-test", "params": Array [], "platforms": Object { "android": null, From a9d8fa40e255558537d84612e5a3011cd46ff92d Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 20:29:11 +0200 Subject: [PATCH 24/46] unlink message has been updated for better readability --- e2e/__tests__/uninstall.test.js | 2 +- packages/cli/src/commands/link/unlink.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/__tests__/uninstall.test.js b/e2e/__tests__/uninstall.test.js index 1c9f6df05..1b9053e49 100644 --- a/e2e/__tests__/uninstall.test.js +++ b/e2e/__tests__/uninstall.test.js @@ -38,7 +38,7 @@ test('uninstall fails when package is not installed', () => { }); const {stderr, code} = run(DIR, ['uninstall', pkg]); - expect(stderr).toContain(`Project "${pkg}" is not a react-native library`); + expect(stderr).toContain(`Failed to unlink "${pkg}".`); expect(code).toBe(1); }); diff --git a/packages/cli/src/commands/link/unlink.js b/packages/cli/src/commands/link/unlink.js index a33f893ad..39272e3e2 100644 --- a/packages/cli/src/commands/link/unlink.js +++ b/packages/cli/src/commands/link/unlink.js @@ -84,7 +84,7 @@ function unlink(args: Array, ctx: ContextT) { if (!dependency) { throw new Error(dedent` - Failed to unlink ${packageName}. It appears that the project is not linked yet. + Failed to unlink "${packageName}". It appears that the project is not linked yet. `); } From ec58f2ff8f0660d57bfabb012bf93e9b27fa77d1 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 21:01:28 +0200 Subject: [PATCH 25/46] Remove unused file: --- .../cli/src/tools/config/__tests__/findDependencies-test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/cli/src/tools/config/__tests__/findDependencies-test.js b/packages/cli/src/tools/config/__tests__/findDependencies-test.js index 684251600..25865744d 100644 --- a/packages/cli/src/tools/config/__tests__/findDependencies-test.js +++ b/packages/cli/src/tools/config/__tests__/findDependencies-test.js @@ -4,8 +4,6 @@ import findDependencies from '../findDependencies'; -const path = require('path'); - import { cleanup, writeFiles, From a111f054f4bab1dead7239e4da7ed4dd5e48fdf2 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 21:05:04 +0200 Subject: [PATCH 26/46] Reload configuration after install --- packages/cli/src/commands/install/install.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/commands/install/install.js b/packages/cli/src/commands/install/install.js index bd9097a0c..ffcb7f0df 100644 --- a/packages/cli/src/commands/install/install.js +++ b/packages/cli/src/commands/install/install.js @@ -11,6 +11,7 @@ import type {ContextT} from '../../tools/types.flow'; import logger from '../../tools/logger'; import * as PackageManager from '../../tools/PackageManager'; import link from '../link/link'; +import loadConfig from '../../tools/config'; async function install(args: Array, ctx: ContextT) { const name = args[0]; @@ -18,8 +19,11 @@ async function install(args: Array, ctx: ContextT) { logger.info(`Installing "${name}"...`); PackageManager.install([name]); + // Reload configuration to see newly installed dependency + const newConfig = loadConfig(); + logger.info(`Linking "${name}"...`); - await link.func([name], ctx, {platforms: undefined}); + await link.func([name], newConfig, {platforms: undefined}); logger.success(`Successfully installed and linked "${name}"`); } From 3e6b3a131b32e8783e50ae5e5c8b0aa23a74c954 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 21:11:58 +0200 Subject: [PATCH 27/46] Fix regressions --- .../src/commands/link/ios/common/unregisterNativeModule.js | 4 +++- packages/cli/src/commands/link/unlink.js | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/commands/link/ios/common/unregisterNativeModule.js b/packages/cli/src/commands/link/ios/common/unregisterNativeModule.js index 482f3ef67..61752d42c 100644 --- a/packages/cli/src/commands/link/ios/common/unregisterNativeModule.js +++ b/packages/cli/src/commands/link/ios/common/unregisterNativeModule.js @@ -22,7 +22,9 @@ export default function unregisterNativeModule( const isIosInstalled = isInstalledIOS(projectConfig, dependencyConfig); const isPodInstalled = isInstalledPods(projectConfig, dependencyConfig); if (isIosInstalled) { - const iOSDependencies = compact(otherDependencies.map(d => d.config.ios)); + const iOSDependencies = compact( + otherDependencies.map(d => d.platforms.ios), + ); unregisterDependencyIOS(dependencyConfig, projectConfig, iOSDependencies); } else if (isPodInstalled) { unregisterDependencyPods(dependencyConfig, projectConfig); diff --git a/packages/cli/src/commands/link/unlink.js b/packages/cli/src/commands/link/unlink.js index 39272e3e2..52bd69112 100644 --- a/packages/cli/src/commands/link/unlink.js +++ b/packages/cli/src/commands/link/unlink.js @@ -57,7 +57,7 @@ const unlinkDependency = ( linkConfig.unregister( packageName, // $FlowExpectedError: We check for existence on line 38 - dependency.config[platform], + dependency.platforms[platform], // $FlowExpectedError: We check for existence on line 38 project[platform], otherDependencies, @@ -139,6 +139,7 @@ function unlink(args: Array, ctx: ContextT) { logger.error( `It seems something went wrong while unlinking. Error:\n${err.message}`, ); + console.log(err.stack); throw err; }); } From 0d6fe637b1a904c3031a0b4738ec7efe6288b643 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 21:13:12 +0200 Subject: [PATCH 28/46] Remove console.log --- packages/cli/src/commands/link/unlink.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/cli/src/commands/link/unlink.js b/packages/cli/src/commands/link/unlink.js index 52bd69112..8f8d6fb91 100644 --- a/packages/cli/src/commands/link/unlink.js +++ b/packages/cli/src/commands/link/unlink.js @@ -139,7 +139,6 @@ function unlink(args: Array, ctx: ContextT) { logger.error( `It seems something went wrong while unlinking. Error:\n${err.message}`, ); - console.log(err.stack); throw err; }); } From 3d6182c73794cae8ecd142b98e4b4916442da3e3 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 21:23:26 +0200 Subject: [PATCH 29/46] Fix ESLint issue --- .../src/commands/info/__tests__/info.test.js | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/packages/cli/src/commands/info/__tests__/info.test.js b/packages/cli/src/commands/info/__tests__/info.test.js index b19c25aa7..cbda1f26f 100644 --- a/packages/cli/src/commands/info/__tests__/info.test.js +++ b/packages/cli/src/commands/info/__tests__/info.test.js @@ -17,20 +17,16 @@ beforeEach(() => { const config = loadConfig(); -test( - 'prints output without arguments', - async () => { - await info.func([], config, {}); - expect(logger.info).toHaveBeenCalledWith( - 'Fetching system and libraries information...', - ); - const output = (logger.log: any).mock.calls[0][0]; - // Checking on output that should be present on all OSes. - // TODO: move to e2e tests and adjust expectations to include npm packages - expect(output).toContain('System:'); - expect(output).toContain('Binaries:'); - }, - 20000, -); +test('prints output without arguments', async () => { + await info.func([], config, {}); + expect(logger.info).toHaveBeenCalledWith( + 'Fetching system and libraries information...', + ); + const output = (logger.log: any).mock.calls[0][0]; + // Checking on output that should be present on all OSes. + // TODO: move to e2e tests and adjust expectations to include npm packages + expect(output).toContain('System:'); + expect(output).toContain('Binaries:'); +}, 20000); test.todo('prints output with --packages'); From a0164bd77c831e58e742b356fbfcc3ebb1102a4d Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 21:28:42 +0200 Subject: [PATCH 30/46] Possible fix to e2e test --- packages/cli/src/tools/config/findDependencies.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/tools/config/findDependencies.js b/packages/cli/src/tools/config/findDependencies.js index acbdda475..11ef07ac3 100644 --- a/packages/cli/src/tools/config/findDependencies.js +++ b/packages/cli/src/tools/config/findDependencies.js @@ -3,6 +3,7 @@ */ import path from 'path'; +import fs from 'fs'; const pluginRe = new RegExp( [ @@ -25,7 +26,9 @@ export default function findDependencies(root: string): Array { let pjson; try { - pjson = require(path.join(root, 'package.json')); + pjson = JSON.parse( + fs.readFileSync(path.join(root, 'package.json'), 'UTF-8'), + ); } catch (e) { return []; } From 453c59cd813d7f34a614ac6b037d0a077f9593ce Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 21:32:24 +0200 Subject: [PATCH 31/46] Export loadConfig function for public interface --- packages/cli/src/cliEntry.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/cli/src/cliEntry.js b/packages/cli/src/cliEntry.js index fbbaa8c64..34a7999a5 100644 --- a/packages/cli/src/cliEntry.js +++ b/packages/cli/src/cliEntry.js @@ -169,13 +169,10 @@ async function setupAndRun() { logger.setVerbose(commander.verbose); } -// @todo replace this -const findPlugins = () => {}; - export default { run, init, - findPlugins, + loadConfig, }; -export {run, init, findPlugins}; +export {run, init, loadConfig}; From bf2f88bdf6afcdc2a6b2e5561a59b39af1c10368 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 21:48:23 +0200 Subject: [PATCH 32/46] Refactor out types --- packages/cli/src/commands/link/linkAll.js | 4 +- packages/cli/src/commands/link/linkAssets.js | 2 +- .../cli/src/tools/config/__mocks__/index.js | 3 +- packages/cli/src/tools/config/types.flow.js | 119 ++++++++++++---- packages/cli/src/tools/types.flow.js | 133 ------------------ 5 files changed, 98 insertions(+), 163 deletions(-) diff --git a/packages/cli/src/commands/link/linkAll.js b/packages/cli/src/commands/link/linkAll.js index faa98ae84..0974ad5a9 100644 --- a/packages/cli/src/commands/link/linkAll.js +++ b/packages/cli/src/commands/link/linkAll.js @@ -6,7 +6,7 @@ import {uniqBy, flatMap} from 'lodash'; import path from 'path'; import dedent from 'dedent'; -import type {ContextT, PlatformsT} from '../../tools/types.flow'; +import type {ConfigT, PlatformsT} from '../../tools/config/types.flow'; import promiseWaterfall from './promiseWaterfall'; import commandStub from './commandStub'; @@ -18,7 +18,7 @@ import linkDependency from './linkDependency'; const dedupeAssets = (assets: Array): Array => uniqBy(assets, asset => path.basename(asset)); -function linkAll(config: ContextT, platforms: PlatformsT) { +function linkAll(config: ConfigT, platforms: PlatformsT) { const projectAssets = config.assets; const assets = dedupeAssets( diff --git a/packages/cli/src/commands/link/linkAssets.js b/packages/cli/src/commands/link/linkAssets.js index 7060ef4ca..462fbc676 100644 --- a/packages/cli/src/commands/link/linkAssets.js +++ b/packages/cli/src/commands/link/linkAssets.js @@ -1,7 +1,7 @@ // @flow import {isEmpty} from 'lodash'; -import type {PlatformsT, ProjectConfigT} from '../../tools/types.flow'; +import type {PlatformsT, ProjectConfigT} from '../../tools/config/types.flow'; import logger from '../../tools/logger'; diff --git a/packages/cli/src/tools/config/__mocks__/index.js b/packages/cli/src/tools/config/__mocks__/index.js index 2635139dd..78f27628a 100644 --- a/packages/cli/src/tools/config/__mocks__/index.js +++ b/packages/cli/src/tools/config/__mocks__/index.js @@ -1,9 +1,8 @@ /** * @flow */ -import {type ConfigT} from '../types.flow'; -export default function mockedLoadConfig(): ConfigT { +export default function mockedLoadConfig() { return { root: '/project/root', reactNativePath: '', diff --git a/packages/cli/src/tools/config/types.flow.js b/packages/cli/src/tools/config/types.flow.js index 7e679a00a..ffc063012 100644 --- a/packages/cli/src/tools/config/types.flow.js +++ b/packages/cli/src/tools/config/types.flow.js @@ -2,17 +2,32 @@ * @flow */ -import type { - DependencyParamsAndroidT, - ProjectParamsAndroidT, - ProjectParamsIOST, - InquirerPromptT, - DependencyConfigAndroidT, - DependencyConfigIOST, - ProjectConfigAndroidT, - ProjectConfigIOST, - PlatformConfigT, -} from '../types.flow'; +type InquirerPromptT = any; + +type DependencyParamsAndroidT = { + sourceDir?: string, + manifestPath?: string, + packageImportPath?: string, + packageInstance?: string, +}; + +type ProjectParamsAndroidT = { + sourceDir?: string, + manifestPath?: string, + packageName?: string, + packageFolder?: string, + mainFilePath?: string, + stringsPath?: string, + settingsGradlePath?: string, + assetsPath?: string, + buildGradlePath?: string, +}; + +type ProjectParamsIOST = { + project?: string, + sharedLibraries?: string[], + libraryFolder?: string, +}; export type ConfigT = {| root: string, @@ -41,19 +56,63 @@ export type ConfigT = {| }, }, platforms: { - ios: PlatformConfigT< - ProjectConfigIOST, - ProjectParamsIOST, - DependencyConfigIOST, - ProjectParamsIOST, - >, - android: PlatformConfigT< - ProjectConfigAndroidT, - ProjectParamsAndroidT, - DependencyConfigAndroidT, - DependencyParamsAndroidT, - >, - [name: string]: PlatformConfigT, + [name: string]: any, + ios: { + projectConfig: (string, ProjectParamsIOST) => ?ProjectConfigIOST, + dependencyConfig: (string, ProjectParamsIOST) => ?DependencyConfigIOST, + linkConfig: () => { + isInstalled: ( + ProjectConfigIOST, + string, + DependencyConfigIOST, + ) => boolean, + register: ( + string, + DependencyConfigIOST, + Object, + ProjectConfigIOST, + ) => void, + unregister: ( + string, + DependencyConfigT, + ProjectConfigIOST, + Array, + ) => void, + copyAssets: (string[], ProjectConfigIOST) => void, + unlinkAssets: (string[], ProjectConfigIOST) => void, + }, + android: { + projectConfig: ( + string, + ProjectParamsAndroidT, + ) => ?ProjectConfigAndroidT, + dependencyConfig: ( + string, + DependencyParamsAndroidT, + ) => ?DependencyConfigAndroidT, + linkConfig: () => { + isInstalled: ( + ProjectConfigAndroidT, + string, + DependencyConfigIOST, + ) => boolean, + register: ( + string, + DependencyConfigIOST, + Object, + ProjectConfigAndroidT, + ) => void, + unregister: ( + string, + DependencyConfigT, + ProjectConfigAndroidT, + Array, + ) => void, + copyAssets: (string[], ProjectConfigIOST) => void, + unlinkAssets: (string[], ProjectConfigIOST) => void, + }, + }, + }, }, commands: string[], haste: { @@ -85,7 +144,9 @@ export type UserDependencyConfigT = { params: InquirerPromptT[], }, commands: string[], - platforms: PlatformsT, + platforms: { + [name: string]: any, + }, }; export type UserConfigT = { @@ -97,3 +158,11 @@ export type UserConfigT = { [key: string]: any, }, }; + +type ProjectConfigIOST = {}; + +type DependencyConfigIOST = ProjectConfigIOST; + +type ProjectConfigAndroidT = {}; + +type DependencyConfigAndroidT = {}; diff --git a/packages/cli/src/tools/types.flow.js b/packages/cli/src/tools/types.flow.js index 6a46b82fc..5926e655c 100644 --- a/packages/cli/src/tools/types.flow.js +++ b/packages/cli/src/tools/types.flow.js @@ -40,136 +40,3 @@ export type ProjectCommandT = LocalCommandT & { * Main type. Can be either local or a project command. */ export type CommandT = LocalCommandT | ProjectCommandT; - -/** - * Config of a single platform - */ -export type PlatformConfigT< - ProjectConfigT, - ProjectParamsT, - DependencyConfigT, - DependencyParamsT, -> = { - projectConfig: (string, ProjectParamsT) => ?ProjectConfigT, - dependencyConfig: (string, DependencyParamsT) => ?DependencyConfigT, - /** - * @todo(grabbou): This should not be part of the "core". It should be - * specific to `link` and `unlink`. Remove it from here soon. - */ - linkConfig?: () => { - /** - * @todo(grabbou): Revert the arguments order to align with the rest - */ - isInstalled: (ProjectConfigT, string, DependencyConfigT) => boolean, - register: (string, DependencyConfigT, Object, ProjectConfigT) => void, - unregister: ( - string, - DependencyConfigT, - ProjectConfigT, - Array, - ) => void, - copyAssets: (string[], ProjectConfigT) => void, - unlinkAssets: (string[], ProjectConfigT) => void, - }, -}; - -export type DependencyParamsAndroidT = { - sourceDir?: string, - manifestPath?: string, - packageImportPath?: string, - packageInstance?: string, -}; - -export type ProjectParamsIOST = { - project?: string, - sharedLibraries?: string[], - libraryFolder?: string, -}; - -export type ProjectParamsAndroidT = { - sourceDir?: string, - manifestPath?: string, - packageName?: string, - packageFolder?: string, - mainFilePath?: string, - stringsPath?: string, - settingsGradlePath?: string, - assetsPath?: string, - buildGradlePath?: string, -}; - -export type ProjectConfigIOST = {}; - -export type DependencyConfigIOST = ProjectConfigIOST; - -export type ProjectConfigAndroidT = {}; - -export type DependencyConfigAndroidT = {}; - -/** - * Config of a project. - * - * When one of the projects is `null`, that means given platform - * is not available in the current project. - */ -export type ProjectConfigT = { - android: ?ProjectConfigAndroidT, - ios: ?ProjectConfigIOST, -}; - -/** - * Config of a dependency. Just like above, when one of the values is `null`, - * given platform is not available. - */ -export type DependencyConfigT = { - android: ?DependencyConfigAndroidT, - ios: ?DependencyConfigIOST, -}; - -export type DependenciesConfig = { - config: DependencyConfigT, - name: string, - path: string, - assets: string[], - commands: {[name: string]: string}, - params: InquirerPromptT[], -}; - -/** - * Available platforms. Additional plugins should assert the type on their own. - */ -export type PlatformsT = { - ios: PlatformConfigT< - ProjectConfigIOST, - ProjectParamsIOST, - DependencyConfigIOST, - ProjectParamsIOST, - >, - android: PlatformConfigT< - ProjectConfigAndroidT, - ProjectParamsAndroidT, - DependencyConfigAndroidT, - DependencyParamsAndroidT, - >, - [name: string]: PlatformConfigT, -}; - -export type InquirerPromptT = any; - -/** - * Configuration of the CLI as set by a package in the package.json - */ -export type PackageConfigurationT = { - assets?: string[], - commands?: {[name: string]: string}, - params?: InquirerPromptT[], - android: DependencyParamsAndroidT, - ios: ProjectParamsIOST, - - plugin?: string | Array, - platform?: string, - haste?: { - platforms?: Array, - providesModuleNodeModules?: Array, - }, -}; From 3b49d80ca89c7b61af79b25d9aa1d2750c5f36df Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 21:59:43 +0200 Subject: [PATCH 33/46] Describe the types --- packages/cli/src/tools/config/types.flow.js | 62 ++++++++++++++++++++- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/tools/config/types.flow.js b/packages/cli/src/tools/config/types.flow.js index ffc063012..d3bfe1c75 100644 --- a/packages/cli/src/tools/config/types.flow.js +++ b/packages/cli/src/tools/config/types.flow.js @@ -2,8 +2,18 @@ * @flow */ +/** + * Opaque type that describes the Inquirer question format. Not typed, since we just + * pass it directly to Inquirer. Validation is done with Joi in `schema.js` + */ type InquirerPromptT = any; +/** + * Settings that a library author can define in the configuration bundled with + * dependency for Android + * + * See UserDependencyConfigT for details + */ type DependencyParamsAndroidT = { sourceDir?: string, manifestPath?: string, @@ -11,6 +21,11 @@ type DependencyParamsAndroidT = { packageInstance?: string, }; +/** + * Settings that user can define in the project configuration for Android + * + * See UserConfigT for details + */ type ProjectParamsAndroidT = { sourceDir?: string, manifestPath?: string, @@ -23,21 +38,39 @@ type ProjectParamsAndroidT = { buildGradlePath?: string, }; +/** + * Settings that user can define in the project configuration for iOS. + * Same for dependency - we share the type. + * + * See UserDependencyConfigT and UserConfigT for details + */ type ProjectParamsIOST = { project?: string, sharedLibraries?: string[], libraryFolder?: string, }; +/** + * Final configuration object + */ export type ConfigT = {| + // Root where the configuration has been resolved from root: string, + + // Path to React Native source reactNativePath: string, + + // Object that contains configuration for a project (null, when platform not available) project: { android: ?ProjectConfigAndroidT, ios: ?ProjectConfigIOST, [key: string]: any, }, + + // An array of assets as defined by the user assets: string[], + + // Map of the dependencies that are present in the project dependencies: { [key: string]: { name: string, @@ -55,6 +88,8 @@ export type ConfigT = {| params: InquirerPromptT[], }, }, + + // Map of available platforms (built-ins and dynamically loaded) platforms: { [name: string]: any, ios: { @@ -114,25 +149,33 @@ export type ConfigT = {| }, }, }, + + // An array of commands that are present in 3rd party packages commands: string[], + + // Haste configuration resolved based on available plugins haste: { platforms: Array, providesModuleNodeModules: Array, }, |}; +/** + * Aliases + */ export type DependencyConfigT = $PropertyType< $PropertyType, '[key: string]', >; - export type HooksT = $PropertyType; - export type ProjectConfigT = $PropertyType; - export type PlatformsT = $PropertyType; +/** + * Config defined by a developer for a library + */ export type UserDependencyConfigT = { + // Additional dependency settings dependency: { platforms: { android: DependencyParamsAndroidT, @@ -143,15 +186,28 @@ export type UserDependencyConfigT = { hooks: HooksT, params: InquirerPromptT[], }, + + // An array of commands that ship with the dependency commands: string[], + + // An array of extra platforms to load platforms: { [name: string]: any, }, }; +/** + * Config defined by a developer for the project + */ export type UserConfigT = { + /** + * Shares some structure with ConfigT, except that haste, root, platforms + * are calculated and can't be defined + */ ...$Diff, reactNativePath: ?string, + + // Additional project settings project: { android?: ProjectParamsAndroidT, ios?: ProjectParamsIOST, From b4811057216af8e4c63ff0f8e87b10c2bbf184ae Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 22:05:25 +0200 Subject: [PATCH 34/46] Note about untyped parts --- packages/cli/src/tools/config/types.flow.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/tools/config/types.flow.js b/packages/cli/src/tools/config/types.flow.js index d3bfe1c75..1c85b9ee7 100644 --- a/packages/cli/src/tools/config/types.flow.js +++ b/packages/cli/src/tools/config/types.flow.js @@ -215,10 +215,9 @@ export type UserConfigT = { }, }; +// The following types are used in untyped-parts of the codebase, so I am leaving them +// until we actually need them. type ProjectConfigIOST = {}; - type DependencyConfigIOST = ProjectConfigIOST; - type ProjectConfigAndroidT = {}; - type DependencyConfigAndroidT = {}; From d188f142d0b8b6277737147acacd7c09290fbad7 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 22:09:33 +0200 Subject: [PATCH 35/46] Bring better debug logs for link --- packages/cli/src/commands/link/link.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/cli/src/commands/link/link.js b/packages/cli/src/commands/link/link.js index 0e118a058..5033bab3d 100644 --- a/packages/cli/src/commands/link/link.js +++ b/packages/cli/src/commands/link/link.js @@ -16,6 +16,7 @@ import promiseWaterfall from './promiseWaterfall'; import logger from '../../tools/logger'; import commandStub from './commandStub'; import promisify from './promisify'; +import getPlatformName from './getPlatformName'; import linkDependency from './linkDependency'; import linkAssets from './linkAssets'; @@ -37,8 +38,16 @@ function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { if (opts.platforms) { platforms = pick(platforms, opts.platforms); + logger.debug('Skipping selected platforms'); } + logger.debug( + 'Available platforms: ' + + `${Object.keys(platforms) + .map(getPlatformName) + .join(', ')}`, + ); + if (rawPackageName === undefined) { logger.debug( 'No package name provided, will attemp to link all possible packages.', From 2f887fd355c1cd1b6b01ee5aefc7ea61f94181f5 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 22:42:19 +0200 Subject: [PATCH 36/46] Lazily access reactNativePath --- packages/cli/src/tools/config/index.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.js index 15b1c4719..ad654869a 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.js @@ -82,8 +82,11 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { }, ({ root: projectRoot, - reactNativePath: - userConfig.reactNativePath || resolveReactNativePath(projectRoot), + get reactNativePath() { + return ( + userConfig.reactNativePath || resolveReactNativePath(projectRoot) + ); + }, dependencies: {}, commands: userConfig.commands, assets: findAssets(projectRoot, userConfig.assets), From acb7993448d56e669c92950368fabc28c95754b0 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 23:03:02 +0200 Subject: [PATCH 37/46] make config truly lazy --- packages/cli/src/commands/init/init.js | 6 +++--- packages/cli/src/tools/completeAssign.js | 22 ++++++++++++++++++++++ packages/cli/src/tools/config/index.js | 11 +++++------ 3 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 packages/cli/src/tools/completeAssign.js diff --git a/packages/cli/src/commands/init/init.js b/packages/cli/src/commands/init/init.js index 7b8486723..24c8b965a 100644 --- a/packages/cli/src/commands/init/init.js +++ b/packages/cli/src/commands/init/init.js @@ -100,9 +100,9 @@ function createProject(projectName: string, options: Options, version: string) { return createFromReactNativeTemplate(projectName, version, options.npm); } -export default async function initialize( +export default (async function initialize( [projectName]: Array, - context: ContextT, + _context: ContextT, options: Options, ) { validateProjectName(projectName); @@ -125,4 +125,4 @@ export default async function initialize( logger.error(e.message); fs.removeSync(projectName); } -} +}); diff --git a/packages/cli/src/tools/completeAssign.js b/packages/cli/src/tools/completeAssign.js new file mode 100644 index 000000000..ce7e58f7b --- /dev/null +++ b/packages/cli/src/tools/completeAssign.js @@ -0,0 +1,22 @@ +/** + * Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + * + * Similar to Object.assign(), but copies full descriptors instead of running them + */ +export default function completeAssign(target, ...sources) { + sources.forEach(source => { + let descriptors = Object.keys(source).reduce((descriptors, key) => { + descriptors[key] = Object.getOwnPropertyDescriptor(source, key); + return descriptors; + }, {}); + // by default, Object.assign copies enumerable Symbols too + Object.getOwnPropertySymbols(source).forEach(sym => { + let descriptor = Object.getOwnPropertyDescriptor(source, sym); + if (descriptor.enumerable) { + descriptors[sym] = descriptor; + } + }); + Object.defineProperties(target, descriptors); + }); + return target; +} diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.js index ad654869a..cd2c866e4 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.js @@ -3,6 +3,7 @@ */ import path from 'path'; import merge from 'deepmerge'; +import assign from '../completeAssign'; import {mapValues} from 'lodash'; import findDependencies from './findDependencies'; @@ -37,8 +38,7 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { readLegacyDependencyConfigFromDisk(root) || readDependencyConfigFromDisk(root); - return { - ...acc, + return assign({}, acc, { dependencies: { ...acc.dependencies, // $FlowIssue: Computed getters are not yet supported. @@ -78,7 +78,7 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { ), platforms: [...acc.haste.platforms, ...Object.keys(config.platforms)], }, - }; + }); }, ({ root: projectRoot, @@ -113,10 +113,9 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { }: ConfigT), ); - return { - ...inferredConfig, + return assign({}, inferredConfig, { dependencies: merge(inferredConfig.dependencies, userConfig.dependencies), - }; + }); } export default loadConfig; From 9b5c3c6b3fef6c230a46554e4dc6ad0b3f244037 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 23:06:03 +0200 Subject: [PATCH 38/46] Update and leave a todo note --- packages/cli/src/tools/{completeAssign.js => assign.js} | 0 packages/cli/src/tools/config/index.js | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) rename packages/cli/src/tools/{completeAssign.js => assign.js} (100%) diff --git a/packages/cli/src/tools/completeAssign.js b/packages/cli/src/tools/assign.js similarity index 100% rename from packages/cli/src/tools/completeAssign.js rename to packages/cli/src/tools/assign.js diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.js index cd2c866e4..ec51e1da2 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.js @@ -3,7 +3,6 @@ */ import path from 'path'; import merge from 'deepmerge'; -import assign from '../completeAssign'; import {mapValues} from 'lodash'; import findDependencies from './findDependencies'; @@ -18,6 +17,8 @@ import { import {type ConfigT} from './types.flow'; +import assign from '../assign'; + /** * Built-in platforms */ @@ -114,6 +115,7 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { ); return assign({}, inferredConfig, { + // @todo rewrite `merge` to use `assign` to not run getters unless needed dependencies: merge(inferredConfig.dependencies, userConfig.dependencies), }); } From 8910d639132b80f2391b1cb34e8995255c725486 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 23:14:22 +0200 Subject: [PATCH 39/46] Flaky e2e tests --- e2e/__tests__/__snapshots__/legacyInit.test.js.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/__tests__/__snapshots__/legacyInit.test.js.snap b/e2e/__tests__/__snapshots__/legacyInit.test.js.snap index f78d5e2b4..887ea29eb 100644 --- a/e2e/__tests__/__snapshots__/legacyInit.test.js.snap +++ b/e2e/__tests__/__snapshots__/legacyInit.test.js.snap @@ -7,8 +7,8 @@ Object { "react-native": "0.59.3", }, "devDependencies": Object { - "@babel/core": "^7.4.0", - "@babel/runtime": "^7.4.2", + "@babel/core": "^7.4.3", + "@babel/runtime": "^7.4.3", "babel-jest": "^24.6.0", "jest": "^24.6.0", "metro-react-native-babel-preset": "^0.53.1", From 4838f19cf6e8d6b5345a62cf4ec3c4fae89ca877 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 23:16:17 +0200 Subject: [PATCH 40/46] Make assets lazy --- packages/cli/src/tools/config/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.js index ec51e1da2..3c0920b59 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.js @@ -90,7 +90,9 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { }, dependencies: {}, commands: userConfig.commands, - assets: findAssets(projectRoot, userConfig.assets), + get assets() { + return findAssets(projectRoot, userConfig.assets); + }, platforms: { ios, android, From d03c7c82805a34f32ee9413903190a2e13096e8c Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 23:18:32 +0200 Subject: [PATCH 41/46] Add flow to assign --- packages/cli/src/tools/assign.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/cli/src/tools/assign.js b/packages/cli/src/tools/assign.js index ce7e58f7b..18f061712 100644 --- a/packages/cli/src/tools/assign.js +++ b/packages/cli/src/tools/assign.js @@ -1,19 +1,22 @@ /** * Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign * - * Similar to Object.assign(), but copies full descriptors instead of running them + * Similar to Object.assign(), but it doesn't execute getters. This allows us to have + * lazy properties on an object and still be able to merge them together + * + * @flow */ -export default function completeAssign(target, ...sources) { +export default function assign(target: Object, ...sources: Object[]) { sources.forEach(source => { - let descriptors = Object.keys(source).reduce((descriptors, key) => { - descriptors[key] = Object.getOwnPropertyDescriptor(source, key); - return descriptors; + let descriptors = Object.keys(source).reduce((acc, key) => { + acc[key] = Object.getOwnPropertyDescriptor(source, key); + return acc; }, {}); // by default, Object.assign copies enumerable Symbols too Object.getOwnPropertySymbols(source).forEach(sym => { let descriptor = Object.getOwnPropertyDescriptor(source, sym); - if (descriptor.enumerable) { - descriptors[sym] = descriptor; + if (descriptor && descriptor.enumerable) { + descriptors[sym.toString()] = descriptor; } }); Object.defineProperties(target, descriptors); From 5e6584d7c402611c1fb9003fbdba5330c2ecf9e9 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 2 Apr 2019 23:24:42 +0200 Subject: [PATCH 42/46] Fix types --- packages/cli/src/tools/config/types.flow.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/tools/config/types.flow.js b/packages/cli/src/tools/config/types.flow.js index 1c85b9ee7..9485cb398 100644 --- a/packages/cli/src/tools/config/types.flow.js +++ b/packages/cli/src/tools/config/types.flow.js @@ -129,11 +129,11 @@ export type ConfigT = {| isInstalled: ( ProjectConfigAndroidT, string, - DependencyConfigIOST, + DependencyConfigAndroidT, ) => boolean, register: ( string, - DependencyConfigIOST, + DependencyConfigAndroidT, Object, ProjectConfigAndroidT, ) => void, @@ -143,8 +143,8 @@ export type ConfigT = {| ProjectConfigAndroidT, Array, ) => void, - copyAssets: (string[], ProjectConfigIOST) => void, - unlinkAssets: (string[], ProjectConfigIOST) => void, + copyAssets: (string[], ProjectConfigAndroidT) => void, + unlinkAssets: (string[], ProjectConfigAndroidT) => void, }, }, }, From 4a99ebc6f192e1b86d8aefa4e9ece0a49a91a234 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Wed, 3 Apr 2019 12:11:22 +0200 Subject: [PATCH 43/46] Fix errors when no config for out-of-tree platform --- packages/cli/src/tools/config/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.js index 3c0920b59..fa7b3949a 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.js @@ -52,7 +52,7 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { platform ].dependencyConfig( root, - config.dependency.platforms[platform], + config.dependency.platforms[platform] || {}, ); return dependency; }, @@ -106,7 +106,7 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { (project, platform) => { project[platform] = this.platforms[platform].projectConfig( projectRoot, - userConfig.project[platform], + userConfig.project[platform] || {}, ); return project; }, From 32550bb6e8db071c2a81f1efa542d951a82f5cd1 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Wed, 3 Apr 2019 12:57:02 +0200 Subject: [PATCH 44/46] initial commit --- packages/cli/src/cliEntry.js | 2 +- packages/cli/src/commands/runIOS/runIOS.js | 3 ++- packages/cli/src/tools/config/types.flow.js | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/cliEntry.js b/packages/cli/src/cliEntry.js index 266a12e62..adcc67491 100644 --- a/packages/cli/src/cliEntry.js +++ b/packages/cli/src/cliEntry.js @@ -123,7 +123,7 @@ const addCommand = (command: CommandT, ctx: ContextT) => { opt.command, opt.description, opt.parse || defaultOptParser, - opt.default, + typeof opt.default === 'function' ? opt.default(ctx) : opt.default, ), ); }; diff --git a/packages/cli/src/commands/runIOS/runIOS.js b/packages/cli/src/commands/runIOS/runIOS.js index 8e23d7da4..66e4e0db8 100644 --- a/packages/cli/src/commands/runIOS/runIOS.js +++ b/packages/cli/src/commands/runIOS/runIOS.js @@ -474,7 +474,8 @@ export default { description: 'Path relative to project root where the Xcode project ' + '(.xcodeproj) lives.', - default: 'ios', + default: ({project: {ios}}: ContextT) => + ios ? ios.sourceDir : undefined, }, { command: '--device [string]', diff --git a/packages/cli/src/tools/config/types.flow.js b/packages/cli/src/tools/config/types.flow.js index 9485cb398..d6dc88736 100644 --- a/packages/cli/src/tools/config/types.flow.js +++ b/packages/cli/src/tools/config/types.flow.js @@ -217,7 +217,9 @@ export type UserConfigT = { // The following types are used in untyped-parts of the codebase, so I am leaving them // until we actually need them. -type ProjectConfigIOST = {}; +type ProjectConfigIOST = { + sourceDir: string, +}; type DependencyConfigIOST = ProjectConfigIOST; type ProjectConfigAndroidT = {}; type DependencyConfigAndroidT = {}; From fa68cefa6e66bdd723c790b23bf649691d3da89a Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Wed, 3 Apr 2019 13:00:39 +0200 Subject: [PATCH 45/46] UPdate flow --- packages/cli/src/tools/types.flow.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/tools/types.flow.js b/packages/cli/src/tools/types.flow.js index 5926e655c..9c197f57c 100644 --- a/packages/cli/src/tools/types.flow.js +++ b/packages/cli/src/tools/types.flow.js @@ -15,7 +15,11 @@ export type LocalCommandT = { command: string, description?: string, parse?: (val: string) => any, - default?: string | boolean | number, + default?: + | string + | boolean + | number + | ((config: ConfigT) => ?(string | boolean | number)), }>, examples?: Array<{ desc: string, From 18e7693afa848df80bc93ce8d0a7886f0d6313b1 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Wed, 3 Apr 2019 13:01:51 +0200 Subject: [PATCH 46/46] Update message --- packages/cli/src/commands/runIOS/runIOS.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/commands/runIOS/runIOS.js b/packages/cli/src/commands/runIOS/runIOS.js index 66e4e0db8..6150d5855 100644 --- a/packages/cli/src/commands/runIOS/runIOS.js +++ b/packages/cli/src/commands/runIOS/runIOS.js @@ -472,7 +472,7 @@ export default { { command: '--project-path [string]', description: - 'Path relative to project root where the Xcode project ' + + 'Relative or absolute path to project root where the Xcode project ' + '(.xcodeproj) lives.', default: ({project: {ios}}: ContextT) => ios ? ios.sourceDir : undefined,