From 23ac2ba03a323b176e10fb50eaa25e822162c9d6 Mon Sep 17 00:00:00 2001 From: Kacper Wiszczuk Date: Sat, 12 Jan 2019 13:26:49 +0100 Subject: [PATCH 1/4] build: deprecate link all behavior --- packages/local-cli/link/link.js | 93 ++++------------------- packages/local-cli/link/linkAll.js | 53 +++++++++++++ packages/local-cli/link/linkAssets.js | 37 +++++++++ packages/local-cli/link/linkDependency.js | 65 ++++++++++++++++ 4 files changed, 168 insertions(+), 80 deletions(-) create mode 100644 packages/local-cli/link/linkAll.js create mode 100644 packages/local-cli/link/linkAssets.js create mode 100644 packages/local-cli/link/linkDependency.js diff --git a/packages/local-cli/link/link.js b/packages/local-cli/link/link.js index 907ecf113..5a6f50609 100644 --- a/packages/local-cli/link/link.js +++ b/packages/local-cli/link/link.js @@ -11,14 +11,15 @@ import type { ContextT } from '../core/types.flow'; const log = require('npmlog'); -const { isEmpty, pick } = require('lodash'); -const chalk = require('chalk'); +const { pick } = require('lodash'); const promiseWaterfall = require('./promiseWaterfall'); const getDependencyConfig = require('./getDependencyConfig'); -const pollParams = require('./pollParams'); const commandStub = require('./commandStub'); const promisify = require('./promisify'); const getProjectConfig = require('./getProjectConfig'); +const linkDependency = require('./linkDependency'); +const linkAssets = require('./linkAssets'); +const linkAll = require('./linkAll'); const findReactNativeScripts = require('../util/findReactNativeScripts'); @@ -26,87 +27,15 @@ const getPlatforms = require('../core/getPlatforms'); log.heading = 'rnpm-link'; -const linkDependency = async (platforms, project, dependency) => { - const params = await pollParams(dependency.params); - - Object.keys(platforms || {}).forEach(platform => { - if (!project[platform] || !dependency.config[platform]) { - return; - } - - const linkConfig = - platforms[platform] && - platforms[platform].linkConfig && - platforms[platform].linkConfig(); - if (!linkConfig || !linkConfig.isInstalled || !linkConfig.register) { - return; - } - - const isInstalled = linkConfig.isInstalled( - project[platform], - dependency.name, - dependency.config[platform] - ); - - if (isInstalled) { - log.info( - chalk.grey( - `Platform '${platform}' module ${dependency.name} is already linked` - ) - ); - return; - } - - log.info(`Linking ${dependency.name} ${platform} dependency`); - - linkConfig.register( - dependency.name, - // $FlowFixMe: We check if dependency.config[platform] exists on line 42 - dependency.config[platform], - params, - // $FlowFixMe: We check if project[platform] exists on line 42 - project[platform] - ); - - log.info( - `Platform '${platform}' module ${ - dependency.name - } has been successfully linked` - ); - }); -}; - -const linkAssets = (platforms, project, dependency) => { - if (isEmpty(dependency.assets)) { - return; - } - - Object.keys(platforms || {}).forEach(platform => { - const linkConfig = - platforms[platform] && - platforms[platform].linkConfig && - platforms[platform].linkConfig(); - - if (!linkConfig || !linkConfig.copyAssets || !project[platform]) { - return; - } - - log.info(`Linking assets to ${platform} project`); - // $FlowFixMe: We check for existence of project[platform] on line 97. - linkConfig.copyAssets(dependency.assets, project[platform]); - }); - - log.info('Assets have been successfully linked to your project'); -}; - type FlagsType = { platforms: Array, }; /** - * Links specified package. + * Updates project and links all dependencies to it. * - * @param args [packageName] + * @param args If optional argument [packageName] is provided, + * only that package is processed. */ function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { let platforms; @@ -130,7 +59,7 @@ function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { ); if (!hasProjectConfig && findReactNativeScripts()) { throw new Error( - '`react-native link ` can not be used in Create React Native App projects. ' + + '`react-native link [package]` can not be used in Create React Native App projects. ' + 'If you need to include a library that relies on custom native code, ' + 'you might have to eject first. ' + 'See https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md ' + @@ -138,6 +67,10 @@ function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { ); } + if (rawPackageName === undefined) { + return linkAll(ctx, platforms, project); + } + // Trim the version / tag out of the package name (eg. package@latest) const packageName = rawPackageName.replace(/^(.+?)(@.+?)$/gi, '$1'); @@ -162,7 +95,7 @@ function link([rawPackageName]: Array, ctx: ContextT, opts: FlagsType) { module.exports = { func: link, description: 'scope link command to certain platforms (comma-separated)', - name: 'link ', + name: 'link [packageName]', options: [ { command: '--platforms [list]', diff --git a/packages/local-cli/link/linkAll.js b/packages/local-cli/link/linkAll.js new file mode 100644 index 000000000..9ec406ca2 --- /dev/null +++ b/packages/local-cli/link/linkAll.js @@ -0,0 +1,53 @@ +// @flow + +import type { ContextT, PlatformsT, ProjectConfigT } from '../core/types.flow'; + +const log = require('npmlog'); +const { uniqBy, flatten } = require('lodash'); +const path = require('path'); +const getProjectDependencies = require('./getProjectDependencies'); +const getDependencyConfig = require('./getDependencyConfig'); +const promiseWaterfall = require('./promiseWaterfall'); +const commandStub = require('./commandStub'); +const promisify = require('./promisify'); +const linkAssets = require('./linkAssets'); +const linkDependency = require('./linkDependency'); + +log.heading = 'rnpm-link'; + +const dedupeAssets = assets => uniqBy(assets, asset => path.basename(asset)); + +function linkAll( + context: ContextT, + platforms: PlatformsT, + project: ProjectConfigT +) { + log.warn( + 'Linking modules without specifying package name is deprecated and will be removed in next release' + ); + const dependencies = getProjectDependencies(context.root); + const depenendenciesConfig = dependencies.map(dependnecy => + getDependencyConfig(context, platforms, dependnecy) + ); + const assets = dedupeAssets(flatten(depenendenciesConfig.map(d => d.assets))); + + const tasks = flatten( + depenendenciesConfig + .map(config => [ + () => promisify(config.commands.prelink || commandStub), + () => linkDependency(platforms, project, config), + () => promisify(config.commands.postlink || commandStub), + ]) + .concat(() => linkAssets(platforms, project, assets)) + ); + + return promiseWaterfall(tasks).catch(err => { + log.error( + `Something went wrong while linking. Error: ${err.message} \n` + + 'Please file an issue here: https://github.com/facebook/react-native/issues' + ); + throw err; + }); +} + +module.exports = linkAll; diff --git a/packages/local-cli/link/linkAssets.js b/packages/local-cli/link/linkAssets.js new file mode 100644 index 000000000..1e983f701 --- /dev/null +++ b/packages/local-cli/link/linkAssets.js @@ -0,0 +1,37 @@ +// @flow + +import type { PlatformsT, ProjectConfigT } from '../core/types.flow'; + +const log = require('npmlog'); +const { isEmpty } = require('lodash'); + +log.heading = 'rnpm-link'; + +const linkAssets = ( + platforms: PlatformsT, + project: ProjectConfigT, + dependency: * +) => { + if (isEmpty(dependency.assets)) { + return; + } + + Object.keys(platforms || {}).forEach(platform => { + const linkConfig = + platforms[platform] && + platforms[platform].linkConfig && + platforms[platform].linkConfig(); + + if (!linkConfig || !linkConfig.copyAssets || !project[platform]) { + return; + } + + log.info(`Linking assets to ${platform} project`); + // $FlowFixMe: We check for existence of project[platform] + linkConfig.copyAssets(dependency.assets, project[platform]); + }); + + log.info('Assets have been successfully linked to your project'); +}; + +module.exports = linkAssets; diff --git a/packages/local-cli/link/linkDependency.js b/packages/local-cli/link/linkDependency.js new file mode 100644 index 000000000..f43b0c99a --- /dev/null +++ b/packages/local-cli/link/linkDependency.js @@ -0,0 +1,65 @@ +// @flow + +import type { PlatformsT, ProjectConfigT } from '../core/types.flow'; + +const log = require('npmlog'); +const chalk = require('chalk'); +const pollParams = require('./pollParams'); + +log.heading = 'rnpm-link'; + +const linkDependency = async ( + platforms: PlatformsT, + project: ProjectConfigT, + dependency: * +) => { + const params = await pollParams(dependency.params); + + Object.keys(platforms || {}).forEach(platform => { + if (!project[platform] || !dependency.config[platform]) { + return; + } + + const linkConfig = + platforms[platform] && + platforms[platform].linkConfig && + platforms[platform].linkConfig(); + if (!linkConfig || !linkConfig.isInstalled || !linkConfig.register) { + return; + } + + const isInstalled = linkConfig.isInstalled( + project[platform], + dependency.name, + dependency.config[platform] + ); + + if (isInstalled) { + log.info( + chalk.grey( + `Platform '${platform}' module ${dependency.name} is already linked` + ) + ); + return; + } + + log.info(`Linking ${dependency.name} ${platform} dependency`); + + linkConfig.register( + dependency.name, + // $FlowFixMe: We check if dependency.config[platform] exists on line 42 + dependency.config[platform], + params, + // $FlowFixMe: We check if project[platform] exists on line 42 + project[platform] + ); + + log.info( + `Platform '${platform}' module ${ + dependency.name + } has been successfully linked` + ); + }); +}; + +module.exports = linkDependency; From 7eef06c2f62ed0c651ec677083c6b64bb3696fe6 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 15 Jan 2019 14:47:21 +0100 Subject: [PATCH 2/4] Link project assets too This reverts previous behaviour --- packages/local-cli/link/linkAll.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/local-cli/link/linkAll.js b/packages/local-cli/link/linkAll.js index 9ec406ca2..733dcdadb 100644 --- a/packages/local-cli/link/linkAll.js +++ b/packages/local-cli/link/linkAll.js @@ -5,6 +5,7 @@ import type { ContextT, PlatformsT, ProjectConfigT } from '../core/types.flow'; const log = require('npmlog'); const { uniqBy, flatten } = require('lodash'); const path = require('path'); +const getAssets = require('../core/getAssets'); const getProjectDependencies = require('./getProjectDependencies'); const getDependencyConfig = require('./getDependencyConfig'); const promiseWaterfall = require('./promiseWaterfall'); @@ -25,11 +26,17 @@ function linkAll( log.warn( 'Linking modules without specifying package name is deprecated and will be removed in next release' ); + const projectAssets = getAssets(context.root); const dependencies = getProjectDependencies(context.root); const depenendenciesConfig = dependencies.map(dependnecy => getDependencyConfig(context, platforms, dependnecy) ); - const assets = dedupeAssets(flatten(depenendenciesConfig.map(d => d.assets))); + const assets = dedupeAssets( + depenendenciesConfig.reduce( + (acc, dependency) => acc.concat(dependency.assets), + projectAssets + ) + ); const tasks = flatten( depenendenciesConfig @@ -37,8 +44,8 @@ function linkAll( () => promisify(config.commands.prelink || commandStub), () => linkDependency(platforms, project, config), () => promisify(config.commands.postlink || commandStub), + () => linkAssets(platforms, project, assets) ]) - .concat(() => linkAssets(platforms, project, assets)) ); return promiseWaterfall(tasks).catch(err => { From de60e5994421e7bb063f3cc68a32d3e748658f32 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 15 Jan 2019 14:52:10 +0100 Subject: [PATCH 3/4] Fix small issue --- packages/local-cli/link/linkAll.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/local-cli/link/linkAll.js b/packages/local-cli/link/linkAll.js index 733dcdadb..f6a419075 100644 --- a/packages/local-cli/link/linkAll.js +++ b/packages/local-cli/link/linkAll.js @@ -39,13 +39,12 @@ function linkAll( ); const tasks = flatten( - depenendenciesConfig - .map(config => [ - () => promisify(config.commands.prelink || commandStub), - () => linkDependency(platforms, project, config), - () => promisify(config.commands.postlink || commandStub), - () => linkAssets(platforms, project, assets) - ]) + depenendenciesConfig.map(config => [ + () => promisify(config.commands.prelink || commandStub), + () => linkDependency(platforms, project, config), + () => promisify(config.commands.postlink || commandStub), + () => linkAssets(platforms, project, assets), + ]) ); return promiseWaterfall(tasks).catch(err => { From 81dd930859110bd77703dc9caccefd54a256b6b8 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Tue, 15 Jan 2019 14:59:42 +0100 Subject: [PATCH 4/4] Add URL to an issue --- packages/local-cli/link/linkAll.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/local-cli/link/linkAll.js b/packages/local-cli/link/linkAll.js index f6a419075..1dbd559d5 100644 --- a/packages/local-cli/link/linkAll.js +++ b/packages/local-cli/link/linkAll.js @@ -24,13 +24,17 @@ function linkAll( project: ProjectConfigT ) { log.warn( - 'Linking modules without specifying package name is deprecated and will be removed in next release' + 'Running `react-native link` without package name is deprecated and will be removed ' + + 'in next release. If you are using `react-native link` to link your project assets, ' + + ' let us know about your use case here: https://goo.gl/RKTeoc' ); + const projectAssets = getAssets(context.root); const dependencies = getProjectDependencies(context.root); const depenendenciesConfig = dependencies.map(dependnecy => getDependencyConfig(context, platforms, dependnecy) ); + const assets = dedupeAssets( depenendenciesConfig.reduce( (acc, dependency) => acc.concat(dependency.assets),