Fix `react-native link` issue when using multiple manifests

Summary:
`react-native link` often fails due to the wrong manifest being used when you use a debug manifest. `findManifest` returns `debug/AndroidManifest.xml` instead of `main/AndroidManifest.xml`. And the debug manifest usually does not have the package name defined so `projectConfigAndroid` throws a cryptic "Cannot read property 'replace' of undefined" error.

This fixes the issue by throwing a more user friendly error and providing a `manifestPath` userConfig.

This is mostly based on comments to #10050.
Closes https://github.com/facebook/react-native/pull/13373

Differential Revision: D4945690

Pulled By: shergin

fbshipit-source-id: b177f916fd4799c873d2515c18cbb87bef3203f0
This commit is contained in:
Daniel Friesen 2017-06-06 14:11:54 -07:00 committed by Facebook Github Bot
parent 2dfcde4c7b
commit 1ad08aa659
4 changed files with 46 additions and 2 deletions

View File

@ -20,6 +20,25 @@ exports.valid = {
},
};
exports.userConfigManifest = {
src: {
main: {
'AndroidManifest.xml': manifest,
com: {
some: {
example: {
'Main.java': mainJavaClass,
'ReactPackage.java': fs.readFileSync(path.join(__dirname, './files/ReactPackage.java')),
},
},
},
},
debug: {
'AndroidManifest.xml': fs.readFileSync(path.join(__dirname, './files/AndroidManifest-debug.xml')),
},
},
};
exports.corrupted = {
src: {
'AndroidManifest.xml': manifest,

View File

@ -0,0 +1,3 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View File

@ -15,6 +15,9 @@ describe('android::getProjectConfig', () => {
flat: {
android: mocks.valid,
},
multiple: {
android: mocks.userConfigManifest,
},
noManifest: {
android: {},
},
@ -43,6 +46,16 @@ describe('android::getProjectConfig', () => {
expect(getProjectConfig(folder, userConfig)).not.toBe(null);
expect(typeof getProjectConfig(folder, userConfig)).toBe('object');
});
it('multiple', () => {
const userConfig = {
manifestPath: 'src/main/AndroidManifest.xml'
};
const folder = 'multiple';
expect(getProjectConfig(folder, userConfig)).not.toBe(null);
expect(typeof getProjectConfig(folder, userConfig)).toBe('object');
});
});
it('should return `null` if android project was not found', () => {

View File

@ -29,7 +29,9 @@ exports.projectConfig = function projectConfigAndroid(folder, userConfig) {
const sourceDir = path.join(folder, src);
const isFlat = sourceDir.indexOf('app') === -1;
const manifestPath = findManifest(sourceDir);
const manifestPath = userConfig.manifestPath
? path.join(sourceDir, userConfig.manifestPath)
: findManifest(sourceDir);
if (!manifestPath) {
return null;
@ -38,6 +40,11 @@ exports.projectConfig = function projectConfigAndroid(folder, userConfig) {
const manifest = readManifest(manifestPath);
const packageName = userConfig.packageName || getPackageName(manifest);
if (!packageName) {
throw new Error(`Package name not found in ${manifestPath}`);
}
const packageFolder = userConfig.packageFolder ||
packageName.replace(/\./g, path.sep);
@ -92,7 +99,9 @@ exports.dependencyConfig = function dependencyConfigAndroid(folder, userConfig)
}
const sourceDir = path.join(folder, src);
const manifestPath = findManifest(sourceDir);
const manifestPath = userConfig.manifestPath
? path.join(sourceDir, userConfig.manifestPath)
: findManifest(sourceDir);
if (!manifestPath) {
return null;