react-native/local-cli/link/unlink.js

168 lines
4.0 KiB
JavaScript

/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
const log = require('npmlog');
const getProjectDependencies = require('./getProjectDependencies');
const getDependencyConfig = require('./getDependencyConfig');
const difference = require('lodash').difference;
const filter = require('lodash').filter;
const flatten = require('lodash').flatten;
const isEmpty = require('lodash').isEmpty;
const promiseWaterfall = require('./promiseWaterfall');
const commandStub = require('./commandStub');
const promisify = require('./promisify');
log.heading = 'rnpm-link';
const unlinkDependency = (
platforms,
project,
dependency,
packageName,
otherDependencies,
) => {
Object.keys(platforms || {}).forEach(platform => {
if (!project[platform] || !dependency[platform]) {
return;
}
const linkConfig =
platforms[platform] &&
platforms[platform].linkConfig &&
platforms[platform].linkConfig();
if (!linkConfig || !linkConfig.isInstalled || !linkConfig.unregister) {
return;
}
const isInstalled = linkConfig.isInstalled(
project[platform],
packageName,
dependency[platform],
);
if (!isInstalled) {
log.info(`Platform '${platform}' module ${packageName} is not installed`);
return;
}
log.info(`Unlinking ${packageName} ${platform} dependency`);
linkConfig.unregister(
packageName,
dependency[platform],
project[platform],
otherDependencies,
);
log.info(
`Platform '${platform}' module ${
dependency.name
} has been successfully unlinked`,
);
});
};
/**
* Updates project and unlink specific dependency
*
* If optional argument [packageName] is provided, it's the only one
* that's checked
*/
function unlink(args, config) {
const packageName = args[0];
let platforms;
let project;
let dependency;
try {
platforms = config.getPlatformConfig();
project = config.getProjectConfig();
} catch (err) {
log.error(
'ERRPACKAGEJSON',
"No package found. Are you sure it's a React Native project?",
);
return Promise.reject(err);
}
try {
dependency = config.getDependencyConfig(packageName);
} catch (err) {
log.warn(
'ERRINVALIDPROJ',
`Project ${packageName} is not a react-native library`,
);
return Promise.reject(err);
}
const allDependencies = getDependencyConfig(config, getProjectDependencies());
const otherDependencies = filter(
allDependencies,
d => d.name !== packageName,
);
const tasks = [
() => promisify(dependency.commands.preunlink || commandStub),
() =>
unlinkDependency(
platforms,
project,
dependency,
packageName,
otherDependencies,
),
() => promisify(dependency.commands.postunlink || commandStub),
];
return promiseWaterfall(tasks)
.then(() => {
// @todo move all these to `tasks` array, just like in
// link
const assets = difference(
dependency.assets,
flatten(allDependencies, d => d.assets),
);
if (isEmpty(assets)) {
return Promise.resolve();
}
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`,
);
})
.catch(err => {
log.error(
`It seems something went wrong while unlinking. Error: ${err.message}`,
);
throw err;
});
}
module.exports = {
func: unlink,
description: 'unlink native dependency',
name: 'unlink <packageName>',
};