Skip to content

Commit

Permalink
Merge pull request #22 from rnpm/feature/support-0.18
Browse files Browse the repository at this point in the history
Support react-native 0.18+
  • Loading branch information
Alexey committed Jan 26, 2016
2 parents 68aafa7 + 5dd07e8 commit 100ac61
Show file tree
Hide file tree
Showing 20 changed files with 528 additions and 56 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"mime": "^1.3.4",
"npmlog": "^2.0.0",
"plist": "^1.2.0",
"semver": "^5.1.0",
"xcode": "^0.8.2"
},
"devDependencies": {
Expand Down
16 changes: 16 additions & 0 deletions src/android/getPrefix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const path = require('path');
const semver = require('semver');

module.exports = function getPrefix(config) {
const rnpkg = require(
path.join(config.folder, 'node_modules', 'react-native', 'package.json')
);

var prefix = 'patches/0.18';

if (semver.lt(rnpkg.version, '0.18.0')) {
prefix = 'patches/0.17';
}

return prefix;
};
27 changes: 27 additions & 0 deletions src/android/patches/0.17/makeMainActivityPatch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const append = (scope, pattern, patch) =>
scope.replace(pattern, `${pattern}\n${patch}`);

module.exports = function makeMainActivityPatch(config) {
const importPattern = `import android.app.Activity;`;
const packagePattern = `.addPackage(new MainReactPackage())`;

/**
* Make a MainActivity.java program patcher
* @param {String} importPath Import path, e.g. com.oblador.vectoricons.VectorIconsPackage;
* @param {String} instance Code to instance a package, e.g. new VectorIconsPackage();
* @return {Function} Patcher function
*/
return function applyMainActivityPatch(content) {
const patched = append(
content,
importPattern,
config.packageImportPath
);

return append(
patched,
packagePattern,
` .addPackage(${config.packageInstance})`
);
};
};
27 changes: 27 additions & 0 deletions src/android/patches/0.18/makeMainActivityPatch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const append = (scope, pattern, patch) =>
scope.replace(pattern, `${pattern}${patch}`);

module.exports = function makeMainActivityPatch(config) {
const importPattern = 'import com.facebook.react.ReactActivity;';
const packagePattern = 'new MainReactPackage()';

/**
* Make a MainActivity.java program patcher
* @param {String} importPath Import path, e.g. com.oblador.vectoricons.VectorIconsPackage;
* @param {String} instance Code to instance a package, e.g. new VectorIconsPackage();
* @return {Function} Patcher function
*/
return function applyMainActivityPatch(content) {
const patched = append(
content,
importPattern,
'\n' + config.packageImportPath
);

return append(
patched,
packagePattern,
',\n ' + config.packageInstance
);
};
};
13 changes: 13 additions & 0 deletions src/android/patches/makeBuildPatch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = function makeBuildPatch(name) {
/**
* Replace pattern by patch in the passed content
* @param {String} content Content of the build.gradle file
* @return {String} Patched content of build.gradle
*/
return function applyBuildPatch(content) {
const pattern = `dependencies {`;
const patch = ` compile project(':${name}')`;

return content.replace(pattern, `${pattern}\n${patch}`);
};
};
22 changes: 22 additions & 0 deletions src/android/patches/makeSettingsPatch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const path = require('path');

module.exports = function makeSettingsPatch(name, dependencyConfig, projectConfig) {
const relative = path.relative(
projectConfig.sourceDir,
dependencyConfig.sourceDir
);

/**
* Replace pattern by patch in the passed content
* @param {String} content Content of the Settings.gradle file
* @return {String} Patched content of Settings.gradle
*/
return function applySettingsPatch(content) {
const pattern = `include ':app'`;
const patch = `include ':${name}'\n` +
`project(':${name}').projectDir = ` +
`new File(rootProject.projectDir, '${relative}')`;

return content.replace(pattern, `${pattern}\n${patch}`);
};
};
75 changes: 19 additions & 56 deletions src/android/registerNativeModule.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
const fs = require('fs-extra');
const path = require('path');
const compose = require('lodash.flowright');

const SETTINGS_PATCH_PATTERN = `include ':app'`;
const BUILD_PATCH_PATTERN = `dependencies {`;
const MAIN_ACTIVITY_IMPORT_PATTERN = `import android.app.Activity;`;
const MAIN_ACTIVITY_PACKAGE_PATTERN = `.addPackage(new MainReactPackage())`;
const getPrefix = require('./getPrefix');

const readFile = (file) =>
() => fs.readFileSync(file, 'utf8');
Expand All @@ -14,81 +9,49 @@ const writeFile = (file, content) => content ?
fs.writeFileSync(file, content, 'utf8') :
(c) => fs.writeFileSync(file, c, 'utf8');

const replace = (scope, pattern, patch) =>
scope.replace(pattern, `${pattern}\n${patch}`);

module.exports = function registerNativeAndroidModule(name, dependencyConfig, projectConfig) {
const BUILD_PATCH = ` compile project(':${name}')`;
const SETTINGS_PATCH = `include ':${name}'\n` +
`project(':${name}').projectDir = ` +
`new File(rootProject.projectDir, '../node_modules/${name}/${dependencyConfig.sourceDir}')`;

/**
* Replace SETTINGS_PATCH_PATTERN by patch in the passed content
* @param {String} content Content of the Settings.gradle file
* @return {String} Patched content of Settings.gradle
*/
const patchProjectSettings = (content) =>
replace(content, SETTINGS_PATCH_PATTERN, SETTINGS_PATCH);

/**
* Replace BUILD_PATCH_PATTERN by patch in the passed content
* @param {String} content Content of the Build.gradle file
* @return {String} Patched content of Build.gradle
*/
const patchProjectBuild = (content) =>
replace(content, BUILD_PATCH_PATTERN, BUILD_PATCH);

const getMainActivityPatch = () =>
` .addPackage(${dependencyConfig.packageInstance})`;
const prefix = getPrefix(projectConfig);

/**
* Make a MainActivity.java program patcher
* @param {String} importPath Import path, e.g. com.oblador.vectoricons.VectorIconsPackage;
* @param {String} instance Code to instance a package, e.g. new VectorIconsPackage();
* @return {Function} Patcher function
*/
const makeMainActivityPatcher = (content) => {
const patched = replace(
content, MAIN_ACTIVITY_IMPORT_PATTERN, dependencyConfig.packageImportPath
);
const makeSettingsPatch = require(`./patches/makeSettingsPatch`);
const makeBuildPatch = require(`./patches/makeBuildPatch`);
const makeMainActivityPatch = require(`./${prefix}/makeMainActivityPatch`);

return replace(
patched, MAIN_ACTIVITY_PACKAGE_PATTERN, getMainActivityPatch()
);
};
const applySettingsPatch = makeSettingsPatch.apply(null, arguments);
const applyBuildPath = makeBuildPatch(name);
const applyMainActivityPatch = makeMainActivityPatch(dependencyConfig);

const applySettingsGradlePatch = compose(
const performSettingsGradlePatch = compose(
writeFile(projectConfig.settingsGradlePath),
patchProjectSettings,
applySettingsPatch,
readFile(projectConfig.settingsGradlePath)
);

const applyBuildGradlePatch = compose(
const performBuildGradlePatch = compose(
writeFile(projectConfig.buildGradlePath),
patchProjectBuild,
applyBuildPath,
readFile(projectConfig.buildGradlePath)
);

const applyMainActivityPatch = compose(
const performMainActivityPatch = compose(
writeFile(projectConfig.mainActivityPath),
makeMainActivityPatcher,
applyMainActivityPatch,
readFile(projectConfig.mainActivityPath)
);

/**
* Check if module has been installed already
*/
const isInstalled = compose(
(content) => ~content.indexOf(getMainActivityPatch()),
(content) => ~content.indexOf(dependencyConfig.packageInstance),
readFile(projectConfig.mainActivityPath)
);

if (!isInstalled(name)) {
compose(
applySettingsGradlePatch,
applyBuildGradlePatch,
applyMainActivityPatch
performSettingsGradlePatch,
performBuildGradlePatch,
performMainActivityPatch
)();
}
};

31 changes: 31 additions & 0 deletions test/android/patches/0.17/makeMainActivityPatch.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const fs = require('fs');
const path = require('path');
const chai = require('chai');
const expect = chai.expect;
const makeMainActivityPatch = require(
'../../../../src/android/patches/0.17/makeMainActivityPatch'
);

const config = {
packageInstance: 'new VectorIconsPackage()',
packageImportPath: 'import com.oblador.vectoricons.VectorIconsPackage;',
};
const mainActivityPatch = fs.readFileSync(
path.join(process.cwd(), 'test/fixtures/android/0.17/MainActivity.java'),
'utf-8'
);
const patchedMainActivity = fs.readFileSync(
path.join(process.cwd(), 'test/fixtures/android/0.17/patchedMainActivity.java'),
'utf-8'
);

describe('[email protected]', () => {
it('should build a patch function', () => {
expect(makeMainActivityPatch(config)).to.be.a('function');
});

it('should make a correct patch', () => {
const patch = makeMainActivityPatch(config);
expect(patch(mainActivityPatch)).to.be.equal(patchedMainActivity);
});
});
31 changes: 31 additions & 0 deletions test/android/patches/0.18/makeMainActivityPatch.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const fs = require('fs');
const path = require('path');
const chai = require('chai');
const expect = chai.expect;
const makeMainActivityPatch = require(
'../../../../src/android/patches/0.18/makeMainActivityPatch'
);

const config = {
packageInstance: 'new VectorIconsPackage()',
packageImportPath: 'import com.oblador.vectoricons.VectorIconsPackage;',
};
const mainActivityPatch = fs.readFileSync(
path.join(process.cwd(), 'test/fixtures/android/0.18/MainActivity.java'),
'utf-8'
);
const patchedMainActivity = fs.readFileSync(
path.join(process.cwd(), 'test/fixtures/android/0.18/patchedMainActivity.java'),
'utf-8'
);

describe('[email protected]', () => {
it('should build a patch function', () => {
expect(makeMainActivityPatch(config)).to.be.a('function');
});

it('should make a correct patch', () => {
const patch = makeMainActivityPatch(config);
expect(patch(mainActivityPatch)).to.be.equal(patchedMainActivity);
});
});
26 changes: 26 additions & 0 deletions test/android/patches/makeBuildPatch.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const fs = require('fs');
const path = require('path');
const chai = require('chai');
const expect = chai.expect;
const makeBuildPatch = require('../../../src/android/patches/makeBuildPatch');

const name = 'test';
const buildGradle = fs.readFileSync(
path.join(process.cwd(), 'test/fixtures/android/build.gradle'),
'utf-8'
);
const patchedBuildGradle = fs.readFileSync(
path.join(process.cwd(), 'test/fixtures/android/patchedBuild.gradle'),
'utf-8'
);

describe('makeBuildPatch', () => {
it('should build a patch function', () => {
expect(makeBuildPatch(name)).to.be.a('function');
});

it('should make a correct patch', () => {
const patch = makeBuildPatch('test');
expect(patch(buildGradle)).to.be.equal(patchedBuildGradle);
});
});
30 changes: 30 additions & 0 deletions test/android/patches/makeSettingsPatch.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const fs = require('fs');
const path = require('path');
const chai = require('chai');
const expect = chai.expect;
const makeSettingsPatch = require('../../../src/android/patches/makeSettingsPatch');

const name = 'test';
const projectConfig = { sourceDir: '.' };
const dependencyConfig = { sourceDir: `../node_modules/${name}/android` };
const settingsGradle = fs.readFileSync(
path.join(process.cwd(), 'test/fixtures/android/settings.gradle'),
'utf-8'
);
const patchedSettingsGradle = fs.readFileSync(
path.join(process.cwd(), 'test/fixtures/android/patchedSettings.gradle'),
'utf-8'
);

describe('makeSettingsPatch', () => {
it('should build a patch function', () => {
expect(
makeSettingsPatch(name, dependencyConfig, projectConfig)
).to.be.a('function');
});

it('should make a correct patch', () => {
const patch = makeSettingsPatch('test', dependencyConfig, projectConfig);
expect(patch(settingsGradle)).to.be.equal(patchedSettingsGradle);
});
});
Loading

0 comments on commit 100ac61

Please sign in to comment.