diff --git a/local-cli/core/android/index.js b/local-cli/core/android/index.js index cc229d298..68d2a073c 100644 --- a/local-cli/core/android/index.js +++ b/local-cli/core/android/index.js @@ -126,3 +126,5 @@ exports.dependencyConfig = function dependencyConfigAndroid(folder, userConfig) return { sourceDir, folder, manifest, packageImportPath, packageInstance }; }; + +exports.linkConfig = require('../../link/android'); diff --git a/local-cli/core/ios/index.js b/local-cli/core/ios/index.js index 6bca59463..0d69ac9f1 100644 --- a/local-cli/core/ios/index.js +++ b/local-cli/core/ios/index.js @@ -57,3 +57,5 @@ exports.projectConfig = function projectConfigIOS(folder, userConfig) { }; exports.dependencyConfig = exports.projectConfig; + +exports.linkConfig = require('../../link/ios'); diff --git a/local-cli/link/__tests__/link.spec.js b/local-cli/link/__tests__/link.spec.js index b3470563d..f15fc3fee 100644 --- a/local-cli/link/__tests__/link.spec.js +++ b/local-cli/link/__tests__/link.spec.js @@ -81,8 +81,10 @@ describe('link', () => { it('should register native module when android/ios projects are present', (done) => { const registerNativeModule = sinon.stub(); const dependencyConfig = {android: {}, ios: {}, assets: [], commands: {}}; + const androidLinkConfig = require('../android'); + const iosLinkConfig = require('../ios'); const config = { - getPlatformConfig: () => ({ios: {}, android: {}}), + getPlatformConfig: () => ({ios: { linkConfig: iosLinkConfig }, android: { linkConfig: androidLinkConfig }}), getProjectConfig: () => ({android: {}, ios: {}, assets: []}), getDependencyConfig: sinon.stub().returns(dependencyConfig), }; @@ -223,8 +225,9 @@ describe('link', () => { sinon.stub().returns(false) ); + const linkConfig = require('../ios'); const config = { - getPlatformConfig: () => ({ ios: {}}), + getPlatformConfig: () => ({ ios: { linkConfig: linkConfig }}), getProjectConfig: () => ({ ios: {}, assets: [] }), getDependencyConfig: sinon.stub().returns({ ios: {}, assets: [], commands: { prelink, postlink }, @@ -251,8 +254,9 @@ describe('link', () => { copyAssets ); + const linkConfig = require('../ios'); const config = { - getPlatformConfig: () => ({ ios: {} }), + getPlatformConfig: () => ({ ios: { linkConfig: linkConfig } }), getProjectConfig: () => ({ ios: {}, assets: projectAssets }), getDependencyConfig: sinon.stub().returns(dependencyConfig), }; diff --git a/local-cli/link/android/copyAssets.js b/local-cli/link/android/copyAssets.js index 0f41a301c..6b3702fa7 100644 --- a/local-cli/link/android/copyAssets.js +++ b/local-cli/link/android/copyAssets.js @@ -17,10 +17,10 @@ const groupFilesByType = require('../groupFilesByType'); * For now, the only types of files that are handled are: * - Fonts (otf, ttf) - copied to targetPath/fonts under original name */ -module.exports = function copyAssetsAndroid(files, targetPath) { +module.exports = function copyAssetsAndroid(files, project) { const assets = groupFilesByType(files); (assets.font || []).forEach(asset => - fs.copySync(asset, path.join(targetPath, 'fonts', path.basename(asset))) + fs.copySync(asset, path.join(project.assetsPath, 'fonts', path.basename(asset))) ); }; diff --git a/local-cli/link/android/index.js b/local-cli/link/android/index.js new file mode 100644 index 000000000..986ec5945 --- /dev/null +++ b/local-cli/link/android/index.js @@ -0,0 +1,9 @@ +module.exports = function() { + return { + isInstalled: require('./isInstalled'), + register: require('./registerNativeModule'), + unregister: require('./unregisterNativeModule'), + copyAssets: require('./copyAssets'), + unlinkAssets: require('./unlinkAssets') + }; +}; diff --git a/local-cli/link/android/unlinkAssets.js b/local-cli/link/android/unlinkAssets.js index 6c8b02191..dbaae6f7b 100644 --- a/local-cli/link/android/unlinkAssets.js +++ b/local-cli/link/android/unlinkAssets.js @@ -17,11 +17,11 @@ const groupFilesByType = require('../groupFilesByType'); * For now, the only types of files that are handled are: * - Fonts (otf, ttf) - copied to targetPath/fonts under original name */ -module.exports = function unlinkAssetsAndroid(files, targetPath) { +module.exports = function unlinkAssetsAndroid(files, project) { const assets = groupFilesByType(files); (assets.font || []).forEach((file) => { - const filePath = path.join(targetPath, 'fonts', path.basename(file)); + const filePath = path.join(project.assetsPath, 'fonts', path.basename(file)); if (fs.existsSync(filePath)) { fs.unlinkSync(filePath); } diff --git a/local-cli/link/ios/common/isInstalled.js b/local-cli/link/ios/common/isInstalled.js new file mode 100644 index 000000000..a7a5f2d07 --- /dev/null +++ b/local-cli/link/ios/common/isInstalled.js @@ -0,0 +1,6 @@ +const isInstalledIOS = require('../isInstalled'); +const isInstalledPods = require('../../pods/isInstalled'); + +module.exports = function isInstalled(config, name) { + return isInstalledIOS(config, name) || isInstalledPods(config, name); +}; diff --git a/local-cli/link/ios/common/registerNativeModule.js b/local-cli/link/ios/common/registerNativeModule.js new file mode 100644 index 000000000..38ce59606 --- /dev/null +++ b/local-cli/link/ios/common/registerNativeModule.js @@ -0,0 +1,16 @@ +const registerDependencyIOS = require('../registerNativeModule'); +const registerDependencyPods = require('../../pods/registerNativeModule'); + +module.exports = function registerNativeModule( + name, + dependencyConfig, + params, + projectConfig +) { + if (projectConfig.podfile && dependencyConfig.podspec) { + registerDependencyPods(name, dependencyConfig, projectConfig); + } + else { + registerDependencyIOS(dependencyConfig, projectConfig); + } +}; diff --git a/local-cli/link/ios/common/unregisterNativeModule.js b/local-cli/link/ios/common/unregisterNativeModule.js new file mode 100644 index 000000000..b42882623 --- /dev/null +++ b/local-cli/link/ios/common/unregisterNativeModule.js @@ -0,0 +1,22 @@ +const compact = require('lodash').compact; +const isInstalledIOS = require('../isInstalled'); +const isInstalledPods = require('../../pods/isInstalled'); +const unregisterDependencyIOS = require('../registerNativeModule'); +const unregisterDependencyPods = require('../../pods/registerNativeModule'); + +module.exports = function unregisterNativeModule( + name, + dependencyConfig, + projectConfig, + otherDependencies +) { + const isIosInstalled = isInstalledIOS(projectConfig, dependencyConfig); + const isPodInstalled = isInstalledPods(projectConfig, dependencyConfig); + if (isIosInstalled) { + const iOSDependencies = compact(otherDependencies.map(d => d.config.ios)); + unregisterDependencyIOS(dependencyConfig, projectConfig, iOSDependencies); + } + else if (isPodInstalled) { + unregisterDependencyPods(dependencyConfig, projectConfig); + } +}; diff --git a/local-cli/link/ios/index.js b/local-cli/link/ios/index.js new file mode 100644 index 000000000..9653b3be8 --- /dev/null +++ b/local-cli/link/ios/index.js @@ -0,0 +1,9 @@ +module.exports = function() { + return { + isInstalled: require('./common/isInstalled'), + register: require('./common/registerNativeModule'), + unregister: require('./common/unregisterNativeModule'), + copyAssets: require('./copyAssets'), + unlinkAssets: require('./unlinkAssets') + }; +}; diff --git a/local-cli/link/link.js b/local-cli/link/link.js index ac0aba2a6..8711f278b 100644 --- a/local-cli/link/link.js +++ b/local-cli/link/link.js @@ -26,14 +26,6 @@ const chalk = require('chalk'); * run Flow. */ const isEmpty = require('lodash').isEmpty; const promiseWaterfall = require('./promiseWaterfall'); -const registerDependencyAndroid = require('./android/registerNativeModule'); -const registerDependencyIOS = require('./ios/registerNativeModule'); -const registerDependencyPods = require('./pods/registerNativeModule'); -const isInstalledAndroid = require('./android/isInstalled'); -const isInstalledIOS = require('./ios/isInstalled'); -const isInstalledPods = require('./pods/isInstalled'); -const copyAssetsAndroid = require('./android/copyAssets'); -const copyAssetsIOS = require('./ios/copyAssets'); const getProjectDependencies = require('./getProjectDependencies'); const getDependencyConfig = require('./getDependencyConfig'); const pollParams = require('./pollParams'); @@ -47,37 +39,8 @@ log.heading = 'rnpm-link'; const dedupeAssets = (assets) => uniqBy(assets, asset => path.basename(asset)); - -const linkDependencyAndroid = (androidProject, dependency) => { - if (!androidProject || !dependency.config.android) { - return null; - } - - const isInstalled = isInstalledAndroid(androidProject, dependency.name); - - if (isInstalled) { - log.info(chalk.grey(`Android module ${dependency.name} is already linked`)); - return null; - } - - return pollParams(dependency.config.params).then(params => { - log.info(`Linking ${dependency.name} android dependency`); - - registerDependencyAndroid( - dependency.name, - dependency.config.android, - params, - androidProject - ); - - log.info(`Android module ${dependency.name} has been successfully linked`); - }); -}; - -const linkDependencyPlatforms = (platforms, project, dependency) => { - const ignorePlatforms = ['android', 'ios']; +const linkDependency = (platforms, project, dependency) => { Object.keys(platforms || {}) - .filter(platform => ignorePlatforms.indexOf(platform) < 0) .forEach(platform => { if (!project[platform] || !dependency.config[platform]) { return null; @@ -110,45 +73,12 @@ const linkDependencyPlatforms = (platforms, project, dependency) => { }); }; -const linkDependencyIOS = (iOSProject, dependency) => { - if (!iOSProject || !dependency.config.ios) { - return; - } - - const isInstalled = isInstalledIOS(iOSProject, dependency.config.ios) || isInstalledPods(iOSProject, dependency.config.ios); - if (isInstalled) { - log.info(chalk.grey(`iOS module ${dependency.name} is already linked`)); - return; - } - - log.info(`Linking ${dependency.name} ios dependency`); - if (iOSProject.podfile && dependency.config.ios.podspec) { - registerDependencyPods(dependency, iOSProject); - } - else { - registerDependencyIOS(dependency.config.ios, iOSProject); - } - log.info(`iOS module ${dependency.name} has been successfully linked`); -}; - const linkAssets = (platforms, project, assets) => { if (isEmpty(assets)) { return; } - if (project.ios) { - log.info('Linking assets to ios project'); - copyAssetsIOS(assets, project.ios); - } - - if (project.android) { - log.info('Linking assets to android project'); - copyAssetsAndroid(assets, project.android.assetsPath); - } - - const ignorePlatforms = ['android', 'ios']; Object.keys(platforms || {}) - .filter(platform => ignorePlatforms.indexOf(platform) < 0) .forEach(platform => { const linkConfig = platforms[platform] && platforms[platform].linkConfig && platforms[platform].linkConfig(); if (!linkConfig || !linkConfig.copyAssets) { @@ -212,9 +142,7 @@ function link(args: Array, config: RNConfig) { const tasks = flatten(dependencies.map(dependency => [ () => promisify(dependency.config.commands.prelink || commandStub), - () => linkDependencyAndroid(project.android, dependency), - () => linkDependencyIOS(project.ios, dependency), - () => linkDependencyPlatforms(platforms, project, dependency), + () => linkDependency(platforms, project, dependency), () => promisify(dependency.config.commands.postlink || commandStub), ])); diff --git a/local-cli/link/pods/registerNativeModule.js b/local-cli/link/pods/registerNativeModule.js index 1032f2448..37041cf78 100644 --- a/local-cli/link/pods/registerNativeModule.js +++ b/local-cli/link/pods/registerNativeModule.js @@ -16,10 +16,10 @@ const findMarkedLinesInPodfile = require('./findMarkedLinesInPodfile'); const addPodEntry = require('./addPodEntry'); const savePodFile = require('./savePodFile'); -module.exports = function registerNativeModulePods(dependency, iOSProject) { +module.exports = function registerNativeModulePods(name, dependencyConfig, iOSProject) { const podLines = readPodfile(iOSProject.podfile); const linesToAddEntry = getLinesToAddEntry(podLines, iOSProject); - addPodEntry(podLines, linesToAddEntry, dependency.config.ios.podspec, dependency.name); + addPodEntry(podLines, linesToAddEntry, dependencyConfig.podspec, name); savePodFile(iOSProject.podfile, podLines); }; diff --git a/local-cli/link/unlink.js b/local-cli/link/unlink.js index 5c54526df..ed3772c4b 100644 --- a/local-cli/link/unlink.js +++ b/local-cli/link/unlink.js @@ -10,16 +10,7 @@ const log = require('npmlog'); const getProjectDependencies = require('./getProjectDependencies'); -const unregisterDependencyAndroid = require('./android/unregisterNativeModule'); -const unregisterDependencyIOS = require('./ios/unregisterNativeModule'); -const unregisterDependencyPods = require('./pods/unregisterNativeModule'); -const isInstalledAndroid = require('./android/isInstalled'); -const isInstalledIOS = require('./ios/isInstalled'); -const isInstalledPods = require('./pods/isInstalled'); -const unlinkAssetsAndroid = require('./android/unlinkAssets'); -const unlinkAssetsIOS = require('./ios/unlinkAssets'); const getDependencyConfig = require('./getDependencyConfig'); -const compact = require('lodash').compact; const difference = require('lodash').difference; const filter = require('lodash').filter; const flatten = require('lodash').flatten; @@ -30,38 +21,17 @@ const promisify = require('./promisify'); log.heading = 'rnpm-link'; -const unlinkDependencyAndroid = (androidProject, dependency, packageName) => { - if (!androidProject || !dependency.android) { - return; - } +const unlinkDependency = (platforms, project, dependency, packageName, otherDependencies) => { - const isInstalled = isInstalledAndroid(androidProject, packageName); - - if (!isInstalled) { - log.info(`Android module ${packageName} is not installed`); - return; - } - - log.info(`Unlinking ${packageName} android dependency`); - - unregisterDependencyAndroid(packageName, dependency.android, androidProject); - - log.info(`Android module ${packageName} has been successfully unlinked`); -}; - -const unlinkDependencyPlatforms = (platforms, project, dependency, packageName) => { - - const ignorePlatforms = ['android', 'ios']; Object.keys(platforms || {}) - .filter(platform => ignorePlatforms.indexOf(platform) < 0) .forEach(platform => { if (!project[platform] || !dependency[platform]) { - return null; + return; } const linkConfig = platforms[platform] && platforms[platform].linkConfig && platforms[platform].linkConfig(); if (!linkConfig || !linkConfig.isInstalled || !linkConfig.unregister) { - return null; + return; } const isInstalled = linkConfig.isInstalled(project[platform], dependency[platform]); @@ -76,37 +46,14 @@ const unlinkDependencyPlatforms = (platforms, project, dependency, packageName) linkConfig.unregister( packageName, dependency[platform], - project[platform] + project[platform], + otherDependencies ); log.info(`Platform '${platform}' module ${dependency.name} has been successfully unlinked`); }); }; -const unlinkDependencyIOS = (iOSProject, dependency, packageName, iOSDependencies) => { - if (!iOSProject || !dependency.ios) { - return; - } - - const isIosInstalled = isInstalledIOS(iOSProject, dependency.ios); - const isPodInstalled = isInstalledPods(iOSProject, dependency.ios); - if (!isIosInstalled && !isPodInstalled) { - log.info(`iOS module ${packageName} is not installed`); - return; - } - - log.info(`Unlinking ${packageName} ios dependency`); - - if (isIosInstalled) { - unregisterDependencyIOS(dependency.ios, iOSProject, iOSDependencies); - } - else if (isPodInstalled) { - unregisterDependencyPods(dependency.ios, iOSProject); - } - - log.info(`iOS module ${packageName} has been successfully unlinked`); -}; - /** * Updates project and unlink specific dependency * @@ -143,13 +90,10 @@ function unlink(args, config) { const allDependencies = getDependencyConfig(config, getProjectDependencies()); const otherDependencies = filter(allDependencies, d => d.name !== packageName); - const iOSDependencies = compact(otherDependencies.map(d => d.config.ios)); const tasks = [ () => promisify(dependency.commands.preunlink || commandStub), - () => unlinkDependencyAndroid(project.android, dependency, packageName), - () => unlinkDependencyIOS(project.ios, dependency, packageName, iOSDependencies), - () => unlinkDependencyPlatforms(platforms, project, dependency, packageName), + () => unlinkDependency(platforms, project, dependency, packageName, otherDependencies), () => promisify(dependency.commands.postunlink || commandStub) ]; @@ -166,15 +110,16 @@ function unlink(args, config) { return Promise.resolve(); } - if (project.ios) { - log.info('Unlinking assets from ios project'); - unlinkAssetsIOS(assets, project.ios); - } - - if (project.android) { - log.info('Unlinking assets from android project'); - unlinkAssetsAndroid(assets, project.android.assetsPath); - } + Object.keys(platforms || {}) + .forEach(platform => { + const linkConfig = platforms[platform] && platforms[platform].linkConfig && platforms[platform].linkConfig(); + if (!linkConfig || !linkConfig.unlinkAssets) { + return; + } + + log.info(`Unlinking assets from ${platform} project`); + linkConfig.unlinkAssets(assets, project[platform]); + }); log.info( `${packageName} assets has been successfully unlinked from your project`